guile-user
[Top][All Lists]
Advanced

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

Re: syntax-rules problem


From: Andreas Rottmann
Subject: Re: syntax-rules problem
Date: Sun, 03 Apr 2011 21:16:00 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux)

David Pirotte <address@hidden> 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
-- 
Andreas Rottmann -- <http://rotty.yi.org/>



reply via email to

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