> > It sounds like you have in mind that a simpler and more generalized
> > grammar will simplify the code.  Is this necessarily true?  I was
> 
> Not necessarily, but we can always try.
> 
> > One thing that must be decided is whether you want 
> >    \keyword arg1 arg2 arg3 ... ;
> > or 
> >    \keyword { arg1 arg2 arg3 ... }
> > Or do you really want both?  
> 
> It doesn't matter for the stuff that is in the init files anyway, so
> being consistent is a good thing.

Well, I think it's desireable for the whole language to have a uniform
syntax.  So the init files should follow the same syntax as the rest
of it.  

> 
> Proposal:
> 
>       use \keyword {} for constructions that nest,
>       use \keyword ; for non-nesting stuff.
> 
> Now that I am thinking again, I realise why I disliked the
> 
>       \keyword {} 
> 
> construction.  This construction means that the meaning of { and } is
> overloaded within the definition of Music, and that is a Bad Thing.  
> 
> We can also take a different route and introduce a third delimiter:
> 
>       {} for sequential music
>       <> for simultaneous music
>       ?? for nestings

I'm not particularly bothered by the use of {} for both sequential
music and nestings.  Unfortunately, there's a shortage of paired
delimiters.  I think overloading may be preferable to the alternative.
It may be worse to introduce a symbol that doesn't clearly indicate
the pairing.

> Or use one delimiter, and have some prefix notation
> 
>       @{} sequential
>       ^{} simultaneous

I think this would make the language harder to read/write.

> but I doubt that this would make the language easier to read/write.
> 
> > But supposing you decide that all commands will have the form 
> >    \keyword arg1 arg2 arg3 ... ;
> > Can this be coded into the grammar in some systematic way?  The
> > arguments are of various types, not always the same type.  
> > 
> > I see things like:
> >    MUSICAL_PITCH '{' int int int '}'
> >    DURATION '{' int unsigned '}'
> >    ABSDYNAMIC '{' unsigned '}'
> >    SPANDYNAMIC '{' int int '}'
> >    SCRIPT '{' script_body '}'
> >          script_body: STRING int int int int int
> > 
> > Can this be rewritten as
> >    MUSICAL_PITCH arglist
> >    DURATION arglist
> >    ABSDYNAMIC arglist
> >    SPANDYNAMIC arglist
> >    SCRIPT arglist
> > for some definition of 'arglist'?  Is it feasible to write the grammar
> 
> We could do  
> 
>       SCRIPT intlist
>       MUSICALPITCH intlist
> 
> etc.

Where "intlist" is a list of integers?  It seems that if the mixed
type list isn't feasible, then it's not worth doing it for only those
commands that happen to take integer lists.

> > One strategy that came to mind is that you can treat all of the
> > commands that take complicated arguments (statement lists or
> > expression lists) the same: set a flag that indicates what command is
> > currently being processed.  When a particular construction is
> > encountered, it can check the flag to see if it is valid.  If not, it
> > can give an error (and a better one than is currently produced).
> > 
> > For example, 
> >    \shape = 2.5 \in 2.5 \in 3.5\in 3.5\in;
> > gives the mysterious message "parse error" when used outside of a
> > \paper block.  This is because the parsing for \shape is only done
> > inside of paper blocks.  If \shape was always parsed, then if it
> > happens to appear outside a paper block, a message like
> > "\shape must appear inside \paper" can be generated.  This would be
> > much friendlier.   
> > 
> > With something like this, if I can define 
> >   statementseq
> > to be normal parsing of the file, and then
> >   mudelafile: statementseq
> >   statementlist: '{' statementseq '}'
> > and then rules like
> >   command statementlist
> > the result is a great simplification in the basic structure of the
> > grammar.  It also has the effect of making the grammar more context
> > independent, since you can parse everything regardless of context.
> > You then decide what to do, or what errors to issue, based on context.
> 
> 
> Yes, but it wouldn't simplify using LilyPond, because this simple
> grammar doesn't explain why \shape can't be done at toplevel.  What
> you are proposing is more or less analogous to going from compile-time
> errors to run-time errors in a programming language: the language
> becomes simpler, but you don't necessarily make less errors.

