Hello,
> The goal was to have an interface close to what one would do in
> imperative programming, that is:
>
> person.address.city = "foo";
>
> I think it’s quite successful at it.
>
> Now, I’m open for suggestions. I don’t have any idea for a better
> interface that meets this goal. For instance, having to spell out the
> getter names may look verbose, but I don’t see how it can be avoided.
>
> Any ideas?
Since updating a field requires creating a new record object (I
think), it seems useful to have an interface to update many fields at
once, to avoid creating many temporary objects. In the spirit of
brainstorming, I have two ideas to offer. First, here's an extended
version of your example:
(let* ((p1 (set-field (person-address address-city) p "Düsseldorf"))
(p2 (set-field (age) p1 32))))
1. Alternate a lists of field names and values. The example becomes
(set-field p (person-address address-city) "Düsseldorf" (age) 32)
2. Pair field names and values. I think of this as analogous to
pairing cond tests and clauses. Your example becomes
2a: (set-field p (person-address address-city "Düsseldorf"))
or maybe
2b: (set-field p ((person-address address-city) "Düsseldorf"))
Of these, I think 2b is the most Schemelike (1 was inspired by Arc). 1
also has the disadvantage that if you leave out a list element, it
might not be immediately obvious where the problem is (although good
indentation could fix that).
Noah