[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: hygiene and macro-introduced toplevel bindings
From: |
Hans Aberg |
Subject: |
Re: hygiene and macro-introduced toplevel bindings |
Date: |
Sun, 27 Feb 2011 23:02:05 +0100 |
On 27 Feb 2011, at 22:37, Andy Wingo wrote:
> Andreas has been struggling with a nonstandard behavior of Guile's
> recently, and we should discuss it more directly.
>
> The issue is in expressions like this:
>
> (define-syntax define-accessor
> (syntax-rules ()
> ((_ getter setter init)
> (begin
> (define val init)
> (define getter (lambda () val))
> (define setter (lambda (x) (set! val x)))
>
> (define-accessor get-x set-x! 0)
>
> The issue is, what happens when this expression is expanded?
>
> Within a let or a lambda, it expands to an three internal definitions:
> `val', `getter', and `setter', where `val' is only visible to within the
> `getter' and `setter' procedures.
>
> At the top level, it expands to three definitions: "val", the getter,
> and the setter. However in this case the "val" binding is global to the
> module, and can be referenced by anyone.
>
> This is what happens in Guile.
When implementing environments with returns and loops with break and continue,
I was not able to produce global symbols. This was under 1.8, though, so
perhaps it has changed.
My solution was to introduce it as a variable in the macro, and then generate
it globally in my program, which generates Guile C-calls. This is the example:
; Macro "environment": (environment return ...) puts the arguments ... into
; a new environment, then evaluated as an imperative sequence; "return x" causes
; x to be returned from the environment
(define-syntax environment
(syntax-rules ()
((environment)
(values))
((environment return (x ...))
(call-with-current-continuation (lambda (return) x ...)))
((environment return label (x ...))
(call-with-current-continuation
(lambda (return) (let ((label return)) x ...))))
))
Here, 'return', is just a variable. But I let the user to write "return
<tuple>", and the value of <tuple> will become the return value of the
environment if called.
There is a variation of the Guile 'while' statement. Then
But it illustrates my problem: I would like a mechanism to control whether a
variable in a macro should be visible or not. It can be tied in the macro in
some lambda-expression, but one may want it visible outside. - The construction
is a bit too hygienic, in other words.
Hans