This is the mail archive of the guile@sourceware.cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: guile-doc/ref/env.texi



[CC-d to list]

jostobfe@linux.zrz.TU-Berlin.DE writes:
> 
> > we need this support for our LilyPond package (which is not included
> > in GUILE).  Have you got any idea when will be part of GUILE
> > officially?
> 
> Hmm.  This patch breaks a) syntax case macros and b) the high level
> (gh_...) api (additional env parameter is now required).  Although
> there are plans for a low level syncase macro support I can't say when this
> will happen. 
> 
> What exactly do you need it for?  In the current guile releases
> environments are implemented as a collection of first class variables.
> In theory the current module system provides all (at least most of :>)
> the functionality you ask for.

I tried asking on the list before, but I realise my explanation was
not very  clear.  I'll try again (please bear with me: I don't know
much about Scheme and GUILE)



Within lilypond (and within the input format), we have several objects
that contain variable settings.  For example, the PAPER block contains
several settings that influence layout details of the output.  The
\paper in the input is parsed into a Paper_def structure. A Paper_def
object is referenced while executing the C++ formatting modules.  So
the variables within the paper block are accessed from C++, but they
are also used in the input.

Here is an example (with slightly altered syntax) that creates three
paper objects.

	layout1 = PAPER {
		% comment: default (predefined) value for interline is 5.0

		stafflinethickness = 0.1 * interline;

		stemlinethickness = 2*
		stafflinethickness;
		% etc. ...
	}

	layout2 = PAPER {
		interline = 4.0;
		stafflinethickness = 0.08 * interline;
		% etc. ...
	}

	layout3 = PAPER {
		% default value for interline used here:
		stafflinethickness = 0.07 * interline;


		TRANSLATOR {
			NAME "Staff"
			staffLineThickness = stafflinethickness;
		}
	}

We would like to use GUILE internally to do variable definition,
scoping, evaluating expressions  etc., but the obvious approach,
translating

	foo = \bar


into


	(define foo bar)

doesn't work, because definitions are supposed to be internal to the
paper block.  In the above example, the value of stafflinethickness
for `layout3' should be 0.07 * 5 = 0.35 (and not 4.0 * 0.07 = 0.28).

Functions like gh_apply and gh_eval don't work for us because they
assume we want to do everything in the toplevel environment.

The second solution would be translating

    PAPER {

     foo = 1.0;
      bar = 2 * foo;
    }

into

	(let* (
	  (foo 2.0)
	  (bar (* 2 foo)) )
	  `((foo . ,foo) (bar . ,bar))
	  )

But then, we get new complications with TRANSLATOR (which references
variables inside the PAPER block).

Ideally, we want to create a C structure that functions as a scope (or
environment, that is the proper name, right?) in scheme, yet is also
accessible from C.

We don't have that much problems with transcending the gh_ API (we use
scm_ functions all the time), but it is not clear to me how I exactly
go about creating an environment within GUILE.

Now that I am writing this, I realise

* that I could probably find the answer in eval.c.  However, I am not
  sure where to look precisely, how variables are stored, and how
  stable this part of the GUILE interface is.

* that my second approach (building a let*) could probably be extended
  to get the current behavior. However I prefer a more Scheme based
  solution, because I think that that will have better-defined
  semantics, and will generalise better when we want new layout
  features.


-- 

Han-Wen Nienhuys, hanwen@cs.uu.nl ** GNU LilyPond - The Music Typesetter 
      http://www.cs.uu.nl/people/hanwen/lilypond/index.html 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]