[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Functional record "setters", a different approach
From: |
Ludovic Courtès |
Subject: |
Re: Functional record "setters", a different approach |
Date: |
Thu, 12 Apr 2012 21:58:52 +0200 |
User-agent: |
Gnus/5.110018 (No Gnus v0.18) Emacs/24.0.93 (gnu/linux) |
Hi Mark!
Mark H Weaver <address@hidden> skribis:
> address@hidden (Ludovic Courtès) writes:
>> Mark H Weaver <address@hidden> skribis:
>>> 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’.
>
> Agreed.
Cool! Could you integrate it somehow, along with the tests I provided?
>> Also, I’d want to avoid the term ‘copy’, which is sounds low-level;
>> ‘set’ seems more appropriate to me. WDYT?
>
> I agree that 'copy' is not a good term to use here, especially since no
> copy is made in the zero-modification case of (modified-copy s).
>
> However, I find the term 'set' misleading, since no mutation is taking
> place. Maybe 'update'? I dunno, I don't have strong feelings on this.
I don’t find ‘set’ misleading because there’s no exclamation mark, and
because it’s conceptually about setting a field’s value. WDYT?
>> Regarding the interface for multi-field nested changes, I’d still
>> prefer:
>>
>> (set-field p (foo bar) val
>> (foo baz) chbouib)
>>
>> Or is it less readable than:
>>
>> (set-field p ((foo bar) val)
>> ((foo baz) chbouib))
>
> I find the first variant to be very un-scheme-like.
Yes; in hindsight, I have the same feeling.
>> 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.
>
> Hmm. I agree that the 'nocheck' variant should not be prominently
> mentioned, and perhaps not documented at all, but I suspect it will
> prove useful to keep it around, even if only for our own internal use to
> build efficient higher-level constructs.
>
> For example, when I built this 'modified-copy' machinery, I was unable
> to build upon the usual (<getter> s) syntax, because that would cause
> the generated code to include many redundant checks (one for each field
> retrieved).
Would these checks be alleviated by Andy’s work on peval “predicates”?
> For example, for (modified-copy s ((foo-x) 'new)) where 's' contains 10
> fields, the expanded code would include 9 separate checks that 's' is
> the right type.
Couldn’t ‘modified-copy’ be implemented differently so that there’s only
one check? That seems like the most obvious (not necessarily the
easiest) way to address the problem.
Every time ‘car’ is used, there’s a type-check that users cannot
eliminate. IMO, if it were to be eliminated, it should be via
orthogonal means, not via the API: for instance, when the compiler knows
the check would always pass at run-time, or with (declare (unsafe)), or
with ‘-DSCM_RECKLESS’. A ‘car-nocheck’ wouldn’t be convenient, would it?
:-)
[...]
>> and more importantly coordinate so we don’t waste time working on the
>> same code in parallel.
>
> I started this work after you were (probably) asleep,
When I don’t sleep, I also have a daytime work, and a family, among
other things, which is why I am not this responsive. Also, I was
assuming I was holding a mutex on this, so-to-speak. Lastly, I check
email less frequently when I have a hack on my mind. :-)
> and rushed to post about it before you woke up, so I did my best
> there. If you would prefer to use your own code instead, that's okay
> with me. As long as we end up with a functional-multi-setter that
> generates good code, I'll be satisfied.
Yeah, me too. So I’m happy we’re getting close to an even better
solution!
>> FWIW I was using this approach to represent the tree of accessors:
>>
>> (define (field-tree fields)
>> ;; Given FIELDS, a list of field-accessor-lists, return a tree
>> ;; that groups together FIELDS by prefix. Example:
>> ;; FIELDS: ((f1 f2 f3) (f1 f4))
>> ;; RESULT: ((f1 (f2 (f3)) (f4)))
>> (define (insert obj tree)
>> (match obj
>> ((head tail ...)
>> (let ((sub (or (assoc-ref tree head) '())))
>> (cons (cons head (insert tail sub))
>> (alist-delete head tree))))
>> (()
>> tree)))
>>
>> (fold-right insert '() fields))
>
> I agree that this is much nicer than my corresponding code. Thanks for
> sharing. Would you like me to incorporate something like this into my
> code, or would you like to start with your code and maybe cherry-pick
> ideas/code from mine? Either way is fine with me.
I’ll let you see whether/how you can borrow from this in your code, if
that’s fine with you.
Thanks,
Ludo’.
- Functional record "setters", a different approach, Mark H Weaver, 2012/04/11
- Re: Functional record "setters", a different approach, Mark H Weaver, 2012/04/11
- Re: Functional record "setters", a different approach, Ludovic Courtès, 2012/04/11
- Re: Functional record "setters", a different approach, Mark H Weaver, 2012/04/12
- Re: Functional record "setters", a different approach, Thien-Thi Nguyen, 2012/04/12
- Re: Functional record "setters", a different approach,
Ludovic Courtès <=
- Re: Functional record "setters", a different approach, Mark H Weaver, 2012/04/12
- Re: Functional record "setters", a different approach, Ludovic Courtès, 2012/04/13
- Re: Functional record "setters", a different approach, Mark H Weaver, 2012/04/13