[Top][All Lists]
[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 13:20:12 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.0.90 (gnu/linux) |
Valentin Villenave <address@hidden> writes:
> On Sun, Dec 4, 2011 at 9:38 AM, David Kastrup <address@hidden> wrote:
>> Apart from the rest of this ugly contraption,
>
> You mean, uglier than using eval-string? I'm not sure what a less ugly
> way of doing that would look like. (Perhaps using hooks, but I have
> yet to master that.)
I don't see why you would be using make-parameter at all, and why you
would be creating a parameter of type _letter_ when you actually _need_
a symbol. Then write a macro around it that needs to do some partial
evaluation using primitive-eval in order to evaluate one half of a
construct in advance but not the other and you already have one added
layer of diddling with evaluation order using macros...
>> there is no reason whatsoever why you are calling the _internals_ of
>> making music functions here instead of define-music-function itself.
>
> Absolutely none whatsoever. That was pure uncalled-for geekness from
> me (at the time, it also allowed me to learn more about the
> music-function internals).
I protest in the name of geeks against this characterization.
> It isn't. defmacro certainly is a cleaner way to do it. That was just
> to show you an example of a case where eval-string was useful to me,
> re. our previous conversation.
But it doesn't do anything you could not have done exactly the same with
the old code without any difference in the bag of tricks otherwise.
I don't get it. It's like you want to put a nail into a wall, and miss
with a hammer, so you take a shoe and complain to the producer of the
hammer that the nails are really hard to drive using a shoe.
>
>> Or put differently: the principal difference of # and $ is that $
>> interprets the resulting expression and generates a token corresponding
>> to its type (or in this particular case, none at all). The premature
>> evaluation is a _side-effect_ of this difference.
>
> Thanks. I think I get it now. I was confused between the _LilyPond_
> parser and the guile interpreter; when you said $(...) expressions
> were evaluated instantly I misunderstood and thought you were
> referring to the former.
They are evaluated in the lexer. In contrast, # is _read_ in the lexer
and evaluated in the parser.
Or, to quote from the manual "Input variables and Scheme":
traLaLa = { c'4 d'4 }
#(define newLa (map ly:music-deep-copy
(list traLaLa traLaLa)))
#(define twice
(make-sequential-music newLa))
{ \twice }
This is actually a rather interesting example. The assignment will
only take place after the parser has ascertained that nothing akin to
`\addlyrics' follows, so it needs to check what comes next. It reads
`#' and the following Scheme expression _without_ evaluating it, so it
can go ahead with the assignment, and _afterwards_ execute the Scheme
code without problem.
The above example shows how to `export' music expressions from the
input to the Scheme interpreter. The opposite is also possible. By
placing it after `$', a Scheme value is interpreted as if it were
entered in LilyPond syntax. Instead of defining `\twice', the example
above could also have been written as
...
{ $(make-sequential-music (list newLa)) }
You can use `$' with a Scheme expression anywhere you could use
`\NAME' after having assigned the Scheme expression to a variable NAME.
This replacement happens in the `Lexer', so Lilypond is not even aware
of the difference.
One drawback, however, is that of timing. If we had been using `$'
instead of `#' for defining `newLa' in the above example, the Lexer
would have evaluated the Scheme code right away in order to figure out
the kind of the next token before Lilypond would have had a chance for
executing the assignment. Consequently, the Scheme definition would
have failed because `traLaLa' would not yet have been defined. As a
rule, using `#' rather than `$' whenever it is allowed will cause fewer
surprises.
>> If would appear that you consider the side-effect more important than
>> the main effect, and have for that reason decided to be smarter than
>> convert-ly and replace # everywhere with $.
>
> Well, you have to take into account where we come from: I'm not used
> to convert-ly being smarter than me :-)
It certainly isn't. But it may have better teachers at times.
>> Looks like we have lots of fun ahead. Do me a favor and from time to
>> time add material to Lilypond's documentation that would have helped
>> you avoid this kind of lock-in hack programming. Once you know how
>> to avoid it.
>
> That's the whole point of our conversation so far: I've already
> identified two eligible regtests (the ly:parser-include-string thing
> and the eval-string thing).
Uhm, "avoid this kind of lock-in hack programming", not support it
better. The regtests are for features that should not stop working
without good reason. This includes ly:parser-include-string and
eval-string. But that does not imply that what you use them for is a
good idea.
> On a totally unrelated note (since we're talking about Scheme
> evaluation), if I may quote a question that I discussed privately with
> Neil last year:
>
> On Mon, Dec 6, 2010 at 6:31 PM, Neil Puttock <address@hidden> wrote:
>> This caught my eye:
>> http://git.savannah.gnu.org/cgit/opus-libre.git/commit/?id=f149327afc41d869e34c29cf32b415254542ca9e
>>
>> (define bar '(hello))
>> (define foo (if (pair? bar) (display "Hello World!")))
>>
>> This reminds me of the problem we have with identifiers: how can we
>> document them automatically? A really ineffecient method would be to
>> keep an alist handy with (key . docstring) pairs, but I think the only
>> way around this would be to extend the use of \description (though
>> this would require all identifiers to be sequential blocks, e.g.,
>>
>> hideNotes =
>> {
>> \description "..."
>> ...
>> }
describeMusic =
#(define-music-function (parser location description music) (string? ly:music?)
(set! (ly:music-property music 'description) description)
music)
hideNotes =
\describeMusic "This hides notes"
{
...
}
--
David Kastrup
- Re: New read/eval Scheme syntax inconsistent in handling existing code, (continued)
- Re: New read/eval Scheme syntax inconsistent in handling existing code, David Kastrup, 2011/12/01
- Re: New read/eval Scheme syntax inconsistent in handling existing code, Valentin Villenave, 2011/12/02
- Re: New read/eval Scheme syntax inconsistent in handling existing code, David Kastrup, 2011/12/02
- Re: New read/eval Scheme syntax inconsistent in handling existing code, Valentin Villenave, 2011/12/02
- Re: New read/eval Scheme syntax inconsistent in handling existing code, David Kastrup, 2011/12/02
- Re: New read/eval Scheme syntax inconsistent in handling existing code, Valentin Villenave, 2011/12/03
- Re: New read/eval Scheme syntax inconsistent in handling existing code, David Kastrup, 2011/12/04
- Re: New read/eval Scheme syntax inconsistent in handling existing code, David Kastrup, 2011/12/04
- Re: New read/eval Scheme syntax inconsistent in handling existing code, David Kastrup, 2011/12/04
- Re: New read/eval Scheme syntax inconsistent in handling existing code, Valentin Villenave, 2011/12/04
- Re: New read/eval Scheme syntax inconsistent in handling existing code,
David Kastrup <=
- Re: New read/eval Scheme syntax inconsistent in handling existing code, Valentin Villenave, 2011/12/04
- Re: New read/eval Scheme syntax inconsistent in handling existing code, David Kastrup, 2011/12/04
- Re: New read/eval Scheme syntax inconsistent in handling existing code, David Kastrup, 2011/12/04
- Re: New read/eval Scheme syntax inconsistent in handling existing code, David Kastrup, 2011/12/04
- Re: New read/eval Scheme syntax inconsistent in handling existing code, Valentin Villenave, 2011/12/04
- Re: New read/eval Scheme syntax inconsistent in handling existing code, David Kastrup, 2011/12/05