lilypond-devel
[Top][All Lists]
Advanced

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

Re: hash/backslash confusion


From: Carl Sorensen
Subject: Re: hash/backslash confusion
Date: Thu, 13 Aug 2009 08:39:42 -0600



On 8/13/09 12:44 AM, "Mark Polesky" <address@hidden> wrote:

> Would anyone like to take a little time to look over this
> highly confusing situation and try to explain to me why it
> is this way?
> 
> I would find it quite helpful.

Most of your confusion comes from the failure to distinguish *LilyPond*
variables from Scheme variables.

LilyPond variables must have strictly alphabetic names, because it is the
parser that is interpreting them.  Bare numbers in LilyPond are used for
durations (e.g. c4), and it greatly simplifies the parser to not allow
numbers in variable names.

Scheme variables follow Scheme naming conventions, and are therefore more
flexible.  Scheme variables are introduced by the hash character, which puts
the parser into Scheme variable parsing mode.

Now, here's the key bit of understanding that I think you're missing.  A
Scheme string is *not* a LilyPond string.  If the parser is looking for a
string, it's a LilyPond string, not a Scheme string.  As far as the parser
is concerned, all Scheme variables are the same -- bits of Scheme.  It's
guile, not the parser, that decides whether the Scheme is valid or not.

There is one more bit of understanding you need:

LilyPond variable \myVariableName is equivalent to a defined *internal*
scheme variable myVariableName.

With this as a basis, let's look at your examples.

> 
> Thanks!
> - Mark
> 
> \version "2.13.4"
> 
> % music expression variables can be defined with "=" or scheme-style,
> % but all variable names must be entirely alphabetic.
I would replace your "music expression variables" with "LilyPond variables".

> 
> sopranoMusic = \relative c'' { c8 d e d c2 }
> #(define altoMusic #{ \relative e' { e8 f g f e2 } #})

One could also do
#(define scheme-only-music-expresson #{ \relative e' { e8 f g g e2 } #})
> 
> % music expression variables can only be dereferenced with "\".

I would change this to "they can only be handled directly by the parser with
"\"".

> 
> \score {
>   \new Staff <<
>   { \sopranoMusic }
>   \\
>   { \altoMusic }
   >> 
> }

One can "dereference" scheme-only-music-expression only in Scheme.

schemeDereferencer =
#(define-music-function (parser location) ()
  scheme-only-music-expression)
> 
> 
> % numeric variables can be defined with "=" or scheme-style, and
> % scheme-defined numeric variable names *can* have non-alphabetic
> % characters.
> 
> one = 1
> hashTwo = #2
> #(define scm-5 5)
> 
> 
> % string variables can be defined with "=" or scheme-style, and
> % scheme-defined string variable names can have hyphens, but not
> % numbers!
> 
> quoteThree = "3"
> hashQuoteFour = #"4"
> #(define scm-quote-Six "6")
> 
> 
> % regardless of the definition method, string variables can only be
> % dereferenced with "\"; and numeric variables can only be dereferenced
> % with "#"!
> 
> \markup \concat {
>   \number \quoteThree    % string
>   \hspace #one           % number
>   \number \hashQuoteFour % string
>   \hspace #hashTwo       % number
>   \number \scm-quote-Six % string
>   \hspace #scm-5         % number
>   \number \hashQuoteFour % string
> }

Note that your "numeric" variables are all Scheme variables; they are
prefaced to the parser by #, not by \.

The scm-quote-Six example is surprising to me.  I guess the parser treats
bare strings (like quoteThree, that are used in definitions) different from
pre-existing strings (prefaced by \).

> 
> %% of course, these restrictions are not an issue within scheme code
> #(for-each
>    display
>    (list one hashTwo quoteThree hashQuoteFour scm-5 scm-quote-Six))
> 
> 
> %% now, neither of these will work
> % \markup \concat { #3 #4 #6 }
> % \markup \concat { #"3" #"4" #"6" }
> 
> %% but this will
> \markup \concat { 3 4 6 }
> 
> %% and of course this will work
> \markup \concat { "3" "4" "6" }
> 
> %% but strangely so will this
> %% (note that \hashQuoteFour works, but not #"4")
> \markup \concat { \quoteThree \hashQuoteFour \scm-quote-Six }
> 

This is because markup needs LilyPond strings, not Scheme variables.
Anything prefaced with a # is a Scheme variable, regardless of what its
contents are.  Anything introduced with \ is a LilyPond string, regardless
of its contents.

> 
> %% so these numbers must be internally represented as strings?
> %% (since this does work)
> \markup \concat { 3 4 6 }
> 
> 
> %% there seems to be no way to successfully pass any of these to \markup
> % \markup \concat { #one #hashTwo #scm-5 }

That is correct, because \concat needs string arguments, not numeric
arguments.

There are two levels of dereferencing going on here.  One in the parser,
where \quoteThree is turned into "3", and one in the guile interpreter,
where "3" is passed to the Scheme function that \concat is turned into by
the parser.

Remember that the purpose of the parser is to build a giant scheme
expression, but that scheme expression is *not* evaluated at parse time.
The first level of dereferencing is primarily the LilyPond parser.

The second level of dereferencing, the evaluation of the scheme expressions,
takes place largely during the translation or engraving step.  And it's
during that step that the scheme errors tend to appear.


Hope this helps.  It was instructional to me to write it.

Carl





reply via email to

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