> I confess that this task was more difficult than I had anticipated, and
> it required a different approach than Ludovic had taken, because
> functional single-field-setters cannot be used to build an optimal
> functional multi-field-setter.
Heh, indeed, I was just looking into it.
> As Ludovic warned, this requires knowledge of the record types at
> expansion time. To accomplish this, I enhanced srfi-9's private
> 'define-inlinable' macro to allow an arbitrary number of key/value pairs
> to be associated with the generated macro. The new macro is called
> 'define-tagged-inlinable', and it's used like this:
> (define-tagged-inlinable (key value) ... (name formals ...) body ...)
> where each 'key' is a private literal identifier in (srfi srfi-9).
> Currently, the keys '%%type', '%%index', and '%%copier' are associated
> with each getter, which causes the getter macro to support additional
> (<GETTER> () %%copier) ==> %%<TYPE-NAME>-modified-copy
> (<GETTER> () %%type) ==> %%<TYPE-NAME>
> (<GETTER> () %%index) ==> <INTEGER>
Looks like a nice generalization of the idea.
> Since the keys are private to (srfi srfi-9), users cannot use these
> private rules without accessing srfi-9's private symbols.
> While I was at it, I incorporated Andy's suggestions
> (accessors/modifiers => getters/setters, throw-bad-struct),
Me too. :-)
> The public interface I've created is quite a bit different than what
> we've been discussing so far. I'm open to changing it, but here's what
> the attached patch currently exports from (srfi srfi-9 gnu):
> (modified-copy <struct-expr> (<field-path> <expr>) ...)
> (modified-copy-nocheck <struct-expr> (<field-path> <expr>) ...)
> where <field-path> is of the form (<field> ...)
I’d still want named single-field setters, for convenience. For that,
we probably still need a separate ‘define-immutable-record-type’.
Also, I’d want to avoid the term ‘copy’, which is sounds low-level;
‘set’ seems more appropriate to me. WDYT?
Regarding the interface for multi-field nested changes, I’d still
(set-field p (foo bar) val
(foo baz) chbouib)
Or is it less readable than:
(set-field p ((foo bar) val)
((foo baz) chbouib))
Finally, I think there’s shouldn’t be a ‘-nocheck’ version. Dynamic
typing entails run-time type checking, that’s a fact of life, but safety
shouldn’t have to be traded for performance.
> These macros can be used on _any_ srfi-9 record, not just ones specially
> declared as immutable.
I assume this preserves “ABI” compatibility too, right?
> Comments and suggestions solicited.
Modulo the above comments, this looks very cool!
What would you think of these changes?
However, in the future, could you please reply in the same thread, and
more importantly coordinate so we don’t waste time working on the same
code in parallel.