Thank you for taking a look at it. Am Di., 6. Dez. 2022 um 16:53 Uhr schrieb Jim Rees <[email protected]>: > > Clever - I'm unsure how this improves efficiency over the r7rs document > version, other than the amount of work done at definition time. Every > access to an unassigned variable seems like it would be slower.
There are a lot of implementations that eliminate set! by replacing assigned variables with boxes (cars of pairs, say) holding their values. N boxes take up more space and are less local than a vector of length N. I don't understand the meaning of your last sentence quoted above. > But a more serious issue with it is that if one or more of the bindings is > exported by the library it is defined in, then the normal mechanisms for > catching prohibited assignments from outside the library no longer work. A > set! becomes a vector-set! into an imported variable which is perfectly legal. Thanks for this observation. I checked the R6RS again; unfortunately (for this case), this must be detected by the implementation (and is not just a "should"). > This could be dealt with by giving identifier-syntax additional semantics - > in order to invoke the (set! _ e) clause, the macro's binding must not be > imported. This is the non-portable fix. > > An alternative hack is to emit #'(begin (lambda () (set! tmp #f)) > (vector-set! tmp i e)). A reasonable compiler will remove the lambda form > altogether, but not before the expander checks the legality of the set!. The > error message may not be very helpful with the name "tmp", but dealing with > that the best way is going to be very implementation-dependent. Very clever! It's still not quite right, though, I think. Given (define-values (a b) ...) at the top level of a library, if the library set!s a, the variable b must still be exportable. So I have to return to ordinary definitions... :-/
