[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: define-void-function
From: |
Freeman Gilmore |
Subject: |
Re: define-void-function |
Date: |
Fri, 8 May 2020 00:42:30 -0400 |
On Thu, May 7, 2020 at 11:32 PM Aaron Hill <address@hidden> 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
>