This is the mail archive of the guile@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: difficulty of writing translators


Jim Blandy <jimb@red-bean.com> writes:

> > [PARAMETER-gizmo code omitted]
> 
> That's the right idea.  Maybe something like the below (modulo
> terminology).
> 
> The other approach is to model them as single procedures that act like
> getters when applied to zero arguments, and setters when applied to
> one argument.  The Guile support for this would just be a new
> lambda-like form that handles things nicely, and a naming convention
> to allow users to easily tell what procedures act this way.  That's
> mildly cuter, but it's not existing practice.
> 
> Comments solicited.

A few things:

It would be nice for this to be more specific.  In particular, right
now, it just names some procedures.  Instead, it could create a place
to store the value, store a list of functions to be notified when the
value changes, and provide a function which adds a function to be
notified (and maybe one to remove a function to be notified).  I'm
thinking more restrictive -> more standard -> easier to recognize.
What you suggested is a convention for variables that aren't really
variables.  We could use a mechanism for using Tcl-style watched
variables. 

define-setting NAME
Constructs a setting called NAME. This defines four functions: 
(NAME) returns the value of the setting.  Initially unspecified. 
(set-NAME! VALUE) sets NAME to VALUE then calls each function in the
watch-list of NAME, which is initially empty. 
(add-NAME-watcher! FUNC) arranges for FUNC to be called with the old
and new values of NAME every time NAME changes. 
(remove-NAME-watcher! FUNC) removes FUNC from the watch-list of NAME. 

As an example:

(define-setting border-width)
(set-border-width! 2)
; Nothing special happens
(add-border-width-watcher (lambda (new old) (redraw-all-borders)))
(border-width)
; => 2
(set-border-width! 5)
; Windows redraw with wider borders
(border-width)
; => 5
(apropos-internal "border-width")
; => (set-border-width! border-width add-border-width-watcher! remove-border-width-watcher!)
; Note no variable to play with

A possible extension would be a way to wrap a normal variable as a
setting (with no watchers), so that code can easily be changed over
later to use a real setting:

(define-setting-from-variable border-width some-variable)

Then code that uses set-border-width! can easily interoperate with code
that expects to use set! border-width.  border-width can't be
watched. 

Andrew