guile-devel
[Top][All Lists]
Advanced

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

Re: Functional record "setters", a different approach


From: Mark H Weaver
Subject: Re: Functional record "setters", a different approach
Date: Thu, 12 Apr 2012 21:58:03 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.92 (gnu/linux)

Hi Ludovic!

address@hidden (Ludovic Courtès) writes:
> Mark H Weaver <address@hidden> skribis:
>> address@hidden (Ludovic Courtès) writes:
>>> 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?

Will do.

>> 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?

Okay, on second thought I'm inclined to agree.  'set' is a good choice.

However, there's a problem with the name 'set-field': because 'field' is
a noun here, it should be made plural when more than one field is being
set.  We could avoid this grammatical problem by making 'field' an
adjective, as in 'field-set'.  This would also be consistent with the
names 'vector-set!', 'struct-set!', 'bitvector-set!', etc.

Another option is 'record-set'.

What do you think?

>>> 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”?

Unfortunately, no.  The 'vtable' field of a struct is a mutable field,
and in fact when a GOOPS class is redefined, the 'vtable' field of
instances are modified.  This means that it is not safe for the compiler
to eliminate redundant calls to 'struct-vtable'.

>> 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.

Yes, and that's exactly what I did.  However, I was only able to
accomplish this by essentially hacking up my own '<getter>-nocheck'.

If I had used the normal getters in the expansion of 'modified-copy',
then (modified-copy s ((foo-x) 'new)) would expand to:

  (make-struct <foo> 0
    (foo-q s) (foo-r s) (foo-s s) (foo-t s) (foo-u s)
    (foo-v s) (foo-w s) 'new      (foo-y s) (foo-z s))

and each of those getter uses would include a type-check in their
expansions.  As you suggested, I instead wrap a single check around the
whole thing and then effectively use (foo-*-nocheck s) instead, by using
'struct-ref' directly.

This example is intended to convince you that 'nocheck' variants of
struct accessors are important as a base upon which to build efficient
higher-level constructs, at least for our own internal use.

> 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?
> :-)

Agreed, but in that case, redundant type tags checks _can_ be optimized
out by a compiler, because those tags are not mutable.  Unfortunately,
the struct vtable pointers _are_ mutable, and in fact are mutated in
practice, so the compiler cannot safely eliminate struct-vtable checks.

> I’ll let you see whether/how you can borrow from this in your code, if
> that’s fine with you.

Okay, will do.

    Thanks!
      Mark



reply via email to

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