From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Rob Browning Newsgroups: gmane.lisp.guile.devel Subject: Re: scm_* API extension? [was] scm_* API question Date: Mon, 05 Aug 2002 13:45:53 -0500 Sender: guile-devel-admin@gnu.org Message-ID: <877kj5w3dq.fsf@raven.i.defaultvalue.org> References: <20020730121436.GA4465@www> <20020730200929.A18106@kiwi.pyrotechnics.com> <20020731100300.GC5661@www> <20020731150602.A32555@kiwi.pyrotechnics.com> <20020801094121.GC7425@www> <15694.49163.715320.366211@meddo.cs.uu.nl> NNTP-Posting-Host: localhost.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: main.gmane.org 1028573135 308 127.0.0.1 (5 Aug 2002 18:45:35 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Mon, 5 Aug 2002 18:45:35 +0000 (UTC) Cc: Marius Vollmer , rm@fabula.de, guile-devel@gnu.org Return-path: Original-Received: from fencepost.gnu.org ([199.232.76.164]) by main.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 17bmrF-00004r-00 for ; Mon, 05 Aug 2002 20:45:33 +0200 Original-Received: from localhost ([127.0.0.1] helo=fencepost.gnu.org) by fencepost.gnu.org with esmtp (Exim 3.35 #1 (Debian)) id 17bmrl-00048R-00; Mon, 05 Aug 2002 14:46:05 -0400 Original-Received: from dsl-209-87-109-2.constant.com ([209.87.109.2] helo=defaultvalue.org) by fencepost.gnu.org with esmtp (Exim 3.35 #1 (Debian)) id 17bmrb-00047u-00 for ; Mon, 05 Aug 2002 14:45:55 -0400 Original-Received: from raven.i.defaultvalue.org (raven.i.defaultvalue.org [192.168.1.7]) by defaultvalue.org (Postfix) with ESMTP id 667DD14EF; Mon, 5 Aug 2002 13:45:54 -0500 (CDT) Original-Received: by raven.i.defaultvalue.org (Postfix, from userid 1000) id D8BB1DD6; Mon, 5 Aug 2002 13:45:53 -0500 (CDT) Original-To: Han-Wen Nienhuys 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") Original-Lines: 82 User-Agent: Gnus/5.090006 (Oort Gnus v0.06) Emacs/21.2 (i386-pc-linux-gnu) Errors-To: guile-devel-admin@gnu.org X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.0.11 Precedence: bulk List-Help: List-Post: List-Subscribe: , List-Id: Developers list for Guile, the GNU extensibility library List-Unsubscribe: , List-Archive: Xref: main.gmane.org gmane.lisp.guile.devel:999 X-Report-Spam: http://spam.gmane.org/gmane.lisp.guile.devel:999 Han-Wen Nienhuys 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