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.vaga...@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
>
>

Reply via email to