guile-devel
[Top][All Lists]
Advanced

[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





reply via email to

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