[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Threading / Pipe Macro
From: |
Mark H Weaver |
Subject: |
Re: Threading / Pipe Macro |
Date: |
Sun, 07 Jul 2019 18:24:32 -0400 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) |
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.
Regards,
Mark
Re: Threading / Pipe Macro, Erik Edrosa, 2019/07/07