Trevor Bača escreveu:
> The first command sets the size of all pages. The second command sets
> the size of the pages that the \paper block applies to – if the \paper
> block is at the top of the file, then it will apply to all pages. If
> the \paper block is inside a \book, then the paper size will only
> apply to that book."
I rather think that the problem is that the input file of Lily is not
a data definition. You've tried to make it look like one by proposing
\new File, but it really isn't:
- we have identifiers; those imply state. for example
foo= { c4 d8 }
<< \foo \foo >>
is valid, but
<< \foo \foo >>
foo= { c4 d8 }
is not. So, we have statefulness.
- we have an entire scheme interpreter under the hood,
#(set-default-paper-size "a4")
executes a command which has side-effects.
I think it would be best if we were more straightforward,
and tell users that an input file is a sequence of commands
which are run in an interpreter. We're doing that anyway:
each .ly file actually is a Scheme module, and the whole file
is a sequence of top-level expressions, which are evaluated one
by one.
Some are directly run as Scheme expressions, such as
#(set-default-paper-size "a4")
Some parts of the input resemble 'pure' expressions
(ie. data), for example \markup and music expressions,
but also \book and \score.
Then, expressions at toplevel have side effects,
* foo = bar
defines identifier \foo
* \header { .. }
is an expression, eg. you can do
bla = \header { .. }
however, if you have a \header{} at toplevel,
it sets the default header.
* #(set-default-paper-size .. )
sets the default paper size
* \book { .. }
will produce an PS/PDF file as side effect
I think this is a well established concept. IN python, you can type
pure data as a toplevel expressions, eg.
"foo"
is valid python. But you can also define variables, either by
def bar(x): pass
or
bar = lambda x: 1
and execute statements with side effects, eg.
print "hello world"
In fact, some interpreters have a REPL (read-eval-print-loop), which are
written in the language itself. This is conceptually similar to
toplevel-handlers that we have in LilyPond.
The behavior of toplevel expressions is actually configurable
at run-time. This is a very useful, because it allows us to
make \book and \score behave differently in normal operation and
in lilypond-book.
See ly/declarations-init.ly and ly/lilypond-book-preamble.ly for the
relevant code.
> The language is actually then considerably clearer: no more \paper (at
> two scoping levels) and \layout (at three scoping levels). Just
> \score-settings, \book-settings and \global-settings naming unique
> slots for input entry. Furthermore, examples in the docs or on the
> list like \paper { whatever } will no longer be ambiguous as to level
> of scope. We will have either \book-settings { whatever } or
> \global-settings { whatever } instead.
this looks superfluous to me, in that we could just use \settings{}
everywhere. Introducing 3 keywords would make the documentation more
consistent and/or clearer. My experience is that it doesn't work, because
people won't use it. We have had \simultaneous { .. } as a
more correct form of << .. >> , but I've never seen it being used.