unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* Macro shadows everything in lexical environment
@ 2024-09-28 19:34 Adam Vagapov
  2024-09-29  9:12 ` Damien Mattei
  0 siblings, 1 reply; 2+ messages in thread
From: Adam Vagapov @ 2024-09-28 19:34 UTC (permalink / raw)
  To: guile-user

Hi everyone!

I am currently in the process of writing macros for shortening some 
common idioms I use in my Guile code.

One thing I am struggling to do is to take an identifier that already 
exists in the current lexical environment, and augment it by generating 
a new macro in the lexical environment with the same identifier.
The newly created macro shadows the old identifier, but needs access to 
the value that was once referred by the old identifier.

See this code for example:

     (define-syntax-rule (foo-macro id)
       (begin
	(define temp id) ;; <-- evaluate expression [1]

	(define-syntax-rule (id) ;; <-- create macro [2]
	  (begin
	    (display "in macro, temp=")
	    (display temp)
	    (newline)))))


     (define (bar)
       (let ((x 123))
	(foo-macro x) ;; <-- store x and make 'x' a macro.

	;; === 'x' should be a macro now ===

	(x) ;; <-- should print "in macro, temp=123"

	#f))

Here, [1] first requires the identifier as-is in the lexical environment 
to store its value in 'temp'. Only after storing it do I want to 
introduce the new macro.

However, what happens is that Guile tries to expand 'id' at 'temp' [1] 
with the newly created macro at [2]. That means I get this error in 'bar':

	Syntax error: source expression failed to match any pattern in form x

Because the new macro doesn't handle the case where 'x' is used as just 
an identifier. But I'd like the macro to only enter the lexical 
environment after 'temp' is set to 'x'.

A short test also reveals that every identifier before '(foo-macro x)' 
in the caller's site also gets shadowed by the new macro.

Is there some sort of method to remedy this?

Regards,
Adam



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Macro shadows everything in lexical environment
  2024-09-28 19:34 Macro shadows everything in lexical environment Adam Vagapov
@ 2024-09-29  9:12 ` Damien Mattei
  0 siblings, 0 replies; 2+ messages in thread
From: Damien Mattei @ 2024-09-29  9:12 UTC (permalink / raw)
  To: Adam Vagapov; +Cc: guile-user

it will be hard to make it work, perhaps with syntax features...

i find this variant that works at REPL and only :

scheme@(guile-user)> (define-syntax foo-macro

  (syntax-rules ()

    ((_ id)
     (define id (create-id-procedure id)))))


(define (create-id-procedure id)
  (define temp id)
  (define (new-funct)
    (display "in procedure, temp=")
    (display temp)
    (newline))
  new-funct) ; return new-funct
scheme@(guile-user)> (define x 123)
scheme@(guile-user)> (foo-macro x)
scheme@(guile-user)> (x)
in procedure, temp=123

indeed, always at REPL, note that your solution works in Racket:
#lang racket
(define-syntax-rule (foo-macro id)
       (begin
        (define temp id) ;; <-- evaluate expression [1]

        (define-syntax-rule (id) ;; <-- create macro [2]
          (begin
            (display "in macro, temp=")
            (display temp)
            (newline)))))

> (define x 123)
> (foo-macro x)
> (x)
in macro, temp=123

but only at toplevel too...
this restrict the use of both solutions.

But i really do not see the use you can do with replacing an identifier by
itself as a macro, perheaps thinking of refactoring your code differently
would be a good idea. If you can provide an example of your code someone
could help you.

regards,
Damien


On Sat, Sep 28, 2024 at 9:39 PM Adam Vagapov <adam.vagapov@outlook.com>
wrote:

> Hi everyone!
>
> I am currently in the process of writing macros for shortening some
> common idioms I use in my Guile code.
>
> One thing I am struggling to do is to take an identifier that already
> exists in the current lexical environment, and augment it by generating
> a new macro in the lexical environment with the same identifier.
> The newly created macro shadows the old identifier, but needs access to
> the value that was once referred by the old identifier.
>
> See this code for example:
>
>      (define-syntax-rule (foo-macro id)
>        (begin
>         (define temp id) ;; <-- evaluate expression [1]
>
>         (define-syntax-rule (id) ;; <-- create macro [2]
>           (begin
>             (display "in macro, temp=")
>             (display temp)
>             (newline)))))
>
>
>      (define (bar)
>        (let ((x 123))
>         (foo-macro x) ;; <-- store x and make 'x' a macro.
>
>         ;; === 'x' should be a macro now ===
>
>         (x) ;; <-- should print "in macro, temp=123"
>
>         #f))
>
> Here, [1] first requires the identifier as-is in the lexical environment
> to store its value in 'temp'. Only after storing it do I want to
> introduce the new macro.
>
> However, what happens is that Guile tries to expand 'id' at 'temp' [1]
> with the newly created macro at [2]. That means I get this error in 'bar':
>
>         Syntax error: source expression failed to match any pattern in
> form x
>
> Because the new macro doesn't handle the case where 'x' is used as just
> an identifier. But I'd like the macro to only enter the lexical
> environment after 'temp' is set to 'x'.
>
> A short test also reveals that every identifier before '(foo-macro x)'
> in the caller's site also gets shadowed by the new macro.
>
> Is there some sort of method to remedy this?
>
> Regards,
> Adam
>
>


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-09-29  9:12 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-28 19:34 Macro shadows everything in lexical environment Adam Vagapov
2024-09-29  9:12 ` Damien Mattei

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).