Autor Thema: define-music-function mit optionalem Argument? Wenn ja, wie?  (Gelesen 1610 mal)

Manuela

  • Gast
define-music-function mit optionalem Argument? Wenn ja, wie?
« am: Mittwoch, 30. März 2016, 06:24 »
Hi,

ich denke, die Überschrift besagt eh schon alles  :)

harm6

  • Gast
Re: define-music-function mit optionalem Argument? Wenn ja, wie?
« Antwort #1 am: Mittwoch, 30. März 2016, 11:36 »
Im Prinzip gehts.
Gebe bei den Argument-Prädikaten einen default an und setze beides in Klammern. In der Praxis wird es häufig Probleme geben, z.B, darf das Prädikat nur einmal vorkommen sonst kriegt der Parser es nicht sortiert. Mit multiplen optionalen Argumenten potenzieren sich die Probleme.
In scheme (genauer gesagt ohne das define-music-function-makro) wäre es einfacher mittels #:optional...

Beispiel für define-music-function:

foo =
#(define-music-function (mrkp mus)((markup? "") ly:music?)
#{
  <>-\markup #mrkp $mus
#})

\foo { c''1 }
\foo "bla" { c''1 }
\foo \markup \bold "bla" { c''1 }

HTH,
  Harm
« Letzte Änderung: Mittwoch, 30. März 2016, 11:38 von harm6 »

Manuela

  • Gast
Re: define-music-function mit optionalem Argument? Wenn ja, wie?
« Antwort #2 am: Mittwoch, 30. März 2016, 15:10 »
Danke Harm.

In Scheme würde ich das inzwischen sogar selbst schaffen  ;)

Leider habe ich drei ly:music Parameter, da sind die Chancen also gering

harm6

  • Gast
Re: define-music-function mit optionalem Argument? Wenn ja, wie?
« Antwort #3 am: Mittwoch, 30. März 2016, 15:58 »
Naja, vielleicht kann man was tricksen.
Hast Du ein kleines Beispiel?

Gruß,
  Harm

Manuela

  • Gast
Re: define-music-function mit optionalem Argument? Wenn ja, wie?
« Antwort #4 am: Mittwoch, 30. März 2016, 19:37 »
Danke für dein Interesse  :)

Hier ein wirklich sehr kleines Beispiel:

\version "2.19.37"

myTestProgramm=
#(define-music-function (mus1 mus2 mus3)
   (ly:music? ly:music? ly:music?)
   (make-sequential-music
    (append (list mus1) (list mus2) (list mus3))
    ))

MusI=\relative c { c' d e }
MusII=\relative c { < c'' d e > }
MusIII =\relative c { g' a c }

\myTestProgramm \MusI \MusII \MusIII

Ich habe jetzt folgendes probiert:

myTestProgramm=
#(define-music-function (mus1 mus2 mus3)
   (ly:music? ly:music? (ly:music? #{ { cis'' } #} ))
   (make-sequential-music
    (append (list mus1) (list mus2) (list mus3))
    ))

MusI=\relative c'' { c d e }
MusII=\relative e'' { < c d e > }
MusIII =\relative c'' { g a c }

\myTestProgramm \MusI \MusII

Das liefert einen Fehler
« Letzte Änderung: Mittwoch, 30. März 2016, 19:43 von Manuela »

harm6

  • Gast
Re: define-music-function mit optionalem Argument? Wenn ja, wie?
« Antwort #5 am: Mittwoch, 30. März 2016, 21:40 »
Das Beste was ich Dir anbieten kann:

\version "2.19.36"
myTestProgramm=
#(define-music-function (mus1 mus2 mus3)
   (ly:music? ly:music? ly:music?)
   (make-sequential-music (list mus1 mus2 mus3)))

MusI=\relative c'' { c d e }
MusII=\relative e'' { < c d e > }
%MusIII =\relative c'' { g a c }

#(if (not (defined? 'MusIII))
     (define MusIII #{ { cis''1 } #}))

\myTestProgramm \MusI \MusII \MusIII

HTH,
  Harm

Manuela

  • Gast
Re: define-music-function mit optionalem Argument? Wenn ja, wie?
« Antwort #6 am: Mittwoch, 30. März 2016, 21:45 »
Danke, wieder was gelernt.  :D

In dieser define-music-function darf ich weniger machen als in einer normalen Prozedur, habe ich festgestellt. Wo kann ich denn eine genauere Beschreibung finden? Oder gibt es keine, muss man dafür den Lilypond Sourcecode durchforsten?

harm6

  • Gast
Re: define-music-function mit optionalem Argument? Wenn ja, wie?
« Antwort #7 am: Mittwoch, 30. März 2016, 22:45 »
source-code ...
Ist in music-functions.scm

die Beschreibung dort:

Zitat
  "Defining macro returning music functions.
Syntax:
  (define-music-function (arg1 arg2 ...) (arg1-type? arg2-type? ...)
    ...function body...)

argX-type can take one of the forms @code{predicate?} for mandatory
arguments satisfying the predicate, @code{(predicate?)} for optional
parameters of that type defaulting to @code{#f}, @code{@w{(predicate?
value)}} for optional parameters with a specified default
value (evaluated at definition time).  An optional parameter can be
omitted in a call only when it can't get confused with a following
parameter of different type.

Must return a music expression.  The @code{origin} is automatically
set to the @code{location} parameter."

Ist aber kein manual ;)


