lilypond-devel
[Top][All Lists]
Advanced

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

Re: lily in scheme


From: David Brandon
Subject: Re: lily in scheme
Date: Fri, 30 Apr 2004 23:01:15 -0400

Well, first I'd say to not take anything I say too seriously. I am new to this project and I definitely don't know everything there is to know about the code by any means. In fact, I don't know much, yet.

What I'm thinking about, I guess, is that for developers the mixing of scheme and lily is no problem, and very powerful, but I wonder about the typical user, if there is such a thing.

Part of my problem is that I didn't understand what you were doing the first time I read it, because I wasn't paying attention, but I was partially reacting to this example:

%%%%%%%%%%% with-props.ly %%%%%%%%%%%%%%
#(use-modules (scm lily-in-scm)
              (srfi srfi-1))

#(define (override->revert override-expr)
  "Return a \\revert music expression for `override-expr', or
#f if it's not an override music expression."
  (if (ly:music? override-expr)
      (let* ((override (ly:music-property override-expr 'element))
             (context (ly:music-property override-expr 'context-type))
             (property (ly:music-property override 'grob-property))
             (layout (ly:music-property override 'symbol)))
        (if (and (ly:music? override) context property layout)
            #{ \revert $context . $layout #'$property #}
            #f))
      #f))

#(define (overrides->reverts music)
  "Return a sequential music expression with reverts for
each override found in music, which is supposed to be a music
expression"
  (make-music 'SequentialMusic
'elements (filter-map override->revert (ly:music-property music 'elements))))

#(define (with-props props)
   (lambda (music)
     (set! (ly:music-property music 'elements)
           (append (ly:music-property props 'elements)
                   (ly:music-property music 'elements)
(ly:music-property (overrides->reverts props) 'elements)))
     music))

foo = \notes { c'8( d') e'( f') g'4( a') }

\score {
    \notes {
        \foo
        \apply #(with-props #{
                 \override Stem #'thickness = #4
                 \override Slur #'transparent = ##t #}) { \foo }
        \foo
    }
}
%%%%%%%%%%% with-props.ly %%%%%%%%%%%%%%

The worry I have here, is the mixing of scheme and lily. The problem is not that extensions are defined in scheme. It's that, first, scheme and lily are mixed together haphazardly (not such a big deal, I guess) and second, that when the extensions are used in lily, they are still scheme-y (more important, IMHO). This is what I'd like to see:

foo = \notes { c'8( d') e'( f') g'4( a') }

\score {
    \notes {
        \foo
        {
            \override Stem.thickness = 4
            \override Slur.transparent = true
            \foo
        }
        \foo
    }
}

Actually, what I'd really like to see is

\score {
    \notes {
        \foo
        {
          Stem.thickness = 4
          Slur.transparent = true
          \foo
        }
        \foo
    }
}

Do you see what I mean? I think scheme should be scheme, and lily should be lily. For example, in a score I'm currently working on, I have

example 1:

#(set-accidental-style 'modern-cautionary)

example 2:

\set Score.markFormatter = #(lambda (mark context) (make-bold-markup (make-box-markup (number->string mark))))

These are both examples out of the Lilypond manual. For a non-programmer, the second example, in particular, is probably completely baffling.

For example 1, why not

\accidental-style = modern-cautionary

or perhaps

\accidental-style = "modern-cautionary"

For example 2:

This is trickier. However, I think a nice way to do it would be to have a separate file named, perhaps, rehersal-marks.scm. In this file, you could define the markFormatter as, say, "box-format" using guile, and then in the lilypond file, use

% import language extensions written in guile
\import "rehersal-marks.scm"

% use the newly defined extension
\set Score.markFormatter = \box-format

Sure, you could put the scheme in a file and just \include it, but the use would still be scheme-y.

The general idea, is that one writes extension modules in scheme, and that one writes lily in lily. This will also encourage writing reusable extensions, instead of just having a bunch of scheme inlined in a .ly file.

I know that this makes things tricky with parsing, but I think that for usability for a wide audience it makes sense. Perhaps using a parser generator that produces scheme instead of C++ would simplify life.

Anyway, I don't really know what I'm talking about here. All I'm trying to do is get towards a separation of lily and scheme code which protects the casual user from what what is, IMHO, a confusing mixed syntax.

David


On Apr 30, 2004, at 5:56 PM, Nicolas Sceaux wrote:

Fri, 30 Apr 2004 14:39:46 -0400, David a dit :

I'm a little bit worried about the architectural implications of this
entire line of discussion.  I mean, lilypond syntax is already a bit
of a frankenstein monster of mixed TeX and scheme.  I think
encouraging too much embedded scheme is an approach which has the
potential to make lilypond source files unreadable.  From a language
point of view, by which I mean the lilypond language, I think it would
be cleaner to have separate scheme extension modules which define new
lilypond commands and are loaded via some kind of \import "module.scm"
or some such.

Or am I just crazy?  Does everyone else think this is the right way to
go?

There may be More Than One Way(tm) to do things.
I'm just investigating a path, which may lead nowhere.

I can't agree however with the argument: potentially
unreadable/dangerous/whatever. This feature is intended to ease the
creation of commands (by using more LilyPond syntax and less Scheme),
which in turn make your lilypond score lighter, thus more
readable.

nicolas


--
David Brandon/address@hidden
"Go back to your desk. Settle down. Focus. And catch up!" --"Bob Shelby"





reply via email to

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