On Thu, May 7, 2020 at 11:32 PM Aaron Hill <lilyp...@hillvisions.com> wrote: > > On 2020-05-07 7:22 pm, Freeman Gilmore wrote: > > Need lots of help this. Starting with this: > > > > sum = #(lambda x > > (define A (apply + x)) > > (display A)) > > > > #(sum 2 3 4 5) % 14 (from LilyPond Log) > > > > I am guessing from reading “Extending LilyPond“ the above could be maid > > into: > > > > function = > > (define-void-function > > (arg1 arg2 …) > > (type1? type2? …) > > body) > > > > This is one of my many tries: but nothing works: > > > > sum = #(define-void-function (x) > > (lambda x > > (define A (apply + x)) > > (display A))) > > > > {\sum 2 3 4} > > > There are several things going on here. > > The lambda construct supports a few patterns for specifying the formals: > > (lambda (a b c) ...) > (lambda args ...) > (lambda (x y . z) ...) > > In the first case, the lambda has fixed arity of three and will bind the > arguments to the provided names in order, first argument to left-most > name. > > In the second case, the lambda has unbounded variable arity and will > bind the arguments as a list to the provided name. > > In the third case, the lambda has variable arity requiring at least two > arguments though having no maximum. Those first two arguments will bind > to the provided names in a manner similar to the first case where all > other arguments are bound to the final name as a list as in the second > case. > > > The define-*-function family of macros support the same syntax for > defining formals, however they also require specifying the signature of > the function using a list of type predicates: > > (define-music-function (a b c) (type? type? type?) ...) > (define-scheme-function args (type? type? type? type?) ...) > (define-void-function (x y . z) (type? type? type? type? type?) ...) > > Since the list of type predicates is finite, the arity of the syntax > function is bounded. The second case above, for instance, accepts > exactly four arguments and binds them to args as a list. In a similar > manner, the third case above accepts precisely five arguments--the first > two bind to x and y respectively, whereas the rest bind to z as a list. > > Note that the signature does support optional arguments providing there > can be no confusion for other types and that the final type predicate is > non-optional. So the arity of these syntax functions can be variable, > but they will always have a minimum and maximum bound. > > > Attempting to apply this to your sum function: > > %%%% > \version "2.20.0" > > sum = > #(define-void-function > args > (number? number? number?) > (format #t "\nargs: ~s, sum: ~s" args (apply + args))) > > \sum 2 3 5 > \sum 8 13 > \sum 21 34 55 89 > %%%% > > ==== > GNU LilyPond 2.20.0 > Processing `lambda-args.ly' > Parsing... > args: (2 3 5), sum: 10 > args: (21 34 55), sum: 110 > lambda-args.ly:11:1: error: wrong type for argument 3. > Expecting number, found #<unspecified> > > \sum 21 34 55 89 > lambda-args.ly:11:15: error: syntax error, unexpected UNSIGNED > \sum 21 34 55 > 89 > fatal error: failed files: "lambda-args.ly" > ==== > > The problem here is that \sum requires no fewer than and no more than > three arguments, which is unlikely to be of much use. > > > We could make \sum more useful by accepting a list of numbers: > > %%%% > \version "2.20.0" > > sum = > #(define-void-function > (args) > (number-list?) I know the the function uses a list for this because of the undetermined number of args as the lambda procedure did. In (number-list?) how do you know what goes here, say it is not a number, like a list of similes? > (format #t "\nargs: ~s, sum: ~s" args (apply + args))) I do not have a clue what this all means "(format #t "\nargs: ~s, sum: ~s" args" Where can i find this information? > > \sum 2, 3, 5 Tried this and {a \sum2,3,5 b} (note spacing) and it worked, which is what i was looking for. But {a \sum 2, -3, 5 b} does not work? How to fix this so it does?
Thank you, ƒg > \sum 8, 13 > \sum 21, 34, 55, 89 > %%%% > > ==== > GNU LilyPond 2.20.0 > Processing `lambda-args.ly' > Parsing... > args: (2 3 5), sum: 10 > args: (8 13), sum: 21 > args: (21 34 55 89), sum: 199 > Success: compilation successfully completed > ==== > > This works because the parser knows how to look for a comma-separated > list of numbers of which can be matched by the number-list? type > predicate. But note that this list counts as a single argument, so we > need to specify the formals as (args), not args. If we omitted the > parentheses, then args would be bound to a list containing the list of > numbers. > > > -- Aaron Hill >