Le lundi 03 avril 2023 à 20:12 -0400, Nate Whetsell a écrit : > Because this engraver doesn’t mention staffs at all, I’m not sure how this is > happening or how to fix it, and I’m hoping I’m missing something simple. Any > help would be greatly appreciated! A small test program follows.
I see ``` #(lambda (context) (let ((span '()) (stub '()) (event-drul '(() . ()))) ^^^^^^^^^^^ ``` then ``` `((listeners (frame-event . ,(lambda (engraver event) (if (= START (ly:event-property event 'span-direction)) (set-car! event-drul event) ^^^^^^^^^^^^^^^^^^^^^^^^^^ (set-cdr! event-drul event))))) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ``` This is Bad (™). Quoting is a more subtle concept than many people think. For example, many beginner/intermediate and even advanced Scheme programmers do not realize that ``` $ LC_ALL=C.UTF-8 ~/lilies/2.25.3/bin/lilypond scheme-sandbox GNU LilyPond 2.25.3 (running Guile 2.2) Processing `/home/jean/lilies/2.25.3/share/lilypond/2.25.3/ly/scheme-sandbox.ly' Parsing... GNU Guile 2.2.7 Copyright (C) 1995-2019 Free Software Foundation, Inc. Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'. This program is free software, and you are welcome to redistribute it under certain conditions; type `,show c' for details. Enter `,help' for help. scheme@(#{ g123}#)> (define (f) (list 'a 'b 'c)) scheme@(#{ g123}#)> (eq? (f) (f)) $1 = #f scheme@(#{ g123}#)> (define (f2) '(a b c)) scheme@(#{ g123}#)> (eq? (f2) (f2)) $2 = #t ``` When you quote something, you always get the same thing, as per `eq?`, i.e., identity. Therefore, the two engraver instances are sharing the same pair of events, which is obviously troublesome. By the way, you can debug Scheme code by adding `#(ly:set-option 'compile-scheme-code)` (see [this](https://lilypond.org/doc/v2.25/Documentation/extending/debugging-scheme-code); caveat: does not work on Windows right now). If you do this, you will get a Guile error about attempting to mutate a literal pair. If you read section 3.4 of the [R5RS](https://conservatory.scheme.org/schemers/Documents/Standards/R5RS/r5rs.pdf), you can find “In many systems it is desirable for constants (i.e. the val- ues of literal expressions) to reside in read-only-memory. To express this, it is convenient to imagine that every object that denotes locations is associated with a flag telling whether that object is mutable or immutable. In such systems literal constants and the strings returned by symbol->string are immutable objects, while all objects created by the other procedures listed in this report are mutable. It is an error to attempt to store a new value into a location that is denoted by an immutable object.” Note that “it is an error” means the program is invalid, not that the implementation is required to detect the error. Guile does it for byte-compiled code (when you use `compile-scheme-code`). It unfortunately doesn't for interpreted code, as in the default mode in LilyPond. The fix here is to change `'(() . ())` to `(cons '() '())` to create a fresh pair for each engraver. Jean
signature.asc
Description: This is a digitally signed message part