Well, the current implementation doesn't explain why \shape can't be
done at top level.  It doesn't even explain why using \shape in that
situation is a parse error.  It doesn't even explain that the parse
error resulted from saying "\shape".  For all the confused user knows,
it was supposed to be "\shape { ... }" instead of "\shape = ... ;".
You have to go read parser.yy to find out that the problem is that
\shape is only legal inside \paper.

BTW, I'll note that the syntax of \shape is an inconsistency.  It
could be made consistent by deleting the '=' sign.

> How would you concisely and unambiguously explain what kinds of
> expressions can be nested in what other kind of expression?

I'm not sure if this is a problem or not.  First, I'll note that it
appears that every command has only one context in which it can
appear.  The \shape command appears exclusively in \paper.  Anywhere
else it is a "parse error".  Furthermore, it seems that only the last
layer of context matters.  If only the last layer of context is
important, then you just need a flag that indicates the current
context.  Each command can have a list of the contexts where it is
permitted (generally there is only one).

I can see what you mean about compile-time vs. run-time errors.  It's
true that it doesn't change the number of errors.  But if it enables
the enigmatic "parse error" to be replaced with a message that
actually carries some information, it would be a valuable change.  On
the other hand, maybe there's some other way to achieve this result.

Basically I think it would be good if anytime a keyword appears in the
wrong context, a message is generated saying: "this keyword is in the
wrong context.  It can only be used in context(s) X (Y, and Z)".  That
way, the user knows immediately what is wrong, rather than spending 10
minutes puzzling over the obscure "parse error", and then having to
consult the manual to figure out where the command is supposed to go.

> > What I really had in mind was going over the grammar to determine (by
> > human thought) whether things are consistent, and fixing
> > inconsistencies that are encountered.  In other words, there would be
> > a more generalized grammar that is not the "Real Thing" but which the
> > programmers match the actual behavior to.
> 
> Let's try to fix the real grammar as far as we can, for starters.
> Then we can focus on the `abstract' grammar.

I think that in order to fix the real grammar, it's necessary to focus
on the abstract grammar.  What I wrote above is that humans have to
read the grammar and decide whether things are consistent are not.
Now of course it's possible to just do this using our enormous mental
capacities.  But I think it is preferable if we construct a written
representation of what we are trying to get the real grammar to do
that reflects the consistency we are trying to enforce.  The abstract
grammar enables us to communicate our notions about what things are
supposed to be consistent.  It will help new people who want to add
features know what kind of constructions they should use.

If you have an abstract grammar that you KNOW you are supposed to be
following, you can look at it before adding a feature to the language
and ask the question: does my addition introduce an inconsistency.  In
fact, I think in the ideal situation, the abstract grammar would be
written before you write one line of code.



I noticed in the README file the suggestion of \plet 2/3 {c8 c8 c8} as
a syntax.  The proposed keyword "\plet" seems kind of mysterious.
(The problem is that "plet" sounds very different from the last
syllable of "triplet".)  Maybe it should be "\tuplet" instead? 
I'm uncertain if this is really better for the general population.  
The word "tuplet" is  used in mathematics in the context "n-tuplet"
to refer to a group of n  things.  But "tuplet" isn't in the english
dictionary.  

Also, this command format appears to be inconsistent because it takes
two arguments but no semicolon.  Admitedly, the semicolon seems like
an unnecessary burden in this situation.  Perhaps semicolons should be
legal but optional for all commands that take a fixed number of args?
(This has the disadvantage of introducing more context into the
grammar, in some sense.)

The syntax 
    \type CONTEXT = NAME { stuff }
seems like an abuse of the '=' sign to me, though a good alternative
hasn't leapt to mind.

Reply via email to