Musik als Listenelement an Guile übergeben

Begonnen von ingmar, Freitag, 21. Juni 2019, 14:59

« vorheriges - nächstes »

ingmar

Hallo Freunde,


ich definiere eine Funktion FOO, die eine Liste erwartet. Die Liste besteht aus Schlüssel-Wert-Paaren, bei einem Element (hier dem einzigen) handelt es sich um Musik. FOO sollte diese Musik zurückliefen. Das ist natürlich nur ein Minimalbeispiel ohne viel sittlichen Nährwert.

Mein Versuch:

\version "2.19.83"

FOO = #(define-music-function (meine-liste) ( list?)
(assq-ref meine-liste 'meine-musik)
)

MUSIC = \relative { c' d e f g1 }

\score { \FOO #(list '(meine-musik . \MUSIC)) }
\score { \FOO #(list '(meine-musik . { a1 })) }


Was mache ich falsch? Habt ihr eine Idee? : - )


Danke, Gruß,
--ingmar

harm6

Hallo Ingmar,

zwei Probleme seh' ich hier. Heutzutage kann man innerhalb eines ly-files lily-code in guile einbetten, und umgekehrt und verschachtelt.
Du mußt in der jeweils aktuellen Umgebung die dan gültigen Mechanismen zum Aufruf eines Wertes verwenden und natürlich auch sicherstellen, daß dieser Wert auch (falls gewünscht) evaluiert wird.

Z.B. (alles in einem ly-file):
(1)
MUSIC = \relative { c' d e f g1 }

kann innerhalb von guile nicht mittels \MUSIC aufgerufen werden:
#(display-scheme-music \MUSIC)
=>
Zitat von: terminalerror: GUILE signaled an error for the expression beginning here
#
(write \MUSIC)
Unbound variable: \MUSIC

Um ly-code in guile einzubetten gibts ja #{ #}
#(display-scheme-music #{ \MUSIC #})
funktioniert.

Aber das kann man einfacher haben, da ly-Definitionen in ly-files in guile direkt aufrufbar sind. d.h.:
#(display-scheme-music MUSIC)
ist einfacher.

(2)
Ein musikalischer Ausdruck, wie { a1 }, also keine Variable, wird von guile nur dann verstanden, wenn #{#} drum rum ist:
#(display-scheme-music #{ { a1 } #})

(3)
Eine Liste wie '(a b c) wird von guile buchstaben getreu verstanden.
Wenn Du etwas aus dieser Liste rausholst, wird das auch nur buchstabengetreu gemacht:
#(display-scheme-music (cdar (list '(meine-musik . MUSIC))))
gibt 'MUSIC zurück, ein symbol, nicht aber den evaluierten Wert der ly-Definition für MUSIC, die beiden haben nichts miteinander zu tun!
Wobei 'Music (quote MUSIC) entspricht.

Du kannst aber guile die Möglichkeit geben Werte zu evaluieren: mittels 'quasiquote'. Der Wert den Du tatsächlich evaluiert haben willst muß dann noch ein 'unquote' bekommen:
#(display-scheme-music (quasiquote (unquote MUSIC)))

Dafür gibts allerdings shortcuts in guile
` ist quasiquote
, ist unquote

Obiges kann man also auch so schreiben:
#(display-scheme-music `(,MUSIC))

(4)
Beim Aufruf Deiner Funktion mußt Du diese Punkte beachten.

In #(list '(meine-musik . \MUSIC)) ist \MUSIC ein symbol ohne weitere Relevanz.
Während #(list `(meine-musik . ,MUSIC)) MUSIC evaluiert.

In #(list '(meine-musik . { a1 })) ist { a1 } für guile völlig unverständlich.
Während in #(list `(meine-musik . ,#{ { a1 } #})) ein in guile korrekt eingebetteter musikalischer Ausdruck evaluiert wird.

Man kann das ganze noch ein bißchen kürzer schreiben (das komplette Beispiel):

FOO = #(define-music-function (meine-liste) (list?)
(assq-ref meine-liste 'meine-musik))

MUSIC = \relative { c' d e f g1 }

\score { \FOO #`((meine-musik . ,MUSIC)) }
\score { \FOO #`((meine-musik . ,#{ { a1 } #}))}


HTH,
  Harm



ingmar

Vielen Dank für die umfassende Antwort!

Bei (1) und (2)  schrei ich natürlich "das hätte ich wissen müssen!", (3) und (4) sind ja komplexer, da schäme ich mich gleich weniger... : - )

Viele der Schwierigkeiten des Alltags haben mit dem exakten Zusammenspiel zwischen LilyPond und Scheme zu tun; ich denke, wer das beherrscht, sollte in den allermeisten Fällen klarkommen. Dort gibt es selten hilfreiche Fehlermeldungen, was nicht als Vorwurf zu verstehen ist. Es wäre schon hilfreiche, wenn ein Editor wie Frescobaldi deutlich die LilyPond-Bereiche von den Scheme-Bereichen trennen würde, etwa durch eine Art Highlighting des Hintergrunds - Frescobaldi ist natürlich nicht Thema unseres Forums hier.

Ja, ich denke, meine Fragen sind geklärt; danke nochmal, auch für die ausführlichen Erklärungen.


Gruß,
--ingmar