On Feb 6, 4:44 pm, Keith Bennett <keithrbenn...@gmail.com> wrote:
> In a substantial GUI app, it is extremely important for visual
> consistency, maintainability, reliability, and extensibility for as
> many components as possible to be coded once and reused (i.e. DRY).

A long time ago in a galaxy far away (okay, 1992-1994 in Cupertino) I
worked on an OS project written in Dylan when it was still a lisp.
Applications were built from frames (in the sense of frame languages
for knowledge representation), and presented to the user by means of s-
expressions that described the data to be presented, the values to be
obtained from the user, and the events that were to transform the
presentation.

If you were to read through a full description of our UI system (both
implemented, and proposed but never implemented) it would probably
sort of remind you of HTML and CSS. In detail it was pretty different
(we're talking about 1992 here; HTML was new and CSS not yet
invented), but in conception, it was similar: you describe a UI
element with a set of nestable expressions, and style and configure it
with (also nestable) styles.

For example, if you wanted to display a dialog box to get some values
from the user, you could call the macro user-bind:

(user-bind ((name <string>)
                (age <integer>))
    (do-stuff-with-user-data name age))

user-bind expanded into code that built a dialog window, constructed
appropriate widgets to retrieve a string and a integer, and provided
an OK and cancel button. Click okay and the user-bind form continued,
evaluating the user code in an environment in which name and age were
bound to the values provided by the user; cancel and a suitable
condition was signaled.

user-bind and similar macros accepted hinting parameters to specify
what kind of widget you wanted and how to lay them out. In the longer
term the plan was to define a style language to be used like so:

(bind ((*dialog-style* (style <tool-dialog>
                                       :scale :small
                                       :system-font *system-dialog-
font*))
         (*button-style* (style <small-button-style>
                                       :color-scheme *dialog-bright-
color-scheme*)))
      (user-bind ((name <string>)
                      (age <integer>))
                 (do-stuff-with-user-data name age)))

The idea was that the macros and methods built a UI element suitable
for capturing the events you needed. For each variable you wanted to
bind, the declared type told the system what kind of widget to create.
In cases where more than one kind of widget was appropriate, a default
choice would be provided in lexical variables that you could override
by rebinding them. Similarly, style and layout were described by
lexical variables that could be rebound. Clojure maps would be very
hand here; it would be straightforward to nest style deltas and obtain
the correct style information in a given lexical contour using merge.

Not all UIs are dialog-like, of course; so there were also functions
and macros to create longer-lived objects.  A suitable combination of
input parameters and lexical bindings made the same sorts of
presentation choices, and established event-handlers for the
constructed elements.

I can imagine implementing something like those tools for  Clojure
+Swing (or bare AWT, or Pivot, or SWT, or whatever).  A Clojure-like
implementation might make long-lived UI elements agents. You could of
course bind such elements to variables, as was done in the system we
built; alternatively, or additionally, you could take a cue from SK8
and Symbolics Dynamic Windows, and make it possible to obtain a valid
reference to a screen object by clicking it, and then paste that
reference into code. Then update the agent to use extended or modified
styles and UI elements. Finally, ask the widget for a copy of the
environment that specifies it.

WIth such a scheme you can write UI elements as well-structured code,
interact with live objects created with the code, modify them
interactively by direct manipulation and by evaluating forms, and save
the current state of the widgets to a (presumably versioned) file.

If I were doing work like this now in Clojure, I'd be inclined to use
vectors rather than macros for most of the UI element specification.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to