[Top][All Lists]

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

Re: Reorganizing the contents of the \paper block

From: Han-Wen Nienhuys
Subject: Re: Reorganizing the contents of the \paper block
Date: Fri, 09 Feb 2007 01:24:49 +0100
User-agent: Thunderbird (X11/20070130)

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.


is valid python. But you can also define variables, either by

  def bar(x):  pass


  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/ and 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.


Han-Wen Nienhuys - address@hidden -

LilyPond Software Design
 -- Code for Music Notation

reply via email to

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