Hi Stéfano,
Am 09.03.2018 um 16:48 schrieb Stefano Troncaro:
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-optionsdefine-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) }
Yes, I like this very much. You still have the familiar
define-X-function with the args and predicates in the usual place, but
with 'with-options' you signal that there will be a rule set for options.
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'm not 100% sure if I have a strong opinion between this and your
hierarchical suggestion. But I *think* I like this one more.
I agree with you that options with a default value become optional and
should not have to be flagged as such separately.
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.
I suggest to require the statement about rule-enforcement because
otherwise one would probably always confuse things.
But *if* we require it - and as the first element - it doesn't have to
be a list (which would BTW rule out an option with that name) but can be
a symbol:
`(strict
(ind ,number? 5)
...
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 partially disagree. Not with the idea of having the flag in front of
the list but with using a/that symbol. Apart from ruling out 'opt as an
option name (OK, in my implementation 'opt couldn't be used as a
*default*) I think this is confusing because you have a first "column"
of payload - opt - msg.
What do you think about
`(strict
(ind ,number? 5)
(target ,symbol?)
(payload)
(? accepted-arg ,fraction?)
(? accepted-without-type)
(msg ,string? "No message given"))
?
Technically it's still a symbol but indicates much better the idea of
"optional".
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.
I'd be glad about a PR along these lines!
Best
Urs
2018-03-09 4:29 GMT-03:00 Urs Liska <li...@openlilylib.org
<mailto:li...@openlilylib.org>>:
@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
lilypond-user@gnu.org <mailto:lilypond-user@gnu.org>
https://lists.gnu.org/mailman/listinfo/lilypond-user
<https://lists.gnu.org/mailman/listinfo/lilypond-user>
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user