Hi David,

Thank you for your reply. Yes, I undestood that about macros. I'm trying to
dynamically generate the variable definitions inside a let block from an
alist, but the only way I manage to do that is if I type the alist
manually. I want to achieve that with an alist stored in a variable.
Simplified example:

> \version "2.19.80"
> #(define-macro (custom-let alist . body)
>    `(let ,(map (lambda(pair) (list (car pair) (cdr pair))) alist)
>       . ,body))
>
> #(custom-let ((my-key . "my-val") (another-key . "another-val"))
>    (pretty-print my-key)
>    (pretty-print another-key))%Outputs:
> %"my-val"
> %"another-val"
> #(define my-alist '((my-key . "my-val") (another-key . "another-val")))
>
> #(custom-let my-alist
>    (pretty-print my-key)
>    (pretty-print another-key))%No applicable method for #<<extended-generic> 
> map (0)> in call (map #<procedure #f (pair)> my-alist)
>
> This is why I wanted to be able to evaluate the contents of the variable
inside the body of the macro. I thought of manually evaluating the
argument, but if I understand correctly it is not possible to do it in the
correct scope (only globally and not locally)? If so, then do you have a
suggestion to solve the problem showed above?

2018-03-28 16:23 GMT-03:00 David Kastrup <d...@gnu.org>:

> Stefano Troncaro <stefanotronc...@gmail.com> writes:
>
> > Hi everyone!
> >
> > I have a question about the following example:
> >
> >> \version "2.19.80"
> >> #(define-macro (why-the-difference obj)
> >>    (display (format "~a , " obj))
> >>    `(display (format "~a\n" ,obj)))
> >>
> >> #(why-the-difference (list 1 2 3))% => (list 1 2 3) , (1 2 3)
> >> #(define var (list 1 2 3))
> >>
> >> #(why-the-difference var)% => var , (1 2 3)
> >>
> >> So, I assume that the difference is because the macro has access to what
> > is typed, and uses that to produce an expression that is later evaluated.
> > So, in the first example, (list 1 2 3) was typed, so that's shown in the
> > output before the comma. While in the second example, var was typed, so
> the
> > symbol var is shown instead.
> >
> > Is there a way to evaluate the symbol inside the body of the macro?
>
> Not reliably.  It's a rather loosely defined point of time.
>
> > I tried the following to no avail:
> >
> >> \version "2.19.80"
> >> #(use-modules (ice-9 r5rs))
> >>
> >> #(define-macro (my-attempt obj)
> >>    (display (format "~a , " (eval 'obj (interaction-environment))))
> >>    `(display (format "~a\n" ,obj)))
>
> Well, that's completely wrong.  (interaction-environment) is a _global_
> environment.  It does not have access to local variables/symbols like
> obj.  So you'd want to write
>
> (eval obj (interaction-environment)) if at all, and even then this will
> only work for global variables.
>
> >> #(define var (list 1 2 3))
> >>
> >> #(my-attempt var)
> >>
> >> This generates the error 'unbound variable: obj'. I don't understand why
> > obj is not considered defined, when if I use obj I get the symbol var (as
> > the first snippet showed). Anyways, I *can* evaluate var:
> >
> >> \version "2.19.80"
> >> #(use-modules (ice-9 r5rs))
> >>
> >> #(define-macro (my-attempt obj)
> >>    (display (format "~a , " (eval 'var (interaction-environment))))
> >>    `(display (format "~a\n" ,obj)))
> >>
> >> #(define var (list 1 2 3))
> >>
> >> #(my-attempt var)% => (1 2 3) , (1 2 3)
> >>
> >> Which makes sense. This achieves what I want but it is not useful
> because
> > I need to know the name of the variable before-hand, so it will not work
> > dynamically.
> >
> > Does anyone know of a way around this?
>
> Apparently you don't understand what a macro does.  A macro receives its
> arguments _unevaluated_, and the result is later evaluated in the
> closure where the macro is called.  (eval obj (interaction-environment))
> is exactly equivalent to (eval 'var (interaction-environment)) here.
>
> --
> David Kastrup
>
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to