lilypond-user
[Top][All Lists]
Advanced

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

Re: Scheme function question


From: Thomas Morley
Subject: Re: Scheme function question
Date: Sat, 23 Nov 2013 02:21:05 +0100

2013/11/22 David Kastrup <address@hidden>:

> #(defmacro-public make-relative (variables reference music)
>   "The list of pitch or music variables in @var{variables} is used as
> a sequence for creating relativable music from @var{music}.
>
> When the constructed music is used outside of @code{\\relative}, it
> just reflects plugging in the @var{variables} into @var{music}.
>
> The action inside of @code{\\relative}, however, is determined by
> first relativizing the surrogate @var{reference} with the variables
> plugged in and then using the variables relativized as a side effect
> of relativizing @var{reference} for evaluating @var{music}.
>
> Since pitches don't have the object identity required for tracing the
> effect of the reference call, they are replaced @emph{only} for the
> purpose of evaluating @var{reference} with simple pitched note events.
>
> The surrogate @var{reference} expression has to be written with that
> in mind.  In addition, it must @emph{not} contain @emph{copies} of
> music that is supposed to be relativized but rather the
> @emph{originals}.  This @emph{includes} the pitch expressions.  As a
> rule, inside of @address@hidden@address@hidden variables must @emph{only} be
> introduced using @code{#}, never via the copying construct @code{$}.
> The reference expression will usually just be a sequential or chord
> expression naming all variables in sequence, implying that following
> music will be relativized according to the resulting pitch of the last
> or first variable, respectively.
>
> Since the usual purpose is to create more complex music from general
> arguments and since music expression parts must not occur more than
> once, one @emph{does} generally need to use copying operators in the
> @emph{replacement} expression @var{music} when using an argument more
> than once there.  Using an argument more than once in @var{reference},
> in contrast, does not make sense.
> "
>
>   ;; pitch and music generator might be stored instead in music
>   ;; properties, and it might make sense to create a music type of its
>   ;; own for this kind of construct rather than using
>   ;; RelativeOctaveMusic
>   (define ((make-relative::to-relative-callback variables music-call ref-call)
>            music pitch)
>     (let* ((ref-vars (map (lambda (v)
>                             (if (ly:pitch? v)
>                                 (make-music 'NoteEvent 'pitch v)
>                                 v))
>                           variables))

I didn't try it, though, two closing parens missing, c/p-error?
>            (after-pitch (ly:make-music-relative! (apply ref-call ref-vars) 
> pitch
>            (actual-vars (map (lambda (v r)
>                                (if (ly:pitch? v)
>                                    (ly:music-property r 'pitch)
>                                    v))
>                              variables ref-vars))
>            (rel-music (apply music-call actual-vars)))
>       (set! (ly:music-property music 'element) rel-music)
>       after-pitch))
>   `(make-music 'RelativeOctaveMusic
>                'to-relative-callback
>                (,make-relative::to-relative-callback
>                 (list ,@variables)
>                 (lambda ,variables ,music)
>                 (lambda ,variables ,reference))
>                'element ,music))

Cheers,
  Harm



reply via email to

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