bug-lilypond
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Scheme parameters names lost with Lilypond 2.23.8


From: Jean Abou Samra
Subject: Re: Scheme parameters names lost with Lilypond 2.23.8
Date: Sun, 1 May 2022 20:53:22 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.8.1

Le 01/05/2022 à 20:29, Stéphane SOPPERA a écrit :
Hi,

While trying to make sure my automatic documentation generation code works with Lilypond 2.23.8 (and especially Guile 2.2) I noticed a bug that may be due to how Lilypond is using Guile 2.2. The current version of my code uses /(p//rocedure-source)/ <https://github.com/soppera/lilypond-harmony-rules/blob/master/generate-doc.scm#L45> to get the names of the parameters of my functions & methods and generate the documentation. I noticed that with Guile 2.2 I always get /#f/ when I call /(//procedure-source)/. But we now have /(program-lambda-list)/ <https://www.gnu.org/software/guile/manual/html_node/Compiled-Procedures.html> that removes the need from parsing the source to get the parameter names.

Thus I tried to use /(program-lambda-list)/ to get the parameters names with Lilypond 2.23.8 (i.e. Guile 2.2) but this fails and instead I get anonymized parameters ("a", "b"... instead of the expected values).

To illustrate the issue let's first see what happens with Lilypond 2.22 (and thus Guile 1.8), compiling:

\version "2.22.0"

#(begin
  (define (f lhs rhs) (+ lhs rhs))

  (display "\nUsing Guile ")
  (display (version))
  (newline)

  (display "source: ")
  (display (procedure-source f))
  (newline))

prints:

GNU LilyPond 2.22.2
Processing `test_2.22.ly'
Parsing...
Using Guile 1.8.7
source: (lambda (lhs rhs) (+ lhs rhs))

(we can't use /(program-lambda-list)/ here since it is not supported by Guile 1.8)

With Lilypond 2.23 (and thus Guile 2.2), compiling:

\version "2.23.8"

#(begin
  (use-modules (system vm program))
  (define (f lhs rhs) (+ lhs rhs))

  (display "Using Guile ")
  (display (version))
  (newline)

  (display "λ-list: ")
  (display (program-lambda-list f))
  (newline)

  (display "source: ")
  (display (procedure-source f))
  (newline))

prints:

GNU LilyPond 2.23.8 (running Guile 2.2)
Processing `test_2.23.ly'
Parsing...Using Guile 2.2.7
λ-list: *(a b)*
source: *#f*

We can see that:

1. We don't have access to the function source anymore (as when using
   Guile 2.2 directly).
2. /(program-lambda-list)/ returns "(a b)" instead of "(lhs rhs)",
   erasing the parameters' names.

To confirm if this is the default behavior of Guile 2.2, I tested this Guile script:

(use-modules (system vm program))
(define (f lhs rhs) (+ lhs rhs))

(display "Using Guile ")
(display (version))
(newline)

(display "λ-list: ")
(display (program-lambda-list f))
(newline)

(display "source: ")
(display (procedure-source f))
(newline)

Running Guile command line tool on this script with the default parameters result in:

Using Guile 2.2.7
λ-list: (lhs rhs)
source: #f

We can see that:

1. Guile 2.2 does not return the source either.
2. Guile 2.2 does return "(lhs rhs)" as expected,  and not "(a b)" as
   Lilypond 2.23.8 is doing.

I dig a bit further into this issue and I can make Guile 2.2 behave like Lilypond by using the flags:

 * --fresh-auto-compile
 * --no-auto-compile

*With those two flags *I indeed get the same output as with Lilypond 2.23.8:

Using Guile 2.2.7
λ-list: (a b)
source: #f

Note that using --fresh-auto-compile is _mandatory_ since without it Guile seems to use previous auto-compilation's output and indeed prints the correct list of parameters.


To summarize the issues:

 * Lilypond 2.23.8 is using Guile 2.2 which does not support
   /(//proceduce-source)/ anymore.
 * But Guile 2.2 offers /(program-lambda-list)/ which can replace the
   use of /(//proceduce-source)/ to get the parameters' names.
 * The issue is that the way Lilypond 2.23.8 uses Guile 2.2 erases the
   parameter names returned by /(program-lambda-list)/, making it
   impossible to use this method either.



Yes, LilyPond uses the evaluator and not the compiler. The
problem with compilation is that it takes time. Most
code snippets within LilyPond source files are very
short and run fast, so compilation is going to dominate
execution. Since Guile 2 is slow at compiling, with the
intent being that you do it ahead of time, we have a performance
issue. It is actually possible that we will move to compiling
anyway, because this might make for better error message.
But it can't be done without careful thought.

Meanwhile, I wouldn't consider this a bug on the LilyPond side,
more like something to report at Guile.

If you need correct signatures, you can call the compiler explicitly:

\version "2.23.9"

#(use-modules (system base compile))
#(define f
   (compile
    '(lambda (a b)
       'x)))

#(use-modules (system vm program))
#(display (program-lambda-list f))
%% This is actually more powerful:
#(use-modules (ice-9 session))
#(display (procedure-arguments f))


Probably most reliably, you can also define a macro that catches
the arguments.

\version "2.23.9"

#(define args-prop (make-object-property))

#(define (find-lvalue syntaks)
   (syntax-case syntaks ()
     ((first . rest)
      (find-lvalue #'first))
     (x
      #'x)))

#(define-syntax define-documented
   (lambda (syntaks)
     (syntax-case syntaks ()
       ((_ target expr)
         #`(begin (define target expr)
                  (set! (args-prop #,(find-lvalue #'target))
                        'target))))))

#(define-documented (f a b c)
   'x)

#(display (f 1 2 3))
#(newline)
#(display (args-prop f))


Best,
Jean



reply via email to

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