guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Functional record “setters”


From: Mark H Weaver
Subject: Re: Functional record “setters”
Date: Tue, 10 Apr 2012 11:15:47 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.92 (gnu/linux)

address@hidden (Ludovic Courtès) writes:
> Mark H Weaver <address@hidden> skribis:
>> address@hidden (Ludovic Courtès) writes:
>>> Noah Lavine <address@hidden> skribis:
>>>
>>>> 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.
>>
>> I don't understand why such knowledge is needed, or why this is
>> difficult.  We have procedural macros.  Simply sort the field-name-paths
>> lexicographically, split the sorted paths into groups with the same car,
>> and recurse.  Am I missing something?
>
> Yes: nothing forces you to prefix names with ‘address-’ here.

As Noah pointed out, that doesn't matter.  All you need to do is to
group together field-name-paths with equal cars and recurse.  The field
names are irrelevant, as long as there exists an equality predicate on
names.

>> The associated runtime cost of searching for fields within the RTDs will
>> make functional records too slow for many purposes.  To my mind, this is
>> absolutely unacceptable for a data type as fundamental as records.  We
>> need to make functional record update as fast as we possibly can.
>
> Agreed.  This is why the patch I posted take a purely syntactical
> approach.
>
> Though we must keep in mind that calling these setters involves a
> ‘make-struct’ call, which is already expensive.  Does anyone have
> figures on the relative cost of (say) a function call compared to a
> small heap allocation?

The relevant cost to compare with is not simply a function call.  In the
general case, 'set-fields' involves grouping together field-name-paths
with equal cars, looking up the field names in the RTDs, and recursing.
This code needs to be written either way, it's just a question of
whether it gets executed at run time or at expansion time.

'make-struct' may be expensive today, but there's no inherent reason why
it needs to be, so we can (and should) fix that later.  That's no excuse
for making functional updates slower than they need to be.  It's
relatively easy to make a smart procedural macro to generate optimal
code here.

>> Let's not make such a basic data structure slow out of laziness.  If you
>> don't want to implement this, I'd be glad to.
>
> Implement what?  The proposed ‘set-fields’?

Yes, or something like it.  I don't have a strong opinion about the
exact syntax, so I'll let you all hash out those details.

    Regards,
      Mark



reply via email to

[Prev in Thread] Current Thread [Next in Thread]