Hi Ludovic! l...@gnu.org (Ludovic Courtès) writes: > Mark H Weaver <m...@netris.org> skribis: >> l...@gnu.org (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