simple scheme in lilypond

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

simple scheme in lilypond

Gianmaria Lari
Probably these are very trivial things. Sorry to ask them but would like to understand.

If I write (1):

\version "2.19.82"
$(object->string (+ 3 2))

Lilypond is happy and compile to a pdf file showing "5".

Even this simpler code works... (2)

\version "2.19.82"
$"Hello"

and generate a pdf file showing "Hello".

It is clear to me that $ introduce a scheme expression that is evaluated. And in the previous two examples the scheme code is evaluated to strings. But I don't understand why lilypond outputs them. If I write (3):

\version "2.19.82"  
"Test"

this does not compile. So I would think that the "correct" code to output evaluated expression in the pdf file should be (4)

\version "2.19.82"
\markup $(object->string (+ 3 2))

or this (5)

\version "2.19.82"
\markup $"Hello"

Why the behaviour of (1) and (2) ?

* * *

I tried to rewrite (1) and (2) with the hash mark instead of dollar (6):

\version "2.19.82"
#(object->string (+ 3 2))

and (7):

\version "2.19.82"
#"Hello"

This time, there is no output in the pdf file. Why this difference?

Thank you, g.

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: simple scheme in lilypond

Jan-Peter Voigt
Hello,

the $ sign has a special meaning of "instant scheme-expression". An
instant scheme expression is evaluated instantly *and* the result is
observed so that lilypond can decide what to do with it. When lily
receives something that can be treated as a markup from an instant
scheme expression it is handled like \markup {}. But a pure string is
not a core lily-expression like music or markup. Thats the reason (3)
fails with an error. The result of a plain scheme-exression introduced
with # is simply ignored in root context.

HTH
Jan-Peter


Am 27.11.18 um 09:14 schrieb Gianmaria Lari:

> Probably these are very trivial things. Sorry to ask them but would like
> to understand.
>
> If I write (1):
>
>
>     \version "2.19.82"
>     $(object->string (+ 3 2))
>
>
> Lilypond is happy and compile to a pdf file showing "5".
>
> Even this simpler code works... (2)
>
>     \version "2.19.82"
>     $"Hello"
>
>
> and generate a pdf file showing "Hello".
>
> It is clear to me that $ introduce a scheme expression that is
> evaluated. And in the previous two examples the scheme code is evaluated
> to strings. But I don't understand why lilypond outputs them. If I write
> (3):
>
>     \version "2.19.82"  
>     "Test"
>
>
> this does not compile. So I would think that the "correct" code to
> output evaluated expression in the pdf file should be (4)
>
>
>     \version "2.19.82"
>     \markup $(object->string (+ 3 2))
>
>
> or this (5)
>
>     \version "2.19.82"
>     \markup $"Hello"
>
>
> Why the behaviour of (1) and (2) ?
>
> * * *
>
> I tried to rewrite (1) and (2) with the hash mark instead of dollar (6):
>
>     \version "2.19.82"
>     #(object->string (+ 3 2))
>
>
> and (7):
>
>     \version "2.19.82"
>     #"Hello"
>
>
> This time, there is no output in the pdf file. Why this difference?
>
> Thank you, g.
>
> _______________________________________________
> lilypond-user mailing list
> [hidden email]
> https://lists.gnu.org/mailman/listinfo/lilypond-user
>


_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: simple scheme in lilypond

David Kastrup
In reply to this post by Gianmaria Lari
Gianmaria Lari <[hidden email]> writes:

> Probably these are very trivial things. Sorry to ask them but would like to
> understand.
>
> If I write (1):
>
>
> \version "2.19.82"
> $(object->string (+ 3 2))
>
>
> Lilypond is happy and compile to a pdf file showing "5".
>
> Even this simpler code works... (2)
>
> \version "2.19.82"
> $"Hello"
>
>
> and generate a pdf file showing "Hello".
>
> It is clear to me that $ introduce a scheme expression that is evaluated.
> And in the previous two examples the scheme code is evaluated to strings.
> But I don't understand why lilypond outputs them. If I write (3):
>
> \version "2.19.82"
> "Test"