Gruß,
  Harm

Arnold

  • Gast
Re: define-music-function mit optionalem Argument? Wenn ja, wie?
« Antwort #8 am: Donnerstag, 31. März 2016, 09:39 »
Hallo Manuela,

ein "Problem" liegt gewissermasen in der allgemeinen Funktionssyntax: Wo endet die Liste der an die Funktion zu übergebenden Parameter?
Vor allem, wenn deine Funktion innerhalb einer "Sequential Music" steht und mit nur zwei Parametern aufgerufen werden soll, aber danach ein weiteres ly:music?-Element kommen soll, dann wird es schon schwierig es eindeutig zu definieren.

Mein Trick ist, eine Funktion zu definieren, welche zwar eine feste Anzahl von Parametern fordert, aber als Typ quasi »ly:music-or-boolean?« akzeptiert. Im Aufruf wird dann ##f für das »nicht vorhandene optionale Argument« angegeben. Und anhand einer Typabfrage entscheidet das Programm, was zu tun ist.

Ich müßte noch mal in meinem "line breaking rehearsal mark" nachsehen, was ich dort angestellt habe, denn dort können für den "linken" und für den "rechten" Text eine Zeichenkette, ein Markup, der Logikwert ##t oder der Logikwert ##f angegeben werden, um verschiedenen effekte zu erzielen.

Arnold

Arnold

  • Gast
Re: define-music-function mit optionalem Argument? Wenn ja, wie?
« Antwort #9 am: Freitag, 1. April 2016, 09:12 »
Hallo Manuele,

ich habe eine eigene Typ-Prüfungs-Funktion definiert, z. Bsp.:
#(define-public (music-or-boolean? m)
  (or (ly:music? m) (boolean? m)))

In meiner »Music-Function« habe ich diesen Kombinations-Typ als Parametertyp angegeben, und später dann den (echten) Typ abgefragt. Z. Bsp.:
MeneFunktion =
#(define-music-function
  (parser location m-one m-two m-three)
  (music-or-boolean? music-or-boolean? music-or-boolean?)
  ; u.s.w.
   (if (ly:music?) m-one)
   ; IF-Zweig / Returnwert
   ; ELSE-Zweig / Returnwert
  ; u.s.w.

Arnold

Manuela

  • Gast
Re: define-music-function mit optionalem Argument? Wenn ja, wie?
« Antwort #10 am: Freitag, 1. April 2016, 09:19 »
Danke Arnold,

die Idee mit dem gemischten Typ ist natürlich genial.  :D

Ich sehe, du gehörst zu den Genies, die das Lilypond Code Snippet Archiv befüllen.

Inzwischen verstehe ich schon, was der Ausdruck (or (ly:music? m) (boolean? m)) bewirkt, vor 2 Wochen wäre das hauptsächlich Verwunderung bei mir gewesen  :)

Update: könnte man nicht auch sowas definieren?

#(define-public (music-oder-nicht? m)
  (or (ly:music? m) #f)

Noch 'n Update: das #f ist eigentlich überflüssig?
« Letzte Änderung: Freitag, 1. April 2016, 09:29 von Manuela »

Arnold

  • Gast
Re: define-music-function mit optionalem Argument? Wenn ja, wie?
« Antwort #11 am: Montag, 4. April 2016, 09:40 »
Hallo Mnauela,

definieren kann man viel, aber Dein Vorschlag ist leider nicht zielführend.
Die Funktionsnamen mit Fragezeichen am Schluß werden »per Übereinkunft« dazu benutzt, um den Typ einer Variablen zu prüfen.
Also würde ich erwarten, daß »music-or-not?« sowohl bei einem Typ »ly:music?«, als auch wenn es kein Typ »ly:music?« ist, ##t zurückgibt - dann könnte man gleich »scheme?« verwenden.

Will man einen eingeschränkteren Tast, also »entweder ly:music? oder der boolean-Wert ##f«, dann könnte die Formel dazu »(or (ly:music? m) (and (boolean? m) (not m)))« lauten.
Da aber in SCHEME fast alles außer dem ##f quasi als ##t behandelt wird, könnte man sich sogar die Prüfung auf »boolean?« schenken, dann bliebe »(or (ly:music? m) (not m))« .
Diese Typ-Prüf-Funktion würde ich dann »music-or-false?« nennen - aber zugegebenermaßen kann auch das zu der gleichen Fehlinterpretation führen wie dein vorgeschlagener Funktionsname., aber »music-or-boolean-value-false?« wäre mir wieder etwas lang.

Arnold