lilypond-devel
[Top][All Lists]
Advanced

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

Re: music macros?


From: Nicolas Sceaux
Subject: Re: music macros?
Date: Sat, 04 Feb 2006 13:40:33 +0100
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (darwin)

Erik Sandberg <address@hidden> writes:

> On Thursday 02 February 2006 02.35, Han-Wen Nienhuys wrote:
>> Erik Sandberg wrote:
>> > Yes, just represent those commands as music functions internally. E.g.,
>> > \transpose creates a MusicFunction expression, with a list of two pitches
>> > and one Music as its 'elements (or 'arguments, I haven't decided yet),
>> > and 'to-music-callback is set to ly:music-transpose (or rather, to a
>> > wrapper around that function).
>>
>> OK, so we create all music expressions/events as "Music promises", which
>> expand into Music objects via some function as soon as they are
>> inspected, but have \relative deal with music-promises directly?
>
> How about this: The parser spits out a big evaluatable Scheme expression, 
> which simply is eval:ed after parsing. A bit like the return value of 
> music->make-music, but with music functions & macros written as real Scheme 
> functions.
>
> The good thing about this solution, is the simplicity and the powerfulness (I 
> suppose that lots of things would be handled automatically by Scheme, perhaps 
> we will even get local variables for free). The bad thing, is that the 
> \relative macro will be rather ugly (it will need to traverse (make-music ..) 
> calls and modify pitches).

When using raw sexpr instead of music objects, you lose semantics.
Making the \relative macro deal with the sexpr:
  (make-music 'NoteEvent 'origin <location object> 'pitch <pitch object>
  ...)
instead of an actual NoteEvent object is a step backward in
expressiveness.

Wait a minute, I should not be the one argumenting against a LilyPond
code -> scheme code compiler!!

More seriously.
  \relativeMacro c'' { c \someUnaryFunction { d \someMusicVariable } }
The parser would read the macro's arguments as unexpanded music objects:

(relativeMacro
  <Unexpanded music object for "c''">
  <Unexpanded music object for the 2nd argument>)
 
Where the two unexpanded music objects looks like:

 <EventChord elements: (<NoteEvent duration: <duration 2 0 1 1>
                                   pitch: <pitch 1 0 0>)>

and:

 <SequentialMusic
   elements: (<EventChord elements: (<NoteEvent duration: <duration 2 0 1 1>
                                                pitch: <pitch -1 0 0>)>
              <MusicFunction procedure: someUnaryFunction
                arguments: (<SequentialMusic
                             elements: (<EventChord
                                          elements: (<NoteEvent duration: 
<duration 2 0 1 1>
                                                                pitch: <pitch 
-1 1 0>)>
                                        <MusicIdentifier symbol: 
'someMusicVariable>)>)>)>

Then, the relativeMacro is called and generate another unexpanded music
object (modifying octaves):

 <SequentialMusic
   elements: (<EventChord elements: (<NoteEvent duration: <duration 2 0 1 1>
                                                pitch: <pitch 1 0 0>)>
              <MusicFunction procedure: someUnaryFunction
                arguments: (<SequentialMusic
                             elements: (<EventChord
                                          elements: (<NoteEvent duration: 
<duration 2 0 1 1>
                                                                pitch: <pitch 1 
1 0>)>
                                        <MusicIdentifier symbol: 
'someMusicVariable>)>)>)>

The top-level music handler finally returns an expanded music object, by
applying music functions and replacing music identifier by their value,
using ly:parser-lookup.

I'm not sure when the #(scheme forms) found in music expressions would
be evaluated, maybe when they are read by the parser (iso when the top
level music handler expand music objects)...

nicolas




reply via email to

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