lilypond-user
[Top][All Lists]
Advanced

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

Re: Having trouble understanding optional and variable amount of argumen


From: Stefano Troncaro
Subject: Re: Having trouble understanding optional and variable amount of arguments
Date: Fri, 9 Mar 2018 12:48:37 -0300

A few thoughts

I think macro definitions for all the define- functions can be avoided like this:
\version "2.19.80"
\include "oll-core/package.ily"

#(define-macro (with-options func-def-proc vars preds rulings . body)
   `(,func-def-proc ,(append '(opts) vars) ,(append '(ly:context-mod?) preds)
      (let* ((rules ,rulings)
             (props (context-mod->props rules #t opts)))
        . ,body)))

testRules =
#(with-options define-void-function () ()
   `((ind ,number? 5)
     (target ,symbol?)
     (payload)
     (accepted-arg ,fraction? opt)
     (accepted-without-type opt)
     (msg ,string? "No message given"))
   (pretty-print props))

\testRules \with {
  msg = "Something"
  unk = "Unknown option"
  target = something
%  accepted-arg = 7/4
%  accepted-without-type = #(ly:make-moment 3/16)
}

With respect on how to write the rule-set, based on your input I see a few possibilities:

1) A very slight modification of its current form
   `((rule-enforcement strict)
 (ind ,number? 5) (target ,symbol?) (payload) (accepted-arg ,fraction? opt) (accepted-without-type opt) (msg ,string? "No message given"))
This keeps the "list of lists" approach you wanted. I think that the parsing of the options could be set to 'flexible' by default and it can be made strict adding that as the first element of the list. Alternatively, a rule-enforcement element may be required.

2) Optional arguments could be anticipated with an opt instead of having it at the end:
   `((ind ,number? 5)
     (target ,symbol?)
     (payload)
     (opt accepted-arg ,fraction?)
     (opt accepted-without-type)
     (msg ,string? "No message given"))
This requires the same input as before but feels clearer to my eyes. I see what you mean about the POV defining what can be called optional. As I described earlier, the "caller" POV feels more intuitive for me but that may just be personal taste. Without more opinions it's difficult to tell.

3) The "elimination of unnecessary parens" is indeed a very minor thing. That approach felt instantly familiar because it resembles how function predicates are defined, in that only the proc is written when there is no default value, but the proc and the default value are parenthesized when they are needed together. In the same logic, I thought the key could be by itself when all one needed was to communicate "this is optional" or "this is required", and parenthesized with more information when needed.

My previous idea was merely just these three together. As you pointed out, I think the first is the one of real importance, and the others are more in the realm of QOL suggestions.

For now I'll await your thoughts, and I'll open a pull request later.

2018-03-09 4:29 GMT-03:00 Urs Liska <address@hidden>:


@Urs
I've thought about this some more. I don't know if you were interested in wrapping the functions that use opts and props in a macro, but I noticed a lot of redundancy so I gave it a try.
\version "2.19.80"
\include "oll-core/package.ily"

#(define-macro (define-void-function-with-options vars preds rulings . body)
   `(define-void-function ,(append '(opts) vars) ,(append '(ly:context-mod?) preds)
      (define rules
        ,rulings)
      (let ((props (context-mod->props rules #t opts)))
        . ,body)))

testRules =
#(define-void-function-with-options () ()
   `((ind ,number? 5)
     (target ,symbol?)
     (payload)
     (accepted-arg ,fraction? opt)
     (accepted-without-type opt)
     (msg ,string? "No message given"))
   (pretty-print props))

\testRules \with {
  msg = "Something"
  unk = "Unknown option"
  target = something
%  accepted-arg = 7/4
%  accepted-without-type = #(ly:make-moment 3/16)
}
Again, tell me if you find it convenient.


Hm.
The definition of testRules looks pretty good. What I'm not so sure about is that this would actually imply creating -with-options variants of *all* define- macros, and I'm not sure if that would add unnecessary complexity compared to "simply" calling context-mod->props within a function definition.

Actually, I start thinking if this doesn't call for a "proper" solution to be added to LilyPond itself. Of course I'm hijacking ly:context-mod? which is semantically there for a different purpose.
What I would like to see is a different predicate, say, ly:properties? that internally is a simple key-value alist but that can be entered with the same \with {} syntax.

Urs

_______________________________________________
lilypond-user mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/lilypond-user



reply via email to

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