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

Reply via email to