Scheme: Optionale Parameter? [Gelöst]

Begonnen von ingmar, Mittwoch, 4. Juli 2018, 13:06

« vorheriges - nächstes »

ingmar

Hallo Freunde,


im Internet finde ich folgende Syntax:

    myFunction = #(define* (a b #:optional (c 17))
    )

Dann kann ich myFunction entweder mit den Parametern a b c aufrufen, oder nur mit a b - wobei dann der Wert 17 für c angenommen wird.

Ich frage mich, ob es sowas auch für define-scheme-function, define-music-function usw. gibt.

Sorry, Kein Minimalbeispiel.


Gruß,
--ingmar

Manuela

Danke für eure Hilfe
viele Grüße
-- Manuela

ingmar

Ja, stimmt.

Ich hab mir da die erste Antwort von Harm rausgepickt. Ich will nie Musik übergeben, eigentlich nur Strings oder Zahlen. Also, nach dem, was ich da verstehe, müsste das etwa so gehen:

\version "2.19.64"
test = #(define-music-function (aa bb) (string? (integer? 42)) #{
\score {
\new Staff \with { instrumentName = $aa } {
\repeat unfold $bb { c' }
}
}
#})

\test "Horn" #16


Das Horn tutet aber nicht – und es sind bestimmt wieder sieben Fehler, die ich alle längst wissen müsste... : - (

--ingmar

Malte

Ohne es getestet zu haben:

\score { ... }

ist kein Musik-Ausdruck, define-music-function müßte aber einen zurückgeben. Vielleicht reichts schon, diesen \score wegzulassen ;)

ingmar

Ja! Richtig.

Und mit define-scheme-function funktioniert es auch. So brauche ich es. Nur eben – der Parameter ist nicht optional:

\version "2.19.64"
test = #(define-scheme-function (aa bb) (string? (integer? 42)) #{
\score {
\new Staff \with { instrumentName = $aa } {
\repeat unfold $bb { c' }
}
}
#})

\test "Horn"


Gruß, danke,
--ingmar

harm6

Der optionale Parameter muß zuerst kommen.


\version "2.19.82"

test = #(define-scheme-function (bb aa) ((integer? 42) string?) #{
\score {
\new Staff \with { instrumentName = $aa } {
\repeat unfold $bb { c' }
}
}
#})

\test "Horn"


Aber wie früher schon gesagt, optionale Argumente in ly-syntax unterliegen starken Beschränkungen...

Gruß,
  Harm

ingmar

Ja, dass der optionale Parameter zuerst kommt, hatte ich schon an deinem Code gesehen, aber offenbar nicht geglaubt. Bei den Programmiersprachen, die ich kenne, ist das halt anders, und viele werden es als intuitiver empfinden, zuerst sozusagen die wichtigen und häufigen Sachen und erst anschließend die seltenen zu nennen.

Ich verstehe (Arnold hatte darauf hingewiesen), dass es für LilyPond natürlich entscheidend ist, aus dem Zusammenhang klar zu erkennen, ob der optionale Parameter nun mit übergeben wurde oder nicht. In meinen Zusammenhängen, wo jedenfalls nicht Musik übergeben wird, scheint das aber zu klappen.

Dank an alle für die schnellen und hilfreichen Antworten!

--ingmar

ingmar

#7
Noch ein abschließender Gedanke, der vielleicht dem nächsten hilft, der sich mit dem Thema herumschlägt. Ich hatte mich gefragt, ob man vielleicht erreichen kann, dass als Parameter wahlweise ein Einzelwert oder ein Wertepaar gestattet ist. Durch die Syntax mit dem Punkt wäre beim Aufruf eindeutig, was passiert, und es müsste sich in vielen Fällen auch gar nicht unnatürlich anfühlen.

Für meinen Fall ist das aber wohl nicht nötig.

Gruß,
--ingmar

harm6

Zitat von: ingmar
Ja, dass der optionale Parameter zuerst kommt, hatte ich schon an deinem Code gesehen, aber offenbar nicht geglaubt. Bei den Programmiersprachen, die ich kenne, ist das halt anders, und viele werden es als intuitiver empfinden, zuerst sozusagen die wichtigen und häufigen Sachen und erst anschließend die seltenen zu nennen.

Nun, LilyPond-syntax ist keine Programmiersprache, sondern eine Eingabesprache. Die Erweiterungssprache (und damit eine echte Programmiersprache,) ist guile.

Auch muß ein optionales Argument einer music-function zuerst kommen, da ansonsten nicht klar sein kann wann die Argumente der function (die optionalen und notwendigen) vollständig sind.

Zitat von: ingmarNoch ein abschließender Gedanke, der vielleicht dem nächsten hilft, der sich mit dem Thema herumschlägt. Ich hatte mich gefragt, ob man vielleicht erreichen kann, dass als Parameter wahlweise ein Einzelwert oder ein Wertepaar gestattet ist. Durch die Syntax mit dem Punkt wäre beim Aufruf eindeutig, was passiert, und es müsste sich in vielen Fällen auch gar nicht unnatürlich anfühlen.

Hier weiß ich nicht genau was Du meinst.

In guile gibt es:
(define (proc arg . rest) ( ... body ...))
wobei proc eine Reihe von Argumenten tragen kann, die neben `arg` im body als Liste bearbeitbar sind.
Aber in guile ist es durch die Klammern absolut klar, wann es zu Ende ist.

(proc arg arg1 arg2 arg3) hat vier Argumente, das ist eimdeutig aber wie soll das in LilyPond deutlich gemacht werden?

Gruß,
  Harm


ingmar

Zitatingmar: Noch ein abschließender Gedanke, der vielleicht dem nächsten hilft, der sich mit dem Thema herumschlägt. Ich hatte mich gefragt, ob man vielleicht erreichen kann, dass als Parameter wahlweise ein Einzelwert oder ein Wertepaar gestattet ist. Durch die Syntax mit dem Punkt wäre beim Aufruf eindeutig, was passiert, und es müsste sich in vielen Fällen auch gar nicht unnatürlich anfühlen.

Harms: Hier weiß ich nicht genau was Du meinst.

Na, ich dachte, wir wollen zwischen Pflicht-Parametern einen einzelnen Parameter optional machen. Vielleicht geht es dadurch, dass wir (wie auch immer) einen der Pflicht-Parameter so definieren, dass er entweder einen Einzelwert oder alternativ ein Paar erlaubt. Die Notation des Paars mit dem Punkt würde syntaktisch immer klarstellen, ob der optionale Parameter nun mitgegeben wurde oder nicht.

Wie gesagt, für meine Zwecke reicht, was wir jetzt haben.

Gruß, Danke,
--ingmar