unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Rob Browning <rlb@defaultvalue.org>
Cc: Marius Vollmer <marius.vollmer@uni-dortmund.de>,
	rm@fabula.de, guile-devel@gnu.org
Subject: Re: scm_* API extension? [was] scm_* API question
Date: Mon, 05 Aug 2002 13:45:53 -0500	[thread overview]
Message-ID: <877kj5w3dq.fsf@raven.i.defaultvalue.org> (raw)
In-Reply-To: <15694.49163.715320.366211@meddo.cs.uu.nl> (Han-Wen Nienhuys's message of "Mon, 5 Aug 2002 20:12:27 +0200")

Han-Wen Nienhuys <hanwen@cs.uu.nl> writes:

> f1.ly
>
> 	 #(set! global-foo-option #t) ;; default  = #f
> 	 \score  {\notes { .. } }
>
> f2.ly
>
> 	\score { \notes { ..other notes.. } }
>
> What really happens during execution depends on the order of
> execution: if you do
>
> 	lilypond f1 f2
>
> then f2 is processed with global-foo-option set to #t. If you change
> the order, then f2 is processed with global-foo-option set to #f.
>
> It would be nice if we could have some kind of copy-on-write system
> for variables, so that I can reset the state of the variables before
> processing each new file.
>
> [disclaimer, I know nothing of advanced Scheme techniques, I might be
> missing some basic idiom here completely.]

I'm not familiar with what lilypond is doing, but can you do one of:

  * create a new "anonymous module" (as I described in an answer to
    the mod_guile thread) for each file/"session" you're going to
    load, initialize the module by calling

      (eval '(ly-initialize-sandbox) *current-user-module*)
 
    then execute the user's code in there with another appropriate
    eval.

  * Don't use globals.  Hide all the lilypond specific state inside
    a relevant per-load-file data structure that's either newly
    created or reinitialized with each file load.

  * Have a suitable initialization function that resets the state of
    the global envt appropriately and call that between .ly files
    loads.  In general, this is easier if you don't make changing
    global variables part of the public API -- i.e. *everything*
    should be a function like (ly-set-global-foo-option! value).  This
    way you have a lot more control over what's going on and it's a
    lot easier to keep track or clean up after user changes.

    For (simplistic) example, if you write an editor and don't make
    raw set!'s part of the public API, then you can more easily
    implement undo:

      (define (sillyedit-change-margin-width! width)
        (push-undo!
          (let ((old-width (silly-edit-get-margin-width)))
            (lambda ()
              (se-lowlevel-set-margin-width! old-width))))
        (se-lowlevel-set-margin-width width))

    With this approach, multiple levels of undo just involve replaying
    the undo list (of course *really* getting undo/redo right is
    *much* harder).

    Anyway, IMO it's often better not to expose variables -- use
    functions for everyhing so you'll be able to rearrange your
    internal semantics later if you want/need to.  It's also easier
    if/when you ever want to migrate to a threaded environment.

  * create your own recursive descent mini-parser for the language in
    question (if it's sufficiently different from plain scheme, or if
    you need super-anal security or error checking), and just load and
    "evaluate" the .ly files with that parser.  You can reinitialize
    it between runs.

Hope this helps.

-- 
Rob Browning
rlb @defaultvalue.org, @linuxdevel.com, and @debian.org
Previously @cs.utexas.edu
GPG=1C58 8B2C FB5E 3F64 EA5C  64AE 78FE E5FE F0CB A0AD

_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


  reply	other threads:[~2002-08-05 18:45 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-07-30 12:14 scm_* API question rm
2002-07-31  1:09 ` Christopher Cramer
2002-07-31 10:03   ` scm_* API extension? [was] " rm
2002-07-31 10:10     ` Marius Vollmer
2002-07-31 18:21       ` rm
2002-07-31 21:59         ` Rob Browning
2002-08-01 10:10           ` rm
2002-08-01 16:51             ` Rob Browning
2002-08-05 15:08         ` Marius Vollmer
2002-08-05 16:06           ` rm
2002-08-05 16:49             ` Marius Vollmer
2002-07-31 20:06       ` Christopher Cramer
2002-07-31 22:14         ` Rob Browning
2002-08-01  9:41         ` rm
2002-08-05 17:51           ` Marius Vollmer
2002-08-05 18:12             ` Han-Wen Nienhuys
2002-08-05 18:45               ` Rob Browning [this message]
2002-08-05 18:31             ` Rob Browning
2002-08-05 18:33             ` rm
2002-08-05 15:12         ` Marius Vollmer
2002-07-31 10:11 ` Marius Vollmer
2002-07-31 10:30   ` rm

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=877kj5w3dq.fsf@raven.i.defaultvalue.org \
    --to=rlb@defaultvalue.org \
    --cc=guile-devel@gnu.org \
    --cc=marius.vollmer@uni-dortmund.de \
    --cc=rm@fabula.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).