bug-lilypond
[Top][All Lists]
Advanced

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

Re: New read/eval Scheme syntax inconsistent in handling existing code


From: David Kastrup
Subject: Re: New read/eval Scheme syntax inconsistent in handling existing code
Date: Sun, 04 Dec 2011 09:38:24 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.90 (gnu/linux)

Valentin Villenave <address@hidden> writes:

> On Fri, Dec 2, 2011 at 1:59 PM, David Kastrup <address@hidden> wrote:
>> I don't see why defmacro should have ceased working, so it might be
>> worth revisiting the problems you experienced.
>
> It's not defmacro that ceased working, it's just that I previously
> used the old ly:make-music-function syntax, which you changed when
> making music-functions optargs-able:
>
> #(use-modules (srfi srfi-39))
>
> #(define-public *tuplet-letter* (make-parameter "t"))
>
> #(defmacro make-simple-function (token expr)
>   (let* ((sym (string->symbol (primitive-eval token))))
>     `(define-public ,sym
>        (ly:make-music-function (list ly:music?)
>                                (lambda (parser location x)
>                                  ,expr)))))
>
> #(make-simple-function (*tuplet-letter*) #{ \times 2/3 $x #} )
>
>
> { \t { a b c } }

Apart from the rest of this ugly contraption, there is no reason
whatsoever why you are calling the _internals_ of making music functions
here instead of define-music-function itself.

#(defmacro make-simple-function (token expr)
  (let* ((sym (string->symbol (primitive-eval token))))
    `(define-public ,sym
       (define-music-function (parser location x) (ly:music?) ,expr))))

Yes, I changed the internals because the internals needed more
information.  But the user API remained identical, and I don't
understand why you don't use it.  It's not like things get simpler when
you sidestep the documented API.

If you insist on meddling with _internals_ of Lilypond for no
discernible reason, yes, you have to expect breakage from time to time.
And there will be no convert-rules helping the upgrade.

> This is a case where eval-string can be used (I'm not suggesting it's
> proper coding practice, though -- in fact *even I* can see how ugly it
> is):
>
> #(use-modules (srfi srfi-39))
>
> #(define-public *tuplet-letter* (make-parameter "t"))
>
> #(define-public (make-simple-function token expr)
>   (eval-string (format #f
>    "(define-public ~a
>       (define-music-function (parser location x) (ly:music?) ~a ))"
>     token expr)))
>
> #(make-simple-function (*tuplet-letter*) "#{ \\times 2/3 $x #}" )
>
> { \t { a b c } }

This is ridiculous.  Now you use the API.  What makes you think
eval-string is necessary for using define-music-function?

> BTW, could you explain again why in the following example the variable
> is overriden with # but not with $? I thought $ gave us the "old"
> instant-evaluation behavior, but here it doesn't seem to be evaluated
> before the music is parsed:
>
> myvar = { b'4 }
>
> $(display "this shouldn't be needed anyway")
> $(eval-string "(define-public myvar #{ a'2 #} )" )
>
> \new Staff \myvar

You need #(display ...).  $ takes a look at the type of the enclosed
expression and creates a token of the appropriate type in the input
stream.  The type of the enclosed expression is *unspecified* so nothing
gets inserted into the input stream by the lexer and the parser is
completely unimpressed.  With #(display ..., the resulting token type is
a Scheme token.  The parser throws it away in this context, but it knows
that a Scheme token can't be between { b'4 } and \addlyrics (for
example).  So the rule it exercises for throwing the Scheme token away
makes sure that the next token is not needed as lookahead token for
finishing the previous token.

You can't write #(display ... in any context, only where Scheme tokens
are allowed.  $(display ... in contrast is allowed anywhere since the
parser never gets to see anything.  Since the parser does not get to see
anything, it does not change parsing.

-- 
David Kastrup




reply via email to

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