Hi! Noah Lavine <noah.b.lav...@gmail.com> skribis:
> 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. Yes, others mentioned it on IRC, though I’m wondering how common this is in practice. > 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) I prefer this one. Perhaps it could be called ‘set-fields’, even. However, generating the most optimal code may prove to be complicated. For instance, you’d want: (set-fields p (person-address address-city) "Düsseldorf" (person-address address-street) "Bar") to expand to: (set-person-address p (let ((a (person-address p))) (set-fields a (address-city) "Düsseldorf" (address-street) "Bar"))) But that would require knowledge of the relationship between ‘address-city’, ‘address-street’, and the underlying record type, etc. Instead, I think I’ll add ‘record-copy’, similar to Racket’s ‘struct-copy’ [0], as Ian Price suggested on IRC. We can do this because it turns out that our SRFI-9 records are now “Guile records”, and thus they have a run-time type descriptor that maps field names to their indices. The drawback compared to generated setters as above is that field lookup happens at run-time, which degrades performance and delays any error report to execution time. Thanks, Ludo’. [0] http://docs.racket-lang.org/reference/struct-copy.html