lilypond-devel
[Top][All Lists]
Advanced

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

Re: \apply nest-props Re: constructive criticism


From: Nicolas Sceaux
Subject: Re: \apply nest-props Re: constructive criticism
Date: Tue, 13 Jan 2004 01:37:08 +0100
User-agent: Gnus/5.1002 (Gnus v5.10.2) Emacs/21.3 (gnu/linux)

Sat, 10 Jan 2004 18:37:18 +0100, Han-Wen a dit : 

 > moving discussion to lilypond-devel
 >> > where nest-props takes care of pre- and appending the appropriate
 >> > settings.
 >> 
 >> for the record, here is a possible implementation (using lily 2.1.0):
 >> 
 >> ----------------------------------------------------
 >> #(use-modules (ice-9 optargs))
 >> 
 >> #(define-public (nthcdr n source)
 >> (do ((rest source (if (pair? rest) (cdr rest)))
 >> (i 0 (1+ i)))
 >> ((= i n) rest)))

 > Isn't this called list-tail ?

oops, yes, it seems. I missed that one.

 >> #(defmacro* make-music (name #:rest props)

 > I noticed that you have a preference for macros iso. functions is
 > there any technical merit of one over the other?  I would like to
 > include your code, but I would prefer to have a uniform style across
 > the Lilypond Scheme code (i.e. either macros or functions, not both
 > arbitrarily mixed.)  

I don't know much about scheme coding style and habits. However, in,
say, Common Lisp, it is not bad style to have both macros and
functions, as they achieve different purposes.

In my lily code, macros are often used because arguments are simply
re-arranged, not evaluated, which would happen with a function. For
instance, in the expression

  (make-music RevertProperty
              symbol 'Slur
              grob-property 'transparent)

RevertProperty, symbol, grob-property, etc, are not evaluated, they
are just used to generate an other piece of code:

  (let ((#:music1234 (make-music-by-name (quote RevertProperty)))) 
    (ly:set-mus-property! #:music1234 (quote symbol) 
                                      (quote Slur)) 
    (ly:set-mus-property! #:music1234 (quote grob-property) 
                                      (quote transparent))
    #:music1234)

It could have been done with a function, but it would have looked
like for instance: 

  (make-music-fn 'RevertProperty 
                 '((symbol . Slur)
                   (grob-property . transparent)))

which is less eleguant. You can *always* do without macros (eh, very
few languages have such a system), but they allow to build a new
syntax that captures your application specificities. (I'm not sure
about the englishness of that sentence, pardon). 

I was recently thinking about tying to fill some of the TODOs in 
scheme source files. One of them is about markup command built by
users, what they have to do, etc.

 - define a function named COMMAND-markup
 - describe its signature
 - the TODO is that it has to be defined in this new-markups.scm
 file.

Here, a macro would be fine. Something that lets you write for
instance:

(def-markup-command raise (number? markup?)
  "Syntax: \\raise AMOUNT MARKUP. "
  "Maybe a longer documentation here..."
  (lambda (paper props . rest) ;; maybe not required, as it is a
                               ;; common pattern
    (ly:molecule-translate-axis (interpret-markup paper
                                                  props
                                                  (cadr rest))
                                   (car rest) Y)))

That would generate the function definition, and add the command
signature to markup-functions-and-signatures. def-markup-command
introduces a new syntax that is specific to your application
domain, eg markups. it is imho clearer than a function where you would
have to quote all arguments. Syntax matters in LilyPond, so, when
writing scheme code for lily, adding clearer syntax thanks to macros
is a plus.

I hope I was not confusing.

nicolas





reply via email to

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