
Garnet – a graphical toolkit for Lisp - cronjobber
http://garnetlisp.sourceforge.net/
======
DonHopkins
The name of the C32 spreadsheet mentioned in the article is an acronym:

"C32 has been implemented as part of the Garnet system. It is an acronym, and
stands for CMU’s Clever and Compelling Contribution to Computer Science in
CommonLisp which is Customizable and Characterized by a Complete Coverage of
Code and Contains a Cornucopia of Creative Constructs, because it Can Create
Complex, Correct Constraints that are Constructed Clearly and Concretely, and
are Communicated using Columns of Cells that are Constantly Calculated so they
Change Continuously and Cancel Confusion."

[http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.18....](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.18.3001&rep=rep1&type=pdf)

~~~
diskcat
Im actually more confused

~~~
Zuider
I am Completely Confused by the Cacophonous Cascade of Cryptic Cant and
Catchphrases in this Comment.

~~~
DonHopkins
It will all make more sense after you read some more BAMcronyms.

[http://www.cs.cmu.edu/~bam/acronyms.html](http://www.cs.cmu.edu/~bam/acronyms.html)

------
DonHopkins
Yay Garnet! ;) I worked on Garnet with Brad Myers at CMU, on the PostScript
printing driver. Brad is really into mineral acronyms, and I came up with an
acronym he liked: "GLASS: Graphical Layer And Server Simplifier".

Garnet had a lot of cool ideas in it, especially its constraints and prototype
based object system.

A few years ago I wrote up a description of a similar system called
OpenLaszlo, and how OpenLaszlo's constraint system compared with Garnet's
constraint system. Garnet had a lazy "pull" constraint system, while Laszlo
had an event/delegate based "push" system. Each used a compiler to
automatically determine the dependencies of constraint expressions.

Constraints and Prototypes in Garnet and Laszlo

[http://www.donhopkins.com/drupal/node/69](http://www.donhopkins.com/drupal/node/69)

The problem we ran into with supporting PostScript with Garnet is that we
wanted to use Display PostScript, but Garnet was using CLX, the Common Lisp X
Protocol library which was of course totally written purely in Lisp.

Of course CLX had no way to use any client side libraries that depended on
XLib itself. I'd steer clear of using anything that depends on CLX for
anything modern. (Does CLX still even exist?)

Brad Myers produced "All the Widgets," which must have some Garnet demos in
there somewhere! [1]

[1] All the Widgets, sponsored by the ACM CHI 1990 conference, to tell the
history of widgets up until then:
[https://www.youtube.com/watch?v=9qtd8Hc90Hw](https://www.youtube.com/watch?v=9qtd8Hc90Hw)

~~~
mpweiher
>
> [http://www.donhopkins.com/drupal/node/69](http://www.donhopkins.com/drupal/node/69)

"Constraints are like structured programming for variables"

Love it! Having been very interested in constraint programming and also
dabbled a bit here and there[1][2][3], what do you think is holding back
constraint programming?

[1]
[http://2016.modularity.info/event/modularity-2016-mvpapers-c...](http://2016.modularity.info/event/modularity-2016-mvpapers-
constraints-as-polymorphic-connectors)

[2] [http://blog.metaobject.com/2014/03/the-siren-call-of-kvo-
and...](http://blog.metaobject.com/2014/03/the-siren-call-of-kvo-and-cocoa-
bindings.html)

[3] [http://blog.metaobject.com/2015/09/very-simple-dataflow-
cons...](http://blog.metaobject.com/2015/09/very-simple-dataflow-constraints-
with.html)

~~~
DonHopkins
> what do you think is holding back constraint programming?

All the constraints. ;)

As you mentioned, there are tricky two-way mathematical constraints, like
Sutherland's Sketchpad [1] and descendants [2], and Gosling's PhD Thesis [3],
where the system understands the constraint expressions mathematically and
transforms them algebraically.

[1] Ivan Sutherland's Sketchpad:
[https://en.wikipedia.org/wiki/Sketchpad](https://en.wikipedia.org/wiki/Sketchpad)

[2] Geometer's Sketchpad:
[https://en.wikipedia.org/wiki/The_Geometer%27s_Sketchpad](https://en.wikipedia.org/wiki/The_Geometer%27s_Sketchpad)

[3] Algebraic Constraints; James Gosling; CMU CS Department PhD Thesis:
[http://digitalcollections.library.cmu.edu/awweb/awarchive?ty...](http://digitalcollections.library.cmu.edu/awweb/awarchive?type=file&item=362626)

And there are simpler one-way data flow constraints like Apple's KVO
notification [4], Garnet's KR based constraints [5], and OpenLaszlo's
event/delegate based constraints [6].

[4] Introduction to Key-Value Observing Programming Guide:
[https://developer.apple.com/library/mac/documentation/Cocoa/...](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html)

[5] KR: Constraint-Based Knowledge Representation:
[https://docs.google.com/viewer?url=http%3A%2F%2Fwww.cs.cmu.e...](https://docs.google.com/viewer?url=http%3A%2F%2Fwww.cs.cmu.edu%2Fafs%2Fcs%2Fproject%2Fgarnet%2Fdoc%2Fkr%2Fkr-
manual.ps)

[6] Oliver Steel: Instance-First Development:
[http://blog.osteele.com/posts/2004/03/classes-and-
prototypes...](http://blog.osteele.com/posts/2004/03/classes-and-prototypes/)

As you pointed out, KVO constraints simply say that object.x = otherObject.y,
so there's not much to them.

I think one thing holding back constraint programming is that they require an
interpreter or compiler to understand them, or the programmer to write code in
a constrained syntax.

Garnet's KR constraints are written as Lisp expressions implemented by Lisp
macros, that parse the expressions and recognize certain expressions like
"gvl" for "get value", and named path expressions. KR wires up the dependency
graph based on that information, and marks the constraint as invalid if any of
the links along the dependency path change, as well as when any of the final
values the expressions reference change. But it doesn't understand the
mathematical expressions themselves. At the time I was working on it, it
didn't know hot to figure out which branches of conditional expressions
mattered, so it would assume it depended on everything in the expression.
(i.e. like the C expression "size = window.landscape ? parent.width :
parent.height" \-- if window.landscape is true, it depends on parent.width,
else it depends on parent.height, but ). It only recalculates the constraint
values lazily when you read them. ("pull" constraints).

OpenLaszlo constraints are written as JavaScript expressions that the
OpenLaszlo compiler parses, and it creates some JavaScript data and hidden
methods behind the scenes that go along with the class, which are used at
runtime to keep track of all the dependencies. You don't have to use a special
expressions in constraints to read values, but you do have to use
object.setValue("key", value) to write values. (This was because OpenLaszlo
was targeting the Flash runtime, and that was the most efficient trade-off,
since Flash didn't support property setters like modern JavaScript does.)

OpenLaszlo constraints used a "push" model of propagating all dependent
changes forward when you called "setValue", because that was the best trade-
off at the time for speed and usability and how it was intended to be used.
But with getters and setters you could implement a more convenient constraint
system that didn't put so many constraints on the programmer and how you use
them.

------
BradAMyers
The C32 acronym is just for fun - here's some more:
[http://www.cs.cmu.edu/~bam/acronyms.html](http://www.cs.cmu.edu/~bam/acronyms.html)

We continue to do research on constraints in my group, see:
[http://cjs.from.so/](http://cjs.from.so/) (but it's in JavaScript - not
Lisp). There are many commercial uses of constraints today, such as for
graphical layout and "data bindings" (connecting the model and the view) in
many toolkits.

Brad Myers, CMU

------
hacker_9
Interesting, but are there any actual modern GUI frameworks for Lisp?

~~~
m48
I've looked into it a bit. The answer appears to be… sort of. It depends on
your definition of "modern," how many hoops you're willing to jump through,
and which dialects of Lisp you're willing to use. These are some of the more
promising options I found.

For Common Lisp, one of the longer-lasting and best supported options appears
to be CAPI, which comes with LispWorks
([http://www.lispworks.com/products/capi.html](http://www.lispworks.com/products/capi.html)),
but that costs a grand and is not open source, so that's kind of out of the
picture for most people. If you're looking for commercial option that will
just work, though, this might be worth investigating. (They seem to have
recently released a "hobbyist" version that is only $500, but you can only use
it for "non-commercial and non-academic purposes," so I'm not really sure how
useful that is.)

Ceramic ([http://ceramic.github.io/](http://ceramic.github.io/)) lets you use
Common Lisp to make desktop web apps using Atom's framework
([http://electron.atom.io/](http://electron.atom.io/)). While that comes with
all the disadvantages of making desktops apps with HTML+CSS+JS, it seems to be
one of the more professional and easier to set up options.

If you're using a Java implementation of Common Lisp, such as ABCL
([http://abcl.org/](http://abcl.org/)), you can presumably use any Java GUI
framework. I've heard, however, that using Java libraries is significantly
more awkward in ABCL than, say, Clojure, and that you might need to write some
Java code to bridge the gap. The main attempt to get that to work I've seen
appears to be this framework ( [https://common-
lisp.net/project/snow/](https://common-lisp.net/project/snow/) )—I'm unaware
of any applications actually written like this.

Clozure CL (not to be confused with Clojure) has bindings to Apple's Cocoa
framework
([http://trac.clozure.com/ccl/wiki/CocoaBridge](http://trac.clozure.com/ccl/wiki/CocoaBridge)).
Apparently there's a fairly battle tested cross-platform implementation of
Cocoa that you can use to make it run on Windows and Linux too, but I'm having
trouble finding a link to that right now. I think it was the framework used to
port Comic Life to Windows, if that helps. Regardless, though, this sounds
like a pretty scary option for someone without prior Cocoa experience.

Most of the more practical looking options I found seemed to be for Scheme.

Racket ([https://racket-lang.org/](https://racket-lang.org/)) comes with a GUI
toolkit that was originally forked from wxWidgets. The IDE is built in it,
among other things. It has some quirks that wxWidgets doesn't, though—for
example, all the widgets are native except for _all text entry controls,_
which makes accessibility… interesting. (Also, on my computer, at least, they
don't quite cooperate with high DPI displays.)

Chicken Scheme apparently has good bindings to IUP ([http://wiki.call-
cc.org/eggref/4/iup](http://wiki.call-cc.org/eggref/4/iup),
[http://webserver2.tecgraf.puc-rio.br/iup/](http://webserver2.tecgraf.puc-
rio.br/iup/)), a fairly lightweight framework that uses native widgets on
Windows and Motif/GTK on Linux/Unix/OS X. I wouldn't really call it modern,
but it does look fairly convenient—the Scheme API seems to basically let you
define GUIs in structured s-expressions ([http://wiki.call-cc.org/iup-
tutor#porting-some-examples-from...](http://wiki.call-cc.org/iup-
tutor#porting-some-examples-from-the-iup-distribution)). (Also, I'm pretty
sure it _does_ support Unicode, and that the IUP site is just out of date.)
This is the option I'm leaning towards learning.

Kawa Scheme runs on Java, providing the same benefits as ABCL, but it seems a
little more battle tested, and provides native support for making Android
applications ([http://www.gnu.org/software/kawa/Android-view-
construction.h...](http://www.gnu.org/software/kawa/Android-view-
construction.html)). It's used to, among other things, power MIT App Inventor.
(You can actually unzip App Inventor projects and find Scheme files inside,
which is kind of fun. I kind of wish the App Inventor team would make the
framework more accessible from Scheme. :p)

And, of course, if you're willing to settle for dialects of Lisp more distant
from Common Lisp or Scheme, you can use Hy and any Python GUI framework
([http://docs.hylang.org/en/latest/](http://docs.hylang.org/en/latest/)), or
Clojure and anything Java.

Hopefully there are some good ones I missed, because Lisp-like languages seem
like they would be pretty cool for GUIs.

~~~
soegaard
> Racket ([https://racket-lang.org/](https://racket-lang.org/)) comes with a
> GUI toolkit > that was originally forked from wxWidgets.

The GUI was rewritten in 2005 and there are no signs of wxWidgets left
([http://blog.racket-lang.org/2010/12/racket-
version-5.html](http://blog.racket-lang.org/2010/12/racket-version-5.html))

There are now native widgets on Windows, OS X, and, Linux.

> (Also, on my computer, at least, they don't quite cooperate > with high DPI
> displays.)

There are support for high resolutions displays at least on OS X - maybe the
situation is different on Linux?