blabla = "Test"
##f
\blabla

will compile again (sorry for the ##f : it is necessary to defeat
lookahead).  It is indistinguishable from

blabla = \markup "Test"
##f
\blabla

in output and in its effect on the variable.  Basically, $x and \x are
the same (apart from the characters allowed in and after x).  The
logical thing would be to permit "Test" on its own but it appears rather
error-prone.  This is similar to

blabla = c4
##f
\blabla

compiling and producing a result while

c4

on its own doesn't.

> I tried to rewrite (1) and (2) with the hash mark instead of dollar (6):
>
> \version "2.19.82"
> #(object->string (+ 3 2))
>
>
> and (7):
>
> \version "2.19.82"
> #"Hello"
>
>
> This time, there is no output in the pdf file. Why this difference?

At the top level of the file, assignments and assignment-like statements
may be executed.  The return value of an assignment in Scheme is
unspecified.  There are things like

#(set! (hashq-ref x y) z)

that somewhat inscrutably return an actual value other than
*unspecified*.  For that reason, # expressions in contexts where
assignments are allowed are evaluated and ignored.  Use $ if you want
them to be heeded.

--
David Kastrup

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: simple scheme in lilypond

Gianmaria Lari
In reply to this post by Jan-Peter Voigt
Thank you Jan, very clear.
g.

On Tue, 27 Nov 2018 at 11:48, Jan-Peter Voigt <[hidden email]> wrote:
Hello,

the $ sign has a special meaning of "instant scheme-expression". An
instant scheme expression is evaluated instantly *and* the result is
observed so that lilypond can decide what to do with it. When lily
receives something that can be treated as a markup from an instant
scheme expression it is handled like \markup {}. But a pure string is
not a core lily-expression like music or markup. Thats the reason (3)
fails with an error. The result of a plain scheme-exression introduced
with # is simply ignored in root context.

HTH
Jan-Peter


Am 27.11.18 um 09:14 schrieb Gianmaria Lari:
> Probably these are very trivial things. Sorry to ask them but would like
> to understand.
>
> If I write (1):
>
>
>     \version "2.19.82"
>     $(object->string (+ 3 2))
>
>
> Lilypond is happy and compile to a pdf file showing "5".
>
> Even this simpler code works... (2)
>
>     \version "2.19.82"
>     $"Hello"
>
>
> and generate a pdf file showing "Hello".
>
> It is clear to me that $ introduce a scheme expression that is
> evaluated. And in the previous two examples the scheme code is evaluated
> to strings. But I don't understand why lilypond outputs them. If I write
> (3):
>
>     \version "2.19.82"  
>     "Test"
>
>
> this does not compile. So I would think that the "correct" code to
> output evaluated expression in the pdf file should be (4)
>
>
>     \version "2.19.82"
>     \markup $(object->string (+ 3 2))
>
>
> or this (5)
>
>     \version "2.19.82"
>     \markup $"Hello"
>
>
> Why the behaviour of (1) and (2) ?
>
> * * *
>
> I tried to rewrite (1) and (2) with the hash mark instead of dollar (6):
>
>     \version "2.19.82"
>     #(object->string (+ 3 2))
>
>
> and (7):
>
>     \version "2.19.82"
>     #"Hello"
>
>
> This time, there is no output in the pdf file. Why this difference?
>
> Thank you, g.
>
> _______________________________________________
> lilypond-user mailing list
> [hidden email]
> https://lists.gnu.org/mailman/listinfo/lilypond-user
>


_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: simple scheme in lilypond

Gianmaria Lari
In reply to this post by David Kastrup


On Tue, 27 Nov 2018 at 12:12, David Kastrup <[hidden email]> wrote:
Gianmaria Lari <[hidden email]> writes:

> Probably these are very trivial things. Sorry to ask them but would like to
> understand.
>
> If I write (1):
>
>
> \version "2.19.82"
> $(object->string (+ 3 2))
>
>
> Lilypond is happy and compile to a pdf file showing "5".
>
> Even this simpler code works... (2)
>
> \version "2.19.82"
> $"Hello"
>
>
> and generate a pdf file showing "Hello".
>
> It is clear to me that $ introduce a scheme expression that is evaluated.
> And in the previous two examples the scheme code is evaluated to strings.
> But I don't understand why lilypond outputs them. If I write (3):
>
> \version "2.19.82"
> "Test"

blabla = "Test"
##f
\blabla

will compile again (sorry for the ##f : it is necessary to defeat
lookahead).  It is indistinguishable from

blabla = \markup "Test"
##f
\blabla

in output and in its effect on the variable.  Basically, $x and \x are
the same (apart from the characters allowed in and after x).  The
logical thing would be to permit "Test" on its own but it appears rather
error-prone.

"... but it appears rather error prone" then lilypond forbid it. Is that right?
Wouldn't be better just a warning like when you make an assignment inside a conditional statement?

Thank you, g. 

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: simple scheme in lilypond

David Kastrup
Gianmaria Lari <[hidden email]> writes:

> On Tue, 27 Nov 2018 at 12:12, David Kastrup <[hidden email]> wrote:
>>
>> in output and in its effect on the variable.  Basically, $x and \x are
>> the same (apart from the characters allowed in and after x).  The
>> logical thing would be to permit "Test" on its own but it appears rather
>> error-prone.
>
>
> "... but it appears rather error prone" then lilypond forbid it. Is that
> right?
> Wouldn't be better just a warning like when you make an assignment inside a
> conditional statement?

C++ has been designed to be readable to the computer, LilyPond has been
designed to be readable to the user.  A standard compliant compiler is
not allowed to throw errors for things permitted by the standard even if
they are a bad idea.  If there is no conceivable reason to be writing
things in an unreadable manner, LilyPond not rarely makes the choice
just not to permit them.  For example, what do we gain when we allow

   c4 d e c g g c1

to be valid input creating 7 single-note scores one after another?
Consistency, because you can do the same by passing each note through a
music variable.  But if the user actually meant what he stated here, it
would have been easy to explicitly write something like

   { c4 } { d } { e } { c } { g } { g } { c1 }

Now with regard to quoted strings, they can also be used for creating
identifiers.  I can write

"Test" = 7

and that is not supposed to typeset "Test" but assign to a variable
called "Test".

It does not particularly help that something like cis=4 is valid note
input (a quarter note with an octave check to the small octave).  Giving
"Test" specific meaning when not followed by = requires lookahead.
Lookahead always is good for trouble.  We may already have it here for
unrelated reasons: not sure.  Either way, when the compiler requires
lookahead to figure out things, so does the human reader.  The language
becomes harder to understand.

Now where "Test" is supposed to be interpreted as a string, it would
seem surprising that #"Test" in the same location would be ignored and I
already explained the rationale for ignoring #-expressions in places
where assignments are allowed.

Basically you are asking to open a can of worms here not because you
actually want a worm but because you consider closed cans offensive.

In this case, if you go to lily/parser.yy and add the production
STRING | to the front of the definition of toplevel_expression (you'd
also need to add an action, namely the relevant part of the preexisting
action for embedded_scm_active), you can then do

bison -rall -g lily/parser.yy

and check the warnings and log files for conflicts (in this case
actually none).  That often is enough to see why a particular proposal
is a bad idea even if it does indeed not trigger on this particular one.

So when messing with syntax in areas that are already pretty full always
triggers the "what is this actually good for?" question and I haven't
seen an answer so far that would convince me we are doing anybody much
of a favor by filling this in the manner you want.

--
David Kastrup

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user