Hi Andreas, Thank you very much for the explication, very helpful. At the time I wondered how it did work [guile-1.6] since the definition was quite clear about set! , but it did and then I used it :-)
[i am not using guile-1.8 but thanks for the advice, which might help other guilers off course] Thanks, David ;; -- Le Sun, 03 Apr 2011 21:16:00 +0200, Andreas Rottmann <a.rottm...@gmx.at> a écrit : > David Pirotte <da...@altosw.be> writes: > > > Hello, > > > > guile version: 2.0.0.160-39be > > > > this used to work: > > > > (define-syntax push* > > (syntax-rules () > > ((push* . ?args) > > (set! (car (last-pair ?args)) > > (cons* ?args))))) > > > Well, that's not well-formed code; there two problems here: > > (1) The first operand to `set!' has to be an identifier; in the > expansion of `push*', it is an expression. Actually, that's the > rule in plain R5RS and R6RS, but Guile contains hooks for > implementing SRFI-17, which allows for expressions in `set!'s first > operand; thus you get, with the above definition: > > scheme@(guile-user)> (use-modules (language tree-il)) > scheme@(guile-user)> (tree-il->scheme (macroexpand '(push* 1 2 lst))) > $4 = (((@@ (guile) setter) car) (last-pair (1 2 lst)) (cons* (1 2 lst))) > > And that, when called, yields the error you got (when SRFI-17 is not > loaded, as the default binding for `car' doesn't have a > setter). After importing SRFI-17, it still won't do what you > intended: > > scheme@(guile-user)> (use-modules (srfi srfi-17)) > scheme@(guile-user)> (push* 1 2 lst) > <unnamed port>:67:0: In procedure #<procedure 3dcdf00 at <current input>:68:0 > ()>: > <unnamed port>:67:0: Wrong type to apply: 1 > > The reason is the second issue: > > (2) `?args' is a pattern variable holding a list, and; so having > `(last-pair ?args)' is not OK: for `(push* 1 2 lst)', it expands to > `(last-pair? (1 2 lst))'. So you might quote `?args', but that > doesn't help to do what you want, because of the first issue. > > That the above code worked in Guile 1.8 can be considered an accident > (or even a bug, IMHO). > > A correct version would be: > > (define-syntax push* > (syntax-rules () > ((push* elements ... identifier) > (set! identifier (cons* elements ... identifier))))) > > Note that the above relies on R6RS-specified extensions to > `syntax-rules' patterns that are not yet available in Guile 1.8. > > HTH, Rotty