Re: Having trouble understanding optional and variable amount of arguments

2018-03-09 Thread Urs Liska

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 >:





@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
 

Re: Having trouble understanding optional and variable amount of arguments

2018-03-09 Thread 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-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 :

>
>
> @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
> https://lists.gnu.org/mailman/listinfo/lilypond-user
>
>
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-03-08 Thread Urs Liska




@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
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-03-08 Thread Urs Liska



Am 08.03.2018 um 23:46 schrieb Stefano Troncaro:

@Urs
With your last update, the following syntax popped to mind:

\version  "2.19.80" %Functional copy of your example #(define  rules
`(strict
   (req payload
(target ,symbol?))
   (opt accepted-without-type
(accepted-arg ,fraction?)
(ind ,number?  5)
(msg ,string?  "No message given"

%Accepts any argument, but provides a type-check and a default for
msg #(define  rules2
`(flexible
   (opt (msg ,string?  "No message given"



I'll think about it later today, just a few short comments for now:


I like it because:
1) It eliminates the need for the boolean argument to 
context-mod->props, and puts that information together with all the 
other rules, which makes them easier to read and parse (mentally) 
because all the information is in the same place. I know it's a minor 
thing but it's not much more typing and it feels cleaner to me. The 
other way you have a 'rules object' that does not contain the whole 
ruleset.


Very good point.


2) It eliminates unnecessary parens.


I'm not sure this is relevant. You don't need to put them around untyped 
options but you have to add another layer around everything.


What I liked about my implementation (as opposed to the first ideas) was 
that it's flat, a simple list of lists. But probably I'll consider this 
as weighing less than 1)



3) It eliminates the need to flag many arguments with opt.


I don't have a strong opinion on that on first sight.

4) Also, arguments that have default values feel optional to me, and 
here they are grouped together. With this I can at first glance know 
what arguments I need to give and what is optional.


What you're proposing is focused on the POV of the *caller* of the 
function (i.e. the document author), while my approach was focused on 
what the *code* needs to be present.
As said I'll have to think more closely about it later today, but you 
may have a good point here too.




It may have defects I'm not seeing. What do you think? If you like it 
I can do the rework.


You may of course open a pull request. Maybe we'll discuss details but I 
have no objections so far.


Best
Urs

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-03-08 Thread Stefano Troncaro
@Harm
I can't imagine how frustrating it must have been to try to upgrade from
1.8, ~5 years is so much time! Indeed, the changes from 1.8 to 2 must be
very deep...
Thank you for taking the time to explain that, I found it very interesting.


@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.

2018-03-08 20:26 GMT-03:00 Thomas Morley :

> 2018-03-08 23:46 GMT+01:00 Stefano Troncaro :
>
> > @David, Harm
> > I didn't know 1.8 was not maintained anymore. I imagine we're still
> using it
> > because updating it would take a lot of work (and create instability) and
> > dev time is better placed elsewhere, or something among those lines, am I
> > right?
>
> Well, guilev2 is deeply different from guilev1 in many ways.
> David K may say more about the details or look into the archives.
> After guille-2.0 was released we were not able to build LilyPond with
> guilev2 for 5(?) years !
>
> I'm now can build LilyPond from the git-repository with guile-2.2.3 in
> a local branch.
> Though, I need to apply several patches mostly from David K and
> Antonio Ospite and I need to disable some functionality, which I don't
> know to fix.
> My kowledge of C++ is more or less zero...
>
>
> From a users point of view the biggest disadvantage is the speed of
> lilypond.
> I think guile-2.0.12 was the first guile-version which could be made
> work for us. Lilypond speed was down to a _factor_ of 5-10, iirc
> Admittedly things improved during further guile-development.
>
> I'm not sure how the values are nowadays, I should redo testings...
>
> For the programmers David may want to chime in.
> I'd like to mention only to major points:
> - Encoding problems
> - We have no infrastructure for precompiled .go-files.
>
> Both or mostly beyond my knowledge :(
>
> > Also, Harm, is that guilev2-lilypond that you named v2.21.0 a
> > personal thing or is it something that is coming after the stable 2.20
> > release is done?
>
> I compile lilypond from the repository. Doing it from master will
> result in 2.21.0.
> The branch stable/2.20 is meant to become the next stable release.
> Current devel-versions are compiled from this branch iirc.
>
> Best,
>   Harm
>
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-03-08 Thread Thomas Morley
2018-03-08 23:46 GMT+01:00 Stefano Troncaro :

> @David, Harm
> I didn't know 1.8 was not maintained anymore. I imagine we're still using it
> because updating it would take a lot of work (and create instability) and
> dev time is better placed elsewhere, or something among those lines, am I
> right?

Well, guilev2 is deeply different from guilev1 in many ways.
David K may say more about the details or look into the archives.
After guille-2.0 was released we were not able to build LilyPond with
guilev2 for 5(?) years !

I'm now can build LilyPond from the git-repository with guile-2.2.3 in
a local branch.
Though, I need to apply several patches mostly from David K and
Antonio Ospite and I need to disable some functionality, which I don't
know to fix.
My kowledge of C++ is more or less zero...


>From a users point of view the biggest disadvantage is the speed of lilypond.
I think guile-2.0.12 was the first guile-version which could be made
work for us. Lilypond speed was down to a _factor_ of 5-10, iirc
Admittedly things improved during further guile-development.

I'm not sure how the values are nowadays, I should redo testings...

For the programmers David may want to chime in.
I'd like to mention only to major points:
- Encoding problems
- We have no infrastructure for precompiled .go-files.

Both or mostly beyond my knowledge :(

> Also, Harm, is that guilev2-lilypond that you named v2.21.0 a
> personal thing or is it something that is coming after the stable 2.20
> release is done?

I compile lilypond from the repository. Doing it from master will
result in 2.21.0.
The branch stable/2.20 is meant to become the next stable release.
Current devel-versions are compiled from this branch iirc.

Best,
  Harm

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-03-08 Thread Stefano Troncaro
@Urs
With your last update, the following syntax popped to mind:

> \version "2.19.80"
> %Functional copy of your example#(define rules
>`(strict
>   (req payload
>(target ,symbol?))
>   (opt accepted-without-type
>(accepted-arg ,fraction?)
>(ind ,number? 5)
>(msg ,string? "No message given"
> %Accepts any argument, but provides a type-check and a default for 
> msg#(define rules2
>`(flexible
>   (opt (msg ,string? "No message given"
>
> I like it because:
1) It eliminates the need for the boolean argument to context-mod->props,
and puts that information together with all the other rules, which makes
them easier to read and parse (mentally) because all the information is in
the same place. I know it's a minor thing but it's not much more typing and
it feels cleaner to me. The other way you have a 'rules object' that does
not contain the whole ruleset.
2) It eliminates unnecessary parens.
3) It eliminates the need to flag many arguments with opt.
4) Also, arguments that have default values feel optional to me, and here
they are grouped together. With this I can at first glance know what
arguments I need to give and what is optional.

It may have defects I'm not seeing. What do you think? If you like it I can
do the rework.


@David, Harm
I didn't know 1.8 was not maintained anymore. I imagine we're still using
it because updating it would take a lot of work (and create instability)
and dev time is better placed elsewhere, or something among those lines, am
I right? Also, Harm, is that guilev2-lilypond that you named v2.21.0 a
personal thing or is it something that is coming after the stable 2.20
release is done? Sorry for asking so many questions, you picked my
curiosity with your conversation.

2018-03-08 18:07 GMT-03:00 David Kastrup :

> Thomas Morley  writes:
>
> > 2018-03-08 17:29 GMT+01:00 David Kastrup :
> >> Stefano Troncaro  writes:
> >>
> >>> @David
> >>> Thank you. The define-syntax and syntax-rules thing looked easier to
> >>> understand at first glance so I tried to use that. I'll experiment with
> >>> macros then.
> >>
> >> If we want to get rid of those problems: Guile-1.8 is no longer
> >> officially maintained.  I think someone forked it for his own purposes.
> >> We might want to cooperate with him regarding some official place where
> >> one can fix those bugs.
> >
> > I've tested with my guilev2-lilypond.:
> >
> > \version "2.21.0"
> >
> > #(define-syntax test
> >(syntax-rules ()
> >  ((test conditional true false)
> >   (if conditional
> >   true
> >   false
> >
> > #(test #t (display "I'm true!\n") (display "I'm false!\n"))
> >
> > Works out of the box, no need for (use-syntax (ice-9 syncase)).
> > `use-syntax' gives an error now. Obviously it's dropped from guilev2.
>
> Sure, it's been part of Scheme standards for quite a while now.
>
> --
> David Kastrup
>
> ___
> lilypond-user mailing list
> lilypond-user@gnu.org
> https://lists.gnu.org/mailman/listinfo/lilypond-user
>
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-03-08 Thread David Kastrup
Thomas Morley  writes:

> 2018-03-08 17:29 GMT+01:00 David Kastrup :
>> Stefano Troncaro  writes:
>>
>>> @David
>>> Thank you. The define-syntax and syntax-rules thing looked easier to
>>> understand at first glance so I tried to use that. I'll experiment with
>>> macros then.
>>
>> If we want to get rid of those problems: Guile-1.8 is no longer
>> officially maintained.  I think someone forked it for his own purposes.
>> We might want to cooperate with him regarding some official place where
>> one can fix those bugs.
>
> I've tested with my guilev2-lilypond.:
>
> \version "2.21.0"
>
> #(define-syntax test
>(syntax-rules ()
>  ((test conditional true false)
>   (if conditional
>   true
>   false
>
> #(test #t (display "I'm true!\n") (display "I'm false!\n"))
>
> Works out of the box, no need for (use-syntax (ice-9 syncase)).
> `use-syntax' gives an error now. Obviously it's dropped from guilev2.

Sure, it's been part of Scheme standards for quite a while now.

-- 
David Kastrup

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-03-08 Thread Thomas Morley
2018-03-08 17:29 GMT+01:00 David Kastrup :
> Stefano Troncaro  writes:
>
>> @David
>> Thank you. The define-syntax and syntax-rules thing looked easier to
>> understand at first glance so I tried to use that. I'll experiment with
>> macros then.
>
> If we want to get rid of those problems: Guile-1.8 is no longer
> officially maintained.  I think someone forked it for his own purposes.
> We might want to cooperate with him regarding some official place where
> one can fix those bugs.

I've tested with my guilev2-lilypond.:

\version "2.21.0"

#(define-syntax test
   (syntax-rules ()
 ((test conditional true false)
  (if conditional
  true
  false

#(test #t (display "I'm true!\n") (display "I'm false!\n"))

Works out of the box, no need for (use-syntax (ice-9 syncase)).
`use-syntax' gives an error now. Obviously it's dropped from guilev2.

>
> Thi-something?  I am bad with names.

You likely refer to
https://lists.gnu.org/archive/html/guile-user/2017-03/msg00087.html
from Thien-Thi Nguyen

Cheers,
  Harm

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-03-08 Thread David Kastrup
Stefano Troncaro  writes:

> @David
> Thank you. The define-syntax and syntax-rules thing looked easier to
> understand at first glance so I tried to use that. I'll experiment with
> macros then.

If we want to get rid of those problems: Guile-1.8 is no longer
officially maintained.  I think someone forked it for his own purposes.
We might want to cooperate with him regarding some official place where
one can fix those bugs.

Thi-something?  I am bad with names.

-- 
David Kastrup

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-03-08 Thread Urs Liska



Am 08.03.2018 um 16:52 schrieb Urs Liska:

@Urs
Great! I tested it a bit and it seems to be working as intended.


I have forgotten one thing that I've only halfway completed by now: 
"accepted" properties without type checking. Currently, if the 
"strict" flag is set, only keys present in the rules are accepted. But 
these are also expected, so what's still missing is a way to specify 
rules as optional so we can filter unknown properties but still have 
optional ones. I've started on it and I think I know how to do it but 
I had to leave the computer.


I've pushed another commit to allow "accepted" but "optional" arguments.

Now with the "strict" option unknown properties are still rejected, but 
if a rule has 'opt as its last element the argument is ignored if it is 
not supplied.


This is something to test with:

\version "2.19.80"

\include "oll-core/package.ily"

#(define rules
   `((ind ,number? 5)
 (target ,symbol?)
 (payload)
 (accepted-arg ,fraction? opt)
 (accepted-without-type opt)
 (msg ,string? "No message given")))

testRules =
#(define-void-function (opts) (ly:context-mod?)
   (let ((props (context-mod->props rules #t opts)))
 (pretty-print props)))

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


Best
Urs

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-03-08 Thread Urs Liska



Am 08.03.2018 um 16:42 schrieb Stefano Troncaro:

@Urs
Great! I tested it a bit and it seems to be working as intended.


I have forgotten one thing that I've only halfway completed by now: 
"accepted" properties without type checking. Currently, if the "strict" 
flag is set, only keys present in the rules are accepted. But these are 
also expected, so what's still missing is a way to specify rules as 
optional so we can filter unknown properties but still have optional 
ones. I've started on it and I think I know how to do it but I had to 
leave the computer.




I'm curious about the "complains about the wrong type for 'target'" 
part though. I remembered that words when typed like that were 
symbols, so I did this to check it out:


\version  "2.19.80" \include  "oll-core/package.ily" #(use-modules  (oop 
goops))

obj = something

testType =
#(define-void-function  (obj) (scheme?)
(display  (format  "'~a' is of type '~a'\n"  obj (class-of obj

\testType \obj checkIfSym =
#(define-void-function  (obj) (symbol?)
(display  (format  "'~a' of type '~a' passed the symbol? test\n"  obj 
(class-of obj

\checkIfSym \obj testTypeInCM =
#(define-void-function  (cm) (ly:context-mod?)
(let  ((props (context-mod->props cm)))
  (for-each  (lambda  (prop)
  (testType (cdr  prop)))
props)))

\testTypeInCM  \with  { target =NoteHead anothertarget ="NoteHead" 
yetanothertarget = #'NoteHead
} %Gives this output: %'something' is of type '#< 
7f52818c4d40>' %'something' of type '#< 
7f52818c4c60>' passed the symbol? test %'NoteHead' is of type
'#<  7f52818c4d40>' %'NoteHead' is of type
'#<  7f52818c4d40>' %'NoteHead' is of type
'#<  7f52818c4c60>'

Also, I thought that predicates were just type checks. But in the 
second example it looks like the symbol? predicate made scheme think 
of the object as a symbol instead of a string. I find this kind of 
confusing, is there something else going on that I'm not seeing?


If I'm not mistaken completely this part may seem somewhat ambigous.
If you simply type some characters (in LilyPond) they are initially a 
string. But if you make the parser "expect" something at a given point 
it will parse it like that. if you define an argument for a 
define-something-function as symbol? then plain characters will be 
parsed as a symbol. But in the key=value parts of a \with block they are 
parsed as string.
This is something one just has to know - just like the fact that you 
have to enclose a string in quotes if it contains spaces or similar issues.


Best
Urs




@David
Thank you. The define-syntax and syntax-rules thing looked easier to 
understand at first glance so I tried to use that. I'll experiment 
with macros then.


2018-03-08 9:21 GMT-03:00 Urs Liska >:




Am 08.03.2018 um 10:35 schrieb Urs Liska:




Am 08.03.2018 um 08:44 schrieb Urs Liska:


Hi Stéfano,


Am 08.03.2018 um 07:26 schrieb Stefano Troncaro:

@Urs
I looked into your examples and \with blocks are very useful.

You said earlier that you were thinking about how to make it so
that the context-mod could have required arguments, default
values for missing ones, and even predicates. I was thinking
that context-mod->props could be made to accept this
information as an optional argument. Then it can return a
'curated' list of props or raise warnings/errors. That I think
shouldn't be difficult to do.


Great idea, thank you. Actually it's pretty much along the lines
I was already thinking about - but I hadn't thought of the
obvious of doing it directly in context-mod->props.


Although I'm undecided on what would be a convenient way of
storing the 'requirement data'. The obvious one to me is an
alist with a structure like this: `((key1 . (required . #t))
(key2 . ((default . 9) (pred . ,number?))) ...), but I'm not
sure. What do you think?



The "required" is not necessary because if a key shows up in
this list it implicltly is required. One addition I'd do is add
a keyword 'strict. When that's present any keys *not* in the
list are rejected.

#(define rules
`((key1 .;; type plus default
((type . ,number?)
 (default . 5)))
  (key2 .;; only the type
((type . ,symbol?)))
  (key3) ;; required without type or default
  (key4 .;; default value but no type
((default . #t)))
  ))

#(define rules2
(cons
 'strict
 `((key1 .
 ((type . ,number?)
  (default . 5)))
   (key2 .
 ((type . ,symbol?))
 
With rules1 the function would simply check for the presence of

the specified keys while with rules2 unknown 

Re: Having trouble understanding optional and variable amount of arguments

2018-03-08 Thread Stefano Troncaro
@Urs
Great! I tested it a bit and it seems to be working as intended.

I'm curious about the "complains about the wrong type for 'target'" part
though. I remembered that words when typed like that were symbols, so I did
this to check it out:

> \version "2.19.80"\include "oll-core/package.ily"#(use-modules (oop goops))
>
> obj = something
>
> testType =
> #(define-void-function (obj) (scheme?)
>(display (format "'~a' is of type '~a'\n" obj (class-of obj
> \testType \obj
> checkIfSym =
> #(define-void-function (obj) (symbol?)
>(display (format "'~a' of type '~a' passed the symbol? test\n" obj 
> (class-of obj
> \checkIfSym \obj
> testTypeInCM =
> #(define-void-function (cm) (ly:context-mod?)
>(let ((props (context-mod->props cm)))
>  (for-each (lambda (prop)
>  (testType (cdr prop)))
>props)))
> \testTypeInCM \with {
>   target = NoteHead
>   anothertarget = "NoteHead"
>   yetanothertarget = #'NoteHead}
> %Gives this output:
> %'something' is of type '#<  7f52818c4d40>'
> %'something' of type '#<  7f52818c4c60>' passed the symbol? 
> test
> %'NoteHead' is of type '#<  7f52818c4d40>'
> %'NoteHead' is of type '#<  7f52818c4d40>'
> %'NoteHead' is of type '#<  7f52818c4c60>'
>
> Also, I thought that predicates were just type checks. But in the second
example it looks like the symbol? predicate made scheme think of the object
as a symbol instead of a string. I find this kind of confusing, is there
something else going on that I'm not seeing?


@David
Thank you. The define-syntax and syntax-rules thing looked easier to
understand at first glance so I tried to use that. I'll experiment with
macros then.

2018-03-08 9:21 GMT-03:00 Urs Liska :

>
>
> Am 08.03.2018 um 10:35 schrieb Urs Liska:
>
>
>
> Am 08.03.2018 um 08:44 schrieb Urs Liska:
>
> Hi Stéfano,
>
> Am 08.03.2018 um 07:26 schrieb Stefano Troncaro:
>
> @Urs
> I looked into your examples and \with blocks are very useful.
>
> You said earlier that you were thinking about how to make it so that the
> context-mod could have required arguments, default values for missing ones,
> and even predicates. I was thinking that context-mod->props could be made
> to accept this information as an optional argument. Then it can return a
> 'curated' list of props or raise warnings/errors. That I think shouldn't be
> difficult to do.
>
>
> Great idea, thank you. Actually it's pretty much along the lines I was
> already thinking about - but I hadn't thought of the obvious of doing it
> directly in context-mod->props.
>
> Although I'm undecided on what would be a convenient way of storing the
> 'requirement data'. The obvious one to me is an alist with a structure like
> this: `((key1 . (required . #t)) (key2 . ((default . 9) (pred . ,number?)))
> ...), but I'm not sure. What do you think?
>
>
> The "required" is not necessary because if a key shows up in this list it
> implicltly is required. One addition I'd do is add a keyword 'strict. When
> that's present any keys *not* in the list are rejected.
>
> #(define rules
>`((key1 .;; type plus default
>((type . ,number?)
> (default . 5)))
>  (key2 .;; only the type
>((type . ,symbol?)))
>  (key3) ;; required without type or default
>  (key4 .;; default value but no type
>((default . #t)))
>  ))
>
> #(define rules2
>(cons
> 'strict
> `((key1 .
> ((type . ,number?)
>  (default . 5)))
>   (key2 .
> ((type . ,symbol?))
>
>
> With rules1 the function would simply check for the presence of the
> specified keys while with rules2 unknown keys would be rejected (issue a
> warning and be dropped)
>
> Defining the rules structures is somewhat picky - but this won't be done
> in the *user* documents but basically in packages or similar library
> structures, so it should be ok.
>
> I'll give that a shot as I can use this in a current project - but of
> course I'd also review pull requests ;-)
>
> Best
> Urs
>
>
> I have implemented the above structure as predicates for use with
> context-mod->props in
> https://github.com/openlilylib/oll-core/commit/
> 2ef019f643cbb719bdba15bd28107bb7f12124da
> (on the typed-props branch), but so far it doesn't do anything yet. But as
> you said, Stéfano, this isn't very hard to do. I just wanted to push that
> before you'd start working on it yourself.
>
> Urs
>
>
>
> OK, I've completed the code but didn't merge it to master yet.
> The interface can now be used like this:
>
> %%%
> \version "2.19.80"
>
> \include "oll-core/package.ily"
>
> #(define rules
>`((ind ,number? 5)
>  (target ,symbol?)
>  (payload)
>  (msg ,string? "No message given")))
>
> testRules =
> #(define-void-function (opts) (ly:context-mod?)
>(let ((props (context-mod->props rules #t opts)))
>  (pretty-print props)))
>
> \testRules \with {
>   msg = "Something"
>   unk = "Unknown option"

Re: Having trouble understanding optional and variable amount of arguments

2018-03-08 Thread Urs Liska



Am 08.03.2018 um 10:35 schrieb Urs Liska:




Am 08.03.2018 um 08:44 schrieb Urs Liska:


Hi Stéfano,


Am 08.03.2018 um 07:26 schrieb Stefano Troncaro:

@Urs
I looked into your examples and \with blocks are very useful.

You said earlier that you were thinking about how to make it so that 
the context-mod could have required arguments, default values for 
missing ones, and even predicates. I was thinking that 
context-mod->props could be made to accept this information as an 
optional argument. Then it can return a 'curated' list of props or 
raise warnings/errors. That I think shouldn't be difficult to do.


Great idea, thank you. Actually it's pretty much along the lines I 
was already thinking about - but I hadn't thought of the obvious of 
doing it directly in context-mod->props.


Although I'm undecided on what would be a convenient way of storing 
the 'requirement data'. The obvious one to me is an alist with a 
structure like this: `((key1 . (required . #t)) (key2 . ((default . 
9) (pred . ,number?))) ...), but I'm not sure. What do you think?




The "required" is not necessary because if a key shows up in this 
list it implicltly is required. One addition I'd do is add a keyword 
'strict. When that's present any keys *not* in the list are rejected.


#(define rules
`((key1 .;; type plus default
((type . ,number?)
 (default . 5)))
  (key2 .;; only the type
((type . ,symbol?)))
  (key3) ;; required without type or default
  (key4 .;; default value but no type
((default . #t)))
  ))

#(define rules2
(cons
 'strict
 `((key1 .
 ((type . ,number?)
  (default . 5)))
   (key2 .
 ((type . ,symbol?))
 
With rules1 the function would simply check for the presence of the 
specified keys while with rules2 unknown keys would be rejected 
(issue a warning and be dropped)


Defining the rules structures is somewhat picky - but this won't be 
done in the *user* documents but basically in packages or similar 
library structures, so it should be ok.


I'll give that a shot as I can use this in a current project - but of 
course I'd also review pull requests ;-)


Best
Urs


I have implemented the above structure as predicates for use with 
context-mod->props in

https://github.com/openlilylib/oll-core/commit/2ef019f643cbb719bdba15bd28107bb7f12124da
(on the typed-props branch), but so far it doesn't do anything yet. 
But as you said, Stéfano, this isn't very hard to do. I just wanted to 
push that before you'd start working on it yourself.


Urs



OK, I've completed the code but didn't merge it to master yet.
The interface can now be used like this:

%%%
\version "2.19.80"

\include "oll-core/package.ily"

#(define rules
   `((ind ,number? 5)
 (target ,symbol?)
 (payload)
 (msg ,string? "No message given")))

testRules =
#(define-void-function (opts) (ly:context-mod?)
   (let ((props (context-mod->props rules #t opts)))
 (pretty-print props)))

\testRules \with {
  msg = "Something"
  unk = "Unknown option"
  target = something
}
%%%

This correctly assigns the 'msg' property, sets 'ind' to the default 5, 
complains about the wrong type for 'target' and the missing 'payload' 
property. The failing properties are discarded and will presumably cause 
errors further down the line, but that is the responsibility of a 
package or a document author.


Best
Urs
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-03-08 Thread Urs Liska



Am 08.03.2018 um 08:44 schrieb Urs Liska:


Hi Stéfano,


Am 08.03.2018 um 07:26 schrieb Stefano Troncaro:

@Urs
I looked into your examples and \with blocks are very useful.

You said earlier that you were thinking about how to make it so that 
the context-mod could have required arguments, default values for 
missing ones, and even predicates. I was thinking that 
context-mod->props could be made to accept this information as an 
optional argument. Then it can return a 'curated' list of props or 
raise warnings/errors. That I think shouldn't be difficult to do.


Great idea, thank you. Actually it's pretty much along the lines I was 
already thinking about - but I hadn't thought of the obvious of doing 
it directly in context-mod->props.


Although I'm undecided on what would be a convenient way of storing 
the 'requirement data'. The obvious one to me is an alist with a 
structure like this: `((key1 . (required . #t)) (key2 . ((default . 
9) (pred . ,number?))) ...), but I'm not sure. What do you think?




The "required" is not necessary because if a key shows up in this list 
it implicltly is required. One addition I'd do is add a keyword 
'strict. When that's present any keys *not* in the list are rejected.


#(define rules
`((key1 .;; type plus default
((type . ,number?)
 (default . 5)))
  (key2 .;; only the type
((type . ,symbol?)))
  (key3) ;; required without type or default
  (key4 .;; default value but no type
((default . #t)))
  ))

#(define rules2
(cons
 'strict
 `((key1 .
 ((type . ,number?)
  (default . 5)))
   (key2 .
 ((type . ,symbol?))
 
With rules1 the function would simply check for the presence of the 
specified keys while with rules2 unknown keys would be rejected (issue 
a warning and be dropped)


Defining the rules structures is somewhat picky - but this won't be 
done in the *user* documents but basically in packages or similar 
library structures, so it should be ok.


I'll give that a shot as I can use this in a current project - but of 
course I'd also review pull requests ;-)


Best
Urs


I have implemented the above structure as predicates for use with 
context-mod->props in

https://github.com/openlilylib/oll-core/commit/2ef019f643cbb719bdba15bd28107bb7f12124da
(on the typed-props branch), but so far it doesn't do anything yet. But 
as you said, Stéfano, this isn't very hard to do. I just wanted to push 
that before you'd start working on it yourself.


Urs
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-03-08 Thread David Kastrup
Stefano Troncaro  writes:

> First of all, I apologize for the delayed response, I wanted to write back
> earlier but I couldn't find the time to delve into your last suggestions.
> Thank you for the useful replies!
>
> @Harm
> I don't understand most of what the code you provided is doing, only that
> it works. It's far too advanced for me, so (unfortunately) dissecting it
> would require much more time than what I currently have. It looks
> interesting though, I hope I can study it in more detail later.
>
> I did manage to look a little bit into macros, and I have a question if you
> don't mind. This chapter of the guile documentation
> 
> explains about define-syntax and syntax-rules. They appear to work but
> generate an error message about wrong number of arguments to a music
> function. Is that module not usable in Lilypond?

Last time I looked it broke because LilyPond uses the symbol "void" as a
music function and the 1.8 implementation is broken enough that it then
evaluates it somewhere.

I am afraid you need to stick with macros.  On the plus side, their
behavior is a lot more clear since they act only when called, not
through some pattern matching.

-- 
David Kastrup

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-03-07 Thread Urs Liska

Hi Stéfano,


Am 08.03.2018 um 07:26 schrieb Stefano Troncaro:

@Urs
I looked into your examples and \with blocks are very useful.

You said earlier that you were thinking about how to make it so that 
the context-mod could have required arguments, default values for 
missing ones, and even predicates. I was thinking that 
context-mod->props could be made to accept this information as an 
optional argument. Then it can return a 'curated' list of props or 
raise warnings/errors. That I think shouldn't be difficult to do.


Great idea, thank you. Actually it's pretty much along the lines I was 
already thinking about - but I hadn't thought of the obvious of doing it 
directly in context-mod->props.


Although I'm undecided on what would be a convenient way of storing 
the 'requirement data'. The obvious one to me is an alist with a 
structure like this: `((key1 . (required . #t)) (key2 . ((default . 9) 
(pred . ,number?))) ...), but I'm not sure. What do you think?




The "required" is not necessary because if a key shows up in this list 
it implicltly is required. One addition I'd do is add a keyword 'strict. 
When that's present any keys *not* in the list are rejected.


#(define rules
   `((key1 .;; type plus default
   ((type . ,number?)
(default . 5)))
 (key2 .;; only the type
   ((type . ,symbol?)))
 (key3) ;; required without type or default
 (key4 .;; default value but no type
   ((default . #t)))
 ))

#(define rules2
   (cons
'strict
`((key1 .
((type . ,number?)
 (default . 5)))
  (key2 .
((type . ,symbol?))


With rules1 the function would simply check for the presence of the 
specified keys while with rules2 unknown keys would be rejected (issue a 
warning and be dropped)


Defining the rules structures is somewhat picky - but this won't be done 
in the *user* documents but basically in packages or similar library 
structures, so it should be ok.


I'll give that a shot as I can use this in a current project - but of 
course I'd also review pull requests ;-)


Best
Urs
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-03-07 Thread Stefano Troncaro
First of all, I apologize for the delayed response, I wanted to write back
earlier but I couldn't find the time to delve into your last suggestions.
Thank you for the useful replies!

@Harm
I don't understand most of what the code you provided is doing, only that
it works. It's far too advanced for me, so (unfortunately) dissecting it
would require much more time than what I currently have. It looks
interesting though, I hope I can study it in more detail later.

I did manage to look a little bit into macros, and I have a question if you
don't mind. This chapter of the guile documentation

explains about define-syntax and syntax-rules. They appear to work but
generate an error message about wrong number of arguments to a music
function. Is that module not usable in Lilypond?

Example that works:

> \version "2.19.80"
> #(define-macro (test conditional true false)
>`(if ,conditional
> ,true
> ,false))
>
> #(test #t (display "I'm true!\n") (display "I'm false!\n"))
>
> Example that works but creates an error, stopping the file from compiling:

> \version "2.19.80"#(use-syntax (ice-9 syncase))
>
> #(define-syntax test
>(syntax-rules ()
>  ((test conditional true false)
>   (if conditional
>   true
>   false
>
> #(test #t (display "I'm true!\n") (display "I'm false!\n"))
> %%% Creates the output:
> %{
> file.ly:5:2: error: GUILE signaled an error for the expression beginning here
> #
>  (define-syntax test
> I'm true!
> Wrong number of arguments to #>
> %}
>
>
@Urs
I looked into your examples and \with blocks are very useful.

You said earlier that you were thinking about how to make it so that the
context-mod could have required arguments, default values for missing ones,
and even predicates. I was thinking that context-mod->props could be made
to accept this information as an optional argument. Then it can return a
'curated' list of props or raise warnings/errors. That I think shouldn't be
difficult to do. Although I'm undecided on what would be a convenient way
of storing the 'requirement data'. The obvious one to me is an alist with a
structure like this: `((key1 . (required . #t)) (key2 . ((default . 9)
(pred . ,number?))) ...), but I'm not sure. What do you think?

2018-03-03 11:34 GMT-03:00 Thomas Morley :

> 2018-03-01 18:31 GMT+01:00 Stefano Troncaro :
> > I didn't know about \default or the dot/comma separated number/symbol
> lists!
> > I can see those being useful in some circumstances. I was thinking about
> > cases where an undefined amount of things different than symbols or
> numbers
> > are required, and the closest I can imagine is chaining functions to
> create
> > the illusion of a variable amount of arguments, like this:
> >>
> >> \version "2.19.80"
> >>
> >> #(define (end-list? obj)
> >>(and (list? obj)
> >> (let ((item (last obj)))
> >>   (and (symbol? item)
> >>(equal? "end" (symbol->string item))
> >>
> >> end = #(list 'end)
> >>
> >> #(define (el->curated-el el)
> >>(delete 'end el))
> >>
> >> untilEnd =
> >> #(define-void-function (proc el) (procedure? end-list?)
> >>(let ((curated-el (el->curated-el el)))
> >>  (for-each
> >>   (lambda (elem)
> >> (proc elem))
> >>   curated-el)))
> >>
> >> selfAppending =
> >> #(define-scheme-function (e-l) (end-list?)
> >>(let ((self-input (list (cons 1 2) (cons 3 4
> >>  (append self-input e-l)))
> >>
> >> selfAppendingInput =
> >> #(define-scheme-function (input e-l) (scheme? end-list?)
> >>(append (list input) e-l))
> >>
> >> \relative c'' {
> >>   c d e f
> >>   \untilEnd #pretty-print
> >> \selfAppending
> >> \selfAppendingInput #'(some useful input?)
> >> \selfAppendingInput #selfAppending
> >> \selfAppending
> >> \end
> >>   g a b c
> >> }
> >
> > This structure just happens to work for something I'm trying now but I
> can
> > see it being too narrow in general.
> >
> > @Urs, I not familiar with \with blocks, I'll take a look at the oll-core
> > code and experiment a bit with it. Maybe I'll be able to help.
> >
> > 2018-03-01 4:55 GMT-03:00 David Kastrup :
> >>
> >> Stefano Troncaro  writes:
> >>
> >> > Thank you! I see that this is not an option then. Also, I now
> understand
> >> > why I couldn't make the optional arguments work, since I always left
> >> > them
> >> > for last.
> >> >
> >> > Do you know if it is possible to have a flexible amount of optional
> >> > arguments that appear before the last mandatory one? Say, for example
> >> > (define-music-function (arg1 args music) (number? ??? ly:music?) where
> >> > arg1
> >> > and music are mandatory, and basically everything between arg1 and the
> >> > next
> >> > music expression is compacted into a list and accessed as args in the
> >> > body
> >> > 

Re: Having trouble understanding optional and variable amount of arguments

2018-03-03 Thread Thomas Morley
2018-03-01 18:31 GMT+01:00 Stefano Troncaro :
> I didn't know about \default or the dot/comma separated number/symbol lists!
> I can see those being useful in some circumstances. I was thinking about
> cases where an undefined amount of things different than symbols or numbers
> are required, and the closest I can imagine is chaining functions to create
> the illusion of a variable amount of arguments, like this:
>>
>> \version "2.19.80"
>>
>> #(define (end-list? obj)
>>(and (list? obj)
>> (let ((item (last obj)))
>>   (and (symbol? item)
>>(equal? "end" (symbol->string item))
>>
>> end = #(list 'end)
>>
>> #(define (el->curated-el el)
>>(delete 'end el))
>>
>> untilEnd =
>> #(define-void-function (proc el) (procedure? end-list?)
>>(let ((curated-el (el->curated-el el)))
>>  (for-each
>>   (lambda (elem)
>> (proc elem))
>>   curated-el)))
>>
>> selfAppending =
>> #(define-scheme-function (e-l) (end-list?)
>>(let ((self-input (list (cons 1 2) (cons 3 4
>>  (append self-input e-l)))
>>
>> selfAppendingInput =
>> #(define-scheme-function (input e-l) (scheme? end-list?)
>>(append (list input) e-l))
>>
>> \relative c'' {
>>   c d e f
>>   \untilEnd #pretty-print
>> \selfAppending
>> \selfAppendingInput #'(some useful input?)
>> \selfAppendingInput #selfAppending
>> \selfAppending
>> \end
>>   g a b c
>> }
>
> This structure just happens to work for something I'm trying now but I can
> see it being too narrow in general.
>
> @Urs, I not familiar with \with blocks, I'll take a look at the oll-core
> code and experiment a bit with it. Maybe I'll be able to help.
>
> 2018-03-01 4:55 GMT-03:00 David Kastrup :
>>
>> Stefano Troncaro  writes:
>>
>> > Thank you! I see that this is not an option then. Also, I now understand
>> > why I couldn't make the optional arguments work, since I always left
>> > them
>> > for last.
>> >
>> > Do you know if it is possible to have a flexible amount of optional
>> > arguments that appear before the last mandatory one? Say, for example
>> > (define-music-function (arg1 args music) (number? ??? ly:music?) where
>> > arg1
>> > and music are mandatory, and basically everything between arg1 and the
>> > next
>> > music expression is compacted into a list and accessed as args in the
>> > body
>> > of the function. Not with that syntax necessarily, but something that
>> > allows for that kind of usage?
>>
>> You know that a number or symbol list can be entered as a
>> comma-separated list?
>>
>> --
>> David Kastrup

Hi Stefano,

I was always fine with one optional list?-predicate (this may ofcourse
be an alist) and sorting/processing this list in the body of the
music-function.
Or things like (lambda (arg . rest) ...) in some cases or the
comma-separated list (as already mentioned).

If you really want to go for a music-function with arbitrary arguments
here some thoughts.

Beside the result has still limitations:
- the amount of possible arguments has to be specified (ofcourse you
can go for something like 20, which should really be enough (currently
5 are defined)
- all those arguments have to be of kind (not (ly:music ...)), which
makes it impossible to enter a second music-argument.
- maybe more, it's not tested beyond the given examples
I expect David K will point out more weaknesses ... lol

I deleted the not matching doc-strings from define-syntax-function and
define-music-function.
Look into music-functions.scm to read them.

\version "2.19.65"

#(defmacro-public define-my-syntax-function
  (args-amount type args signature . body)
  (define (has-parser/location? arg where)
(let loop ((arg arg))
  (if (list? arg)
  (any loop arg)
  (memq arg where
  (define (currying-lambda args doc-string? body)
(if (and (pair? args)
 (pair? (car args)))
(currying-lambda (car args) doc-string?
 `((lambda ,(cdr args) ,@body)))
(let* ((compatibility? (if (list? args)
   (= (length args) (+ 2 (length signature)))
   (and (pair? args) (pair? (cdr args))
(eq? (car args) 'parser
   (realargs (if compatibility? (cddr args) args)))
  `(lambda ,realargs
 ,(format #f "~a\n~a" realargs (or doc-string? ""))
 ,@(if (and compatibility?
(has-parser/location? body (take args 2)))
   `((let ((,(car args) (*parser*)) (,(cadr args) (*location*)))
   ,@body))
   body)

  (let ((docstring
 (and (pair? body) (pair? (cdr body))
  (if (string? (car body))
  (car body)
  (and (pair? (car body))
   (eq? '_i (caar body))
   (pair? (cdar 

Re: Having trouble understanding optional and variable amount of arguments

2018-03-01 Thread Urs Liska



Am 01.03.2018 um 18:31 schrieb Stefano Troncaro:

...

@Urs, I not familiar with \with blocks, I'll take a look at the 
oll-core code and experiment a bit with it. Maybe I'll be able to help.



Look at 
https://github.com/openlilylib/scholarly/blob/master/usage-examples/annotate.ly 
to see an example for the syntax.
Actually this does what you want: an unlimited number of optional 
arguments.


%%%
\version "2.19.80"

#(define (context-mod->props mod)
   (map
    (lambda (prop)
  (cons (cadr prop) (caddr prop)))
    (ly:get-context-mods mod)))

myVariableFunc =
#(define-void-function (opts mus)((ly:context-mod? #f) ly:music?)
   (let ((props
  (if opts
  (context-mod->props opts)
  '(
 (for-each (lambda (prop)
 (ly:message "Option '~a': '~a'" (car prop) (cdr prop)))
   props)
 mus))

\relative {
  c' d e f
  \myVariableFunc \with {
    first = "Hello"
    second = 124
    third = #'((a . red)(b . blue))
    fourth = #(ly:version)
    fifth = #display
  } g1
}
 %%%

Note that instead of defining context-mod->props you could include 
"oll-core/package.ily" (or rather: if you have included anything from 
OLL you can simply use that procedure.


HTH
Urs
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-03-01 Thread Urs Liska



Am 01.03.2018 um 18:31 schrieb Stefano Troncaro:

...

@Urs, I not familiar with \with blocks, I'll take a look at the 
oll-core code and experiment a bit with it. Maybe I'll be able to help.



Look at 
https://github.com/openlilylib/scholarly/blob/master/usage-examples/annotate.ly 
to see an example for the syntax.
Actually this does what you want: an unlimited number of optional 
arguments.


%%%
\version "2.19.80"

\include "oll-core/package.ily"

myVariableFunc =
#(define-void-function (opts mus)((ly:context-mod? #f) ly:music?)
   (let ((props
  (if opts
  (context-mod->props opts)
  '(
 (for-each (lambda (prop)
 (ly:message "Option '~a': '~a'" (car prop) (cdr prop)))
   props)
 mus))

\relative {
  c' d e f
  \myVariableFunc \with {
    first = "Hello"
    second = 124
    third = #'((a . red)(b . blue))
    fourth = #(ly:version)
    fifth = #display
  } g1
}
 %%%
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-03-01 Thread Stefano Troncaro
I didn't know about \default or the dot/comma separated number/symbol
lists! I can see those being useful in some circumstances. I was thinking
about cases where an undefined amount of things different than symbols or
numbers are required, and the closest I can imagine is chaining functions
to create the illusion of a variable amount of arguments, like this:

> \version "2.19.80"
> #(define (end-list? obj)
>(and (list? obj)
> (let ((item (last obj)))
>   (and (symbol? item)
>(equal? "end" (symbol->string item))
>
> end = #(list 'end)
>
> #(define (el->curated-el el)
>(delete 'end el))
>
> untilEnd =
> #(define-void-function (proc el) (procedure? end-list?)
>(let ((curated-el (el->curated-el el)))
>  (for-each
>   (lambda (elem)
> (proc elem))
>   curated-el)))
>
> selfAppending =
> #(define-scheme-function (e-l) (end-list?)
>(let ((self-input (list (cons 1 2) (cons 3 4
>  (append self-input e-l)))
>
> selfAppendingInput =
> #(define-scheme-function (input e-l) (scheme? end-list?)
>(append (list input) e-l))
> \relative c'' {
>   c d e f
>   \untilEnd #pretty-print
> \selfAppending
> \selfAppendingInput #'(some useful input?)
> \selfAppendingInput #selfAppending
> \selfAppending
> \end
>   g a b c}
>
> This structure just happens to work for something I'm trying now but I can
see it being too narrow in general.

@Urs, I not familiar with \with blocks, I'll take a look at the oll-core
code and experiment a bit with it. Maybe I'll be able to help.

2018-03-01 4:55 GMT-03:00 David Kastrup :

> Stefano Troncaro  writes:
>
> > Thank you! I see that this is not an option then. Also, I now understand
> > why I couldn't make the optional arguments work, since I always left them
> > for last.
> >
> > Do you know if it is possible to have a flexible amount of optional
> > arguments that appear before the last mandatory one? Say, for example
> > (define-music-function (arg1 args music) (number? ??? ly:music?) where
> arg1
> > and music are mandatory, and basically everything between arg1 and the
> next
> > music expression is compacted into a list and accessed as args in the
> body
> > of the function. Not with that syntax necessarily, but something that
> > allows for that kind of usage?
>
> You know that a number or symbol list can be entered as a
> comma-separated list?
>
> --
> David Kastrup
>
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-02-28 Thread David Kastrup
Stefano Troncaro  writes:

> Thank you! I see that this is not an option then. Also, I now understand
> why I couldn't make the optional arguments work, since I always left them
> for last.
>
> Do you know if it is possible to have a flexible amount of optional
> arguments that appear before the last mandatory one? Say, for example
> (define-music-function (arg1 args music) (number? ??? ly:music?) where arg1
> and music are mandatory, and basically everything between arg1 and the next
> music expression is compacted into a list and accessed as args in the body
> of the function. Not with that syntax necessarily, but something that
> allows for that kind of usage?

You know that a number or symbol list can be entered as a
comma-separated list?

-- 
David Kastrup

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-02-28 Thread David Kastrup
Stefano Troncaro  writes:

> Thank you! I see that this is not an option then. Also, I now understand
> why I couldn't make the optional arguments work, since I always left them
> for last.

You can use an explicit \default to substitute optional arguments in
final position.

-- 
David Kastrup

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-02-28 Thread Urs Liska


Am 1. März 2018 03:26:31 MEZ schrieb Stefano Troncaro 
:
>Thank you! I see that this is not an option then. Also, I now
>understand
>why I couldn't make the optional arguments work, since I always left
>them
>for last.
>
>Do you know if it is possible to have a flexible amount of optional
>arguments that appear before the last mandatory one? Say, for example
>(define-music-function (arg1 args music) (number? ??? ly:music?) where
>arg1
>and music are mandatory, and basically everything between arg1 and the
>next
>music expression is compacted into a list and accessed as args in the
>body
>of the function. Not with that syntax necessarily, but something that
>allows for that kind of usage?

I *think* that's not doable in general (I'd love to be proven wrong), but if 
you can have all optional args as symbols you can use a dot-separated symbol 
list.

What I generally use is a \with {} argument which can take arbitrary named 
arguments. In oll-core there are a few helper functions for this, especially 
context-mod->props that turns the value into a regular alist.
I've just started thinking about an enhancement that
- allows to require some arguments
- can set missing args to defaults
- allows type checking

I'd be happy to collaborate on this.

Best
Urs
>
>2018-02-28 20:45 GMT-03:00 Simon Albrecht :
>
>> On 28.02.2018 23:54, Stefano Troncaro wrote:
>>
>>> I need a little help again. I'm struggling to understand how one
>would
>>> make a music function like \tempo, that accepts a variable number of
>>> arguments. I couldn't find its definition so I couldn't look for
>myself.
>>>
>>> So far I know about making lambdas that take additional arguments
>and
>>> store the extras in a list, but this does not work in a music
>function (or
>>> if it works I don't know how to do it). And while I could make a
>lambda
>>> that then passes the arguments to a music function, then I can't use
>it
>>> with Lilypond syntax, so I'm forced to put the lambda and all it's
>>> arguments between parenthesis.
>>>
>>> But \tempo doesn't require parenthesis, and the parser still
>understands
>>> what is part of the function and what not. How would one go about
>writing a
>>> function that behaves like this?
>>>
>>
>> As has been said, \tempo isn’t a music function. However, you _can_
>define
>> functions with optional arguments; it’s mentioned in <
>> http://lilypond.org/doc/v2.19/Documentation/extending/schem
>> e-function-definitions>. The last optional argument has to be
>followed by
>> a mandatory argument of different type, because that’s how the parser
>will
>> recognise that optional arguments were skipped.
>>
>> HTH, Simon
>>

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-02-28 Thread Stefano Troncaro
Thank you! I see that this is not an option then. Also, I now understand
why I couldn't make the optional arguments work, since I always left them
for last.

Do you know if it is possible to have a flexible amount of optional
arguments that appear before the last mandatory one? Say, for example
(define-music-function (arg1 args music) (number? ??? ly:music?) where arg1
and music are mandatory, and basically everything between arg1 and the next
music expression is compacted into a list and accessed as args in the body
of the function. Not with that syntax necessarily, but something that
allows for that kind of usage?

2018-02-28 20:45 GMT-03:00 Simon Albrecht :

> On 28.02.2018 23:54, Stefano Troncaro wrote:
>
>> I need a little help again. I'm struggling to understand how one would
>> make a music function like \tempo, that accepts a variable number of
>> arguments. I couldn't find its definition so I couldn't look for myself.
>>
>> So far I know about making lambdas that take additional arguments and
>> store the extras in a list, but this does not work in a music function (or
>> if it works I don't know how to do it). And while I could make a lambda
>> that then passes the arguments to a music function, then I can't use it
>> with Lilypond syntax, so I'm forced to put the lambda and all it's
>> arguments between parenthesis.
>>
>> But \tempo doesn't require parenthesis, and the parser still understands
>> what is part of the function and what not. How would one go about writing a
>> function that behaves like this?
>>
>
> As has been said, \tempo isn’t a music function. However, you _can_ define
> functions with optional arguments; it’s mentioned in <
> http://lilypond.org/doc/v2.19/Documentation/extending/schem
> e-function-definitions>. The last optional argument has to be followed by
> a mandatory argument of different type, because that’s how the parser will
> recognise that optional arguments were skipped.
>
> HTH, Simon
>
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-02-28 Thread Simon Albrecht

On 28.02.2018 23:54, Stefano Troncaro wrote:
I need a little help again. I'm struggling to understand how one would 
make a music function like \tempo, that accepts a variable number of 
arguments. I couldn't find its definition so I couldn't look for myself.


So far I know about making lambdas that take additional arguments and 
store the extras in a list, but this does not work in a music function 
(or if it works I don't know how to do it). And while I could make a 
lambda that then passes the arguments to a music function, then I 
can't use it with Lilypond syntax, so I'm forced to put the lambda and 
all it's arguments between parenthesis.


But \tempo doesn't require parenthesis, and the parser still 
understands what is part of the function and what not. How would one 
go about writing a function that behaves like this?


As has been said, \tempo isn’t a music function. However, you _can_ 
define functions with optional arguments; it’s mentioned in 
. 
The last optional argument has to be followed by a mandatory argument of 
different type, because that’s how the parser will recognise that 
optional arguments were skipped.


HTH, Simon

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Having trouble understanding optional and variable amount of arguments

2018-02-28 Thread Caagr98
I think \tempo (and a few other commands such as \repeat\alternative, \set, and 
\override) are hardcoded in the Lilypond compiler using methods not accessible 
through Scheme, so you can't make that kind of functions yourself. You can make 
functions with optional arguments, though. I think the syntax is something like 
(define-music-function (optional-int-defaults-to-4 music) ((int? 4) ly:music?) 
...).

On 02/28/18 23:54, Stefano Troncaro wrote:
> Hello everyone,
> 
> I need a little help again. I'm struggling to understand how one would make a 
> music function like \tempo, that accepts a variable number of arguments. I 
> couldn't find its definition so I couldn't look for myself.
> 
> So far I know about making lambdas that take additional arguments and store 
> the extras in a list, but this does not work in a music function (or if it 
> works I don't know how to do it). And while I could make a lambda that then 
> passes the arguments to a music function, then I can't use it with Lilypond 
> syntax, so I'm forced to put the lambda and all it's arguments between 
> parenthesis.
> 
> But \tempo doesn't require parenthesis, and the parser still understands what 
> is part of the function and what not. How would one go about writing a 
> function that behaves like this?
> 
> Thank you in advance for your help!
> Stéfano
> 
> 
> ___
> lilypond-user mailing list
> lilypond-user@gnu.org
> https://lists.gnu.org/mailman/listinfo/lilypond-user
> 

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Having trouble understanding optional and variable amount of arguments

2018-02-28 Thread Stefano Troncaro
Hello everyone,

I need a little help again. I'm struggling to understand how one would make
a music function like \tempo, that accepts a variable number of arguments.
I couldn't find its definition so I couldn't look for myself.

So far I know about making lambdas that take additional arguments and store
the extras in a list, but this does not work in a music function (or if it
works I don't know how to do it). And while I could make a lambda that then
passes the arguments to a music function, then I can't use it with Lilypond
syntax, so I'm forced to put the lambda and all it's arguments between
parenthesis.

But \tempo doesn't require parenthesis, and the parser still understands
what is part of the function and what not. How would one go about writing a
function that behaves like this?

Thank you in advance for your help!
Stéfano
___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user