[Top][All Lists]

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

Re: Threading / Pipe Macro

From: Chris Vine
Subject: Re: Threading / Pipe Macro
Date: Mon, 8 Jul 2019 01:10:42 +0100

On Sun, 07 Jul 2019 18:24:32 -0400
Mark H Weaver <address@hidden> wrote:
> Hi Chris,
> Here's a complete, unedited transcript with Guile 2.2.6:
> --8<---------------cut here---------------start------------->8---
> mhw@jojen ~$ guile
> GNU Guile 2.2.6
> Copyright (C) 1995-2019 Free Software Foundation, Inc.
> Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
> This program is free software, and you are welcome to redistribute it
> under certain conditions; type `,show c' for details.
> Enter `,help' for help.
> scheme@(guile-user)> (define-syntax ->
>   (lambda (x)
>     (syntax-case x ()
>       [(k exp0 . exps)
>        (let* ([reversed (reverse (cons (syntax->datum #'exp0)
>                                        (syntax->datum #'exps)))]
>               [out (let loop ([first (car reversed)]
>                               [rest (cdr reversed)])
>                      (if (null? rest)
>                          first
>                          (let ([func (car first)]
>                                [args (cdr first)])
>                            (append `(,func ,@args)
>                                    (list (loop (car rest) (cdr rest)))))))])
>          (datum->syntax #'k out))])))
> scheme@(guile-user)> (define t 'global-t)
> scheme@(guile-user)> (define-syntax-rule (foo x)
>                        (-> x (format #t "[t=~A] ~A\n" t)))
> scheme@(guile-user)> (let ((t 'inner-t))
>                        (foo t))
> [t=global-t] global-t
> $1 = #t
> scheme@(guile-user)> (define-syntax ->
>                        (syntax-rules ()
>                          ((-> exp)
>                           exp)
>                          ((-> exp ... (op args ...))
>                           (op args ... (-> exp ...)))))
> scheme@(guile-user)> (let ((t 'inner-t))
>                        (foo t))
> [t=global-t] inner-t
> $2 = #t
> scheme@(guile-user)>
> --8<---------------cut here---------------end--------------->8---
> Chris Vine <address@hidden> writes:
> > How strange.  Both your and my macro gives 'global-t' when I test them,
> Can you show me a complete, unedited transcript that demonstrates what
> you're seeing?
> > which is the result I would expect.  (Maybe I am missing something here,
> > but a result of 'inner-t' would seem to me to imply unhygiene.)
> (foo EXPR) is supposed to print "[t=global-t] VAL", where VAL is the
> result of evaluating EXPR.  With this in mind,
>     (let ((t 'inner-t))
>       (foo t))
> The argument to 'foo' here should refer to the lexical binding of 't',
> i.e. the variable with value 'inner-t'.  I'm curious what would make you
> expect otherwise.
> On the other hand, the reference to 't' in the template of the 'foo'
> macro should refer to the toplevel variable 't', because the template
> does not appear within the 'let'.
> This is a good example of why syntax objects are needed, to distinguish
> between these two references to distinct variables named 't'.  When you
> convert the references to datums, the distinctions are lost.

You will have seen that your post crossed with mine which agreed with

My assumption as it happens was that when all you were doing was
rearranging input forms then it was not possible when using it to have
"two distinct variables named 't'".  I have been proved to be wrong in
the case of your particular example of a macro in a macro.

Anyway, the original poster now has two implementations of a pipeline
operator which do work correctly, one using syntax-rules and one doing
it the harder way with syntax-case.  It had not occurred to me that
syntax-rules could actually do it.

It is a sufficiently useful macro that there seems to me to be a case
for putting it in guile.  As I mentioned, I use it frequently.


reply via email to

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