From: Ken Tilton
Subject: Novus, Booty, This One's For You
Date: 
Message-ID: <8m8hg.743$IP7.545@fe10.lga>
Available as cells-manifesto.txt in:

     http://common-lisp.net/cgi-bin/viewcvs.cgi/cells/?root=cells


                    Cells In A Nutshell

The Cells library as it stands is all about doing interesting things 
with slots of CLOS instances. Nothing says a global variable could not 
be mediated by a Cell, and indeed one Cells user is known to have 
experimented with that. Also, some work was done on having slots of 
DEFSTRUCTs mediated by Cells. But for the rest of this exposition let's 
just talk about CLOS slots and instances.

The Cells library allows the programmer to specify at make-instance time 
that a slot of an instance be mediated for the life of that instance by 
one of:

    -- a so-called "input" Cell;
    -- a "ruled" Cell; or
    -- no Cell at all.

Note that "slot of an instance" is not the same as "slot of a class". A 
vital feature of the Cells library is that different instances may do 
different things Cells-wise with the same slot.

A slot mediated by an input Cell may be assigned new values at runtime. 
It is an error to assign a new value to a slot of an instance not 
mediated by any Cell. Ruled Cells come with an instance-specific rule in 
the form of an anonymous function of two variables, the instance owning 
the slot and the prior value (if any) computed by the rule. These rules 
consist of arbitrarily complex Common Lisp code, and are invoked 
immediately after instance initialization or, if they are declared lazy, 
when their slot readers are invoked.

When a rule runs, any dynamic read (either expressly in the rule source 
or during the execution of  some function invoked by the rule) of a slot 
of any instance mediated by a Cell of any type establishes a runtime 
dependency of the ruled cell on the slot of the instance that was read. 
Note then that thanks to code branching, dependencies can vary after 
every rule invocation.

When application code assigns a new value to an input Cell (a quick way 
of saying an instance slot mediated by an input Cell) -- typically by 
code polling OS events or a socket or an input device -- a cascade of 
recalculation ensues to bring direct and indirect ruled dependents 
current with the new value assigned to the input Cell.

To allow the emergent data animation model to operate usefully on the 
world outside the model--if only to update the screen--programmers may 
specify so-called observer callbacks dispatched according to: slot name,
instance, new value, old value, and whether the old value actually 
existed (false only on the first go).

Finally, to make it possible for such a declarative model to talk 
intelligibly to imperative systems such as Tcl/Tk which sometimes 
requires a precise sequence of commands for something to work at all, a 
mechanism exists by which client code can (a) queue tasks for execution 
after a data change has fully propagated and (b) process those tasks 
with a client-supplied handler. Tasks are queued with arbitrary keying 
data which can be used by the handler to sort or compress the queued tasks.

                            Data Integrity

When application code assigns to some input cell X, the Cells engine 
guarantees:

   - recomputation exactly once of all and only state affected by the 
change to X, directly or indirectly through some intermediate datapoint. 
note that if A depends on B, and B depends on X, when B gets 
recalculated it may come up with the same value as before. In this case 
A is not considered to have been affected by the change to X and will 
not be recomputed.

   - recomputations, when they read other datapoints, must see only 
values current with the new value of X. Example: if A depends on B and 
X, and B depends on X, when A reads B it must return a value recomputed 
from the new value of X.

   - similarly, client observer callbacks must see only values current 
with the new value of X; and

   - a corollary: should a client observer SETF a datapoint Y, all the 
above must happen with values current with not just X, but also with the 
value of Y /prior/ to the change to Y.

   - Deferred "client" code must see only values current with X and not 
any values current with some subsequent change to Y queued by an observer

                         Benefits

Program state guaranteed to be self-consistent, without programmer 
effort. Dependencies are identified by the engine, and change 
propagation happens automatically.

Greater object re-use. Slots of instances can be authored with rules, 
not just literal values. In a sense, we get greater reuse by allowing 
instances to override slot derivations instance by instance. But not 
slot expressions, which are still class-oriented.

Natural decomposition of overall application complexity into so many 
simple rules and slot observers.

                       Applications

Any application that must maintain an interesting, long-lived data model 
incorporating a stream of unpredictable data. Two examples: any GUI 
application and a RoboCup soccer client.

An application needing to shadow data between two systems. Examples: a 
Lisp GUI imlemented by thinly wrapping a  C GUI library, where Lisp-land 
activity must be propagated to the C GUI, and C GUI events must 
propagate to Lisp-land. See the Cells-Gtk or Celtk projects. Also, a 
persistent CLOS implementation that must echo CLOS instance data into, 
say, SQL tables.

From: Jack Unrue
Subject: Re: Novus, Booty, This One's For You
Date: 
Message-ID: <j26a825tkgbc7bjn92ffji15td24vmtcf0@4ax.com>
On Tue, 06 Jun 2006 01:26:49 -0400, Ken Tilton <·········@gmail.com> wrote:
>
> Available as cells-manifesto.txt in:
>
>      http://common-lisp.net/cgi-bin/viewcvs.cgi/cells/?root=cells
>
>
>                     Cells In A Nutshell
>
> [snip]

Hey Ken, that's pretty good stuff. How do you like the
following as a sort of elevator pitch?  If you like it,
feel free to use it in your docs:


Cells provides the plumbing for data dependency management
which every non-trivial program must have; a developer
using Cells can focus on computing program state and
reacting to state changes, leaving Cells to worry about
how that state is propagated. Cells does this by enabling
a declarative mechanism built via an extension to CLOS,
and hence achieves its goal in a way that meshes well with
with typical Common Lisp programming style.


-- 
Jack Unrue
From: Ken Tilton
Subject: Re: Novus, Booty, This One's For You
Date: 
Message-ID: <kyfhg.2$Wd5.1@fe10.lga>
Jack Unrue wrote:
> On Tue, 06 Jun 2006 01:26:49 -0400, Ken Tilton <·········@gmail.com> wrote:
> 
>>Available as cells-manifesto.txt in:
>>
>>     http://common-lisp.net/cgi-bin/viewcvs.cgi/cells/?root=cells
>>
>>
>>                    Cells In A Nutshell
>>
>>[snip]
> 
> 
> Hey Ken, that's pretty good stuff. How do you like the
> following as a sort of elevator pitch?  If you like it,
> feel free to use it in your docs:
> 
> 
> Cells provides the plumbing for data dependency management
> which every non-trivial program must have; a developer
> using Cells can focus on computing program state and
> reacting to state changes, leaving Cells to worry about
> how that state is propagated. Cells does this by enabling
> a declarative mechanism built via an extension to CLOS,
> and hence achieves its goal in a way that meshes well with
> with typical Common Lisp programming style.
> 
> 

OK, I just added sections for Prior Art and Commentary. Your bit went 
into commentary:

"Prior Art
---------
The entire constraint programming field, beginning I guess with Guy Steele's
PhD Thesis in which he develops a constraint programming language or two.
   http://portal.acm.org/citation.cfm?id=889490&dl=ACM&coll=ACM
   http://www.cs.utk.edu/~bvz/quickplan.html

Garnet's KR

COSI:
  "The Constraint Sequencing Infrastructure (COSI) is an extension to
the Common Lisp Object System (*(CLOS)) which supports a constraint
based object-oriented programming model. .....

"A constraint is a specialized method which will be automatically
re-run by the COSI infrastructure whenever any of its input values
change. Input values are any of the object attributes that are
accessed by the constraint, and which are therefore assumed to
alter the processing within the constraint.

"Whenever a state change occurs those constraints which depend upon
that state are added to a propagation queue. When the system is
queried a propagation cycle runs ensuring that the state of the
system is consistent with all constraints prior to returning a value."
-- http://www.cliki.net/ACL2/COSI?source

See also:
  The spreadsheet paradigm: 
http://www.cs.utk.edu/~bvz/active-value-spreadsheet.html
  The dataflow paradigm: http://en.wikipedia.org/wiki/Dataflow
  Reactive programming: http://www.haskell.org/yampa/AFPLectureNotes.pdf
  Frame-based programming

Commentary
----------
-- Jack Unrue, comp.lang.lisp
"Cells provides the plumbing for data dependency management which every
non-trivial program must have; a developer using Cells can focus on
computing program state and reacting to state changes, leaving Cells to 
worry about
how that state is propagated. Cells does this by enabling a declarative
mechanism built via an extension to CLOS, and hence achieves its goal in 
a way
that meshes well with with typical Common Lisp programming style."

-- Bill Clementson, http://bc.tech.coop/blog/030911.html
"Kenny Tilton has been talking about his Cells implementation on 
comp.lang.lisp
for some time but I've only just had a look at it over the past few 
evenings.
It's actually pretty neat. Kenny describes Cells as, conceptually, 
analogous to
a spreadsheet cell (e.g. -- something in which you can put a value or a 
formula
and have it updated automatically based on changes in other "cell" values).
Another way of saying this might be that Cells allows you to define classes
whose slots can be dynamically (and automatically) updated and for which
standard observers can be defined that react to changes in those slots."

-- "What is Cells?", Cells-GTk FAQ, 
http://common-lisp.net/project/cells-gtk/faq.html#q2
"If you are at all familiar with developing  moderately complex software 
that
is operated through a GUI, then you have probably
learned this lesson: Keeping what is presented through the GUI in-sync 
with what
the user is allowed to do, and in-sync with the computational state of the
program is often tedious, complicated work. .... Cells-GTK helps
with these tasks by providing an abstraction over the details; each of 
the tasks
just listed can be controlled by (a) formula that specify the value of
attributes of graphic features in the part-subpart declaration (that 
declaration
is called 'defpart' in cells-gtk); and, (b) formula that specify the 
value of CLOS slots."

-- Phillip Eby, PyCells and peak.events,
... http://www.eby-sarna.com/pipermail/peak/2006-May/002545.html
"What I discovered is quite cool.  The Cells system *automatically
discovers* dynamic dependencies, without having to explicitly specify that
X depends on Y, as long as X and Y are both implemented using cell
objects.  The system knows when you are computing a value for X, and
registers the fact that Y was read during this computation, thus allowing
it to automatically invalidate the X calculation if Y changes.

"...Aside from the automatic dependency
detection, the cells system has another trick that is able to significantly
reduce the complexity of event cascades, similar to what I was trying (but
failing) to do using the "scheduled thread" concept in peak.events.

"Specifically, the cells system understands how to make event-based updates
orderly and deterministic, in a way that peak.events cannot.  It
effectively divides time into "propagation" and "non-propagation"
states.  Instead of simply making callbacks whenever a computed value
changes, the system makes orderly updates by queueing invalidated cells for
updating.  Also, if you write code that sets a new value imperatively (as
opposed to it being pulled declaratively), the actual set operation is
deferred until all computed cells are up-to-date with the current state of
the universe."

kenny

-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
    Attorney for Mary Winkler, confessed killer of her
    minister husband, when asked if the couple had
    marital problems.
From: Jack Unrue
Subject: Re: Novus, Booty, This One's For You
Date: 
Message-ID: <k1rb829se6g9bq2rk5477gs1sfo8tug0d8@4ax.com>
On Tue, 06 Jun 2006 09:38:18 -0400, Ken Tilton <·········@gmail.com> wrote:
>
>"Cells provides the plumbing for data dependency management which every
>non-trivial program must have; a developer using Cells can focus on
>computing program state and reacting to state changes, leaving Cells to 
>worry about
>how that state is propagated. Cells does this by enabling a declarative
>mechanism built via an extension to CLOS, and hence achieves its goal in 
>a way
>that meshes well with with typical Common Lisp programming style."
                  ^^^^^^^^^

Sorry, that was a typo in my original post.

-- 
Jack Unrue
From: Steven E. Harris
Subject: Re: Novus, Booty, This One's For You
Date: 
Message-ID: <q94odx6z2k5.fsf@chlorine.gnostech.com>
Ken Tilton <·········@gmail.com> writes:

> It is an error to assign a new value to a slot of an instance not
> mediated by any Cell.

This sentence is confusing. Does this imply that every mutable slot in
the program must be mediated by a Cell? Does "not mediated by any
Cell" modify "instance", "slot", or "value"?

> Note then that thanks to code branching, dependencies can vary after
> every rule invocation.

Say we have some Cell rule like:

  (if (foo)
      (^a)
    (^b))

On one read, foo returns true, so Cell "a" knows that this Cell
depends on it. Any updates to "a" will propagate back out to this
Cell. Now, if we run this rule again, foo might return a different
value. Two questions arise:

  o Is there some way to indicate that the current value of this Cell
    shouldn't be cached? ("volatile" comes to mind.)

  o If foo returns false, this Cell should stop depending on "a" and
    come to depend on "b". How does Cells unwire the link from "a" to
    this Cell? Does Cells keep not only "parent pointers" (subject to
    observer) but "child pointers" (observer to subject) as well, so
    that this Cell in question can visit all its current dependencies
    and erase them?

>   - a corollary: should a client observer SETF a datapoint Y, all the
> above must happen with values current with not just X, but also with
> the value of Y /prior/ to the change to Y.

Does execution of this SETF "hang" synchronously while the rest of X
updates propagate, or is the SETF request truly put into a queue, with
SETF returning and the actual change to Y happening "later"?

>   - Deferred "client" code must see only values current with X and not
> any values current with some subsequent change to Y queued by an
> observer

There's that word "queue" again.

  ... you tell me you're not in the mood for details. Now you listen
  to me; I want details, and I want them right now. I don't have a
  job, I've got no place to go, you're not in the mood? Well you GET
  in the mood!
                    -- George Costanza�


Footnotes: 
� http://en.wikiquote.org/wiki/Seinfeld

-- 
Steven E. Harris
From: Ken Tilton
Subject: Re: Novus, Booty, This One's For You
Date: 
Message-ID: <xxjhg.11$gV1.8@fe12.lga>
I just made extensive additions to cells-manifesto.txt, which is rapidly 
turning into cells-user-guide.txt. I refer you to that for your answers, 
in the hope of finding out how to make it better. Some responses below, 
though....

Steven E. Harris wrote:
> Ken Tilton <·········@gmail.com> writes:
> 
> 
>>It is an error to assign a new value to a slot of an instance not
>>mediated by any Cell.
> 
> 
> This sentence is confusing. Does this imply that every mutable slot in
> the program must be mediated by a Cell? 

No. Not every class must be a Cells-ready class, and not every slot must 
be managed by Cells. I have commandeered neither Common Lisp nor CLOS. 
Do attempt to adjust your television.

> Does "not mediated by any
> Cell" modify "instance", "slot", or "value"?

A slot of a class may be declared to be subject to the Cells engine, yet 
an instance may be defined in a way that the slot is not mediated by a 
Cell. (make-instance 'box :width 42) would do the trick. The Cells 
engine still notifies any observer at initialization time, even though 
this cell /slot/ is not in this instance mediated by a cell.


> 
> 
>>Note then that thanks to code branching, dependencies can vary after
>>every rule invocation.
> 
> 
> Say we have some Cell rule like:
> 
>   (if (foo)
>       (^a)
>     (^b))
> 
> On one read, foo returns true, so Cell "a" knows that this Cell
> depends on it. Any updates to "a" will propagate back out to this
> Cell. Now, if we run this rule again, foo might return a different
> value. Two questions arise:
> 
>   o Is there some way to indicate that the current value of this Cell
>     shouldn't be cached? ("volatile" comes to mind.)

No. You /can/ in effect say that a slot of a class should always 
propagate, by supplying a changedp predicate that always answers "yes", 
and a rule can return a second value of :propagate so that this slot of 
this instance always propagates.

> 
>   o If foo returns false, this Cell should stop depending on "a" and
>     come to depend on "b". How does Cells unwire the link from "a" to
>     this Cell? Does Cells keep not only "parent pointers" (subject to
>     observer) but "child pointers" (observer to subject) as well, so
>     that this Cell in question can visit all its current dependencies
>     and erase them?

yeah.

> 
> 
>>  - a corollary: should a client observer SETF a datapoint Y, all the
>>above must happen with values current with not just X, but also with
>>the value of Y /prior/ to the change to Y.
> 
> 
> Does execution of this SETF "hang" synchronously while the rest of X
> updates propagate, or is the SETF request truly put into a queue, with
> SETF returning and the actual change to Y happening "later"?

I forget. You are supposed to write syntax to defer the change. I forget 
if I throw an error if the syntax is omitted or just hang the outer setf 
until the renegade inner setf completes. I might have done the latter 
since Cells worked fine for ages in many different applications with 
such renegades. RoboCup broke that.

> 
> 
>>  - Deferred "client" code must see only values current with X and not
>>any values current with some subsequent change to Y queued by an
>>observer
> 
> 
> There's that word "queue" again.

It appears 34 times in the Cells source, including 21 times in 
integrity.lisp. The different queues used are:

(define-constant *ufb-opcodes* '(:tell-dependents
                                  :awaken ;; new instances
                                  :client
                                  :ephemeral-reset
                                  :change)) ;; input cell

And now for your pop quiz:

- Which queue seems to be missing? 10 points
- When do you suppose that work is being done? 2 points
- Why does it not have to wait? 20 points

Due midnight, EDT.

kenny

-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
    Attorney for Mary Winkler, confessed killer of her
    minister husband, when asked if the couple had
    marital problems.
From: Steven E. Harris
Subject: Re: Novus, Booty, This One's For You
Date: 
Message-ID: <q94d5dmxgmf.fsf@chlorine.gnostech.com>
Ken Tilton <·········@gmail.com> writes:

> I just made extensive additions to cells-manifesto.txt, which is
> rapidly turning into cells-user-guide.txt. I refer you to that for
> your answers, in the hope of finding out how to make it better.

I'll take a look.

> (make-instance 'box :width 42) would do the trick. The Cells engine
> still notifies any observer at initialization time, even though this
> cell /slot/ is not in this instance mediated by a cell.

And that's /not/ the error you're describing, right?

I'm looking at the elaborated wording in cells-manifesto.txt under the
heading "No Cell at All". Now I see the bit about ":cell nil". Just to
clarify, the error you're describing arises when :cell is non-nil,
meaning that the slot should be managed/mediated by Cells, but the
user still changes a value that cannot be properly observed?

No, wait. I'm confused by what "Here" refers to in "Here, the Cells
engine has been told ..." If "Here" refers to specifying ":cell nil",
then that sounds like like it's describing a way to lock down a
per-instance constant in a slot. If "Here" refers to the error in the
previous paragraph, it's contrasting the error case with specifying
":cell nil". Do you see how it could be read either way?

By either interpretation, the error case wording still sounds too
strong:

  it is an error to assign a new value to a slot of an instance not
  mediated by any Cell.

I would assume that I could have slots with values that are never of
interest to Cells flow. Maybe I increment a counter every time some
change arises, and I want to inspect that counter at the end of the
program run for some reason. Say that the counter is a slot in an
instance that has some other Cell-mediated slots. Now, the slot is
"not mediated by an Cell". Is it an error to change its value?

> And now for your pop quiz:
>
> - Which queue seems to be missing? 10 points
> - When do you suppose that work is being done? 2 points
> - Why does it not have to wait? 20 points
>
> Due midnight, EDT.

I'm going to warn you right now: I may need an extension.

-- 
Steven E. Harris
From: Ken Tilton
Subject: Re: Novus, Booty, This One's For You
Date: 
Message-ID: <umkhg.16$gV1.8@fe12.lga>
Ken Tilton wrote:
>> Does execution of this SETF "hang" synchronously while the rest of X
>> updates propagate, or is the SETF request truly put into a queue, with
>> SETF returning and the actual change to Y happening "later"?
> 
> 
> I forget. You are supposed to write syntax to defer the change. I forget 
> if I throw an error if the syntax is omitted or just hang the outer setf 
> until the renegade inner setf completes. 

It is a BREAK, actually, which is not supposed to be handleable, tho it 
is in ACL. To do a SETF:

  (defobserver this-slot (self new old oldboundp)
     (with-integrity (:change)
         (setf (this-delta self) (if oldboundp (- new old) 0))))

kenny

-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
    Attorney for Mary Winkler, confessed killer of her
    minister husband, when asked if the couple had
    marital problems.
From: Vagif Verdi
Subject: Re: Novus, Booty, This One's For You
Date: 
Message-ID: <1149637946.510062.116020@i40g2000cwc.googlegroups.com>
I downloaded and run cells on Lispworks (windows). Works fine.

Ken Tilton wrote:
> The Cells library as it stands is all about doing interesting things
> with slots of CLOS instances.

I think this is misleading. Readers may think ANY CLOS, while in fact
you have to define CLOS instances using specific cellc macro.
You cannot do anything to CLOS classes defined using standart defclass.

Maybe i'm wrong. Maybe i missed somehting.
But then please, can you give us an example of how to "cellify"
existing CLOS classes.
Particularly I'm intrested in GUI framworks like Lispworks CAPI.
From: Ken Tilton
Subject: Re: Novus, Booty, This One's For You
Date: 
Message-ID: <hFrhg.331$n_4.45@fe08.lga>
Vagif Verdi wrote:
> I downloaded and run cells on Lispworks (windows). Works fine.
> 
> Ken Tilton wrote:
> 
>>The Cells library as it stands is all about doing interesting things
>>with slots of CLOS instances.
> 
> 
> I think this is misleading. Readers may think ANY CLOS, while in fact
> you have to define CLOS instances using specific cellc macro.
> You cannot do anything to CLOS classes defined using standart defclass.
> 
> Maybe i'm wrong. Maybe i missed somehting.

I am not sure, so I'll just tell you what I know. You can subclass an 
existing class (I think this is what you are asking) and turn any of its 
existing slots into Cells:

  (defmodel md-push-button (capi:push-button) ;; "md-" is short for model
    ((enabled :cell t ;; this happens to be the default
              :initarg :enabled ;; same
              :accessor push-button-enabled ;; same
              :initform t)))

...might work (see below). If so, you could then do:

     (make-instance 'md-push-button
         :text "Ok"
         :enabled (c? <code deciding if user input is satisfactory>))

below: It might not work if CAPI works by doing clever things (as it 
well should) with slot accessors. For example, perhaps in CAPI the GF 
(setf enabled) GF is where CAPI arranges for a button to be dimmed. if so...

Houston, we have a problem, but it can be solved by first understanding 
what the pure CLOS framework needs and staying out of its way. Or one 
can take the bull by the horns and handle button dimming with rules that 
watch the enabled slot, leaving relatively little work for CAPI.

But this last bit will not work if CAPi does not even expose button 
dimming to the user. If so, do what I did when similarly wrapping tcl/tk 
classes: have an observer talk to CAPI.

  (defmodel md-push-button (capi:push-button) ;; "md-" is short for model
    ((md-enabled :cell t ;; this happens to be the default
              :initarg :md-enabled
              :accessor md-push-button-enabled ;; different!
              :initform t)))

  (defobserver md-push-button-enabled (self new old old-boundp)
      (setf (push-button-enabled self) new))

Enough of that gets old, so with tcl/tk I wrote a DEFTK macro to write 
all the glue for me.

> But then please, can you give us an example of how to "cellify"
> existing CLOS classes.
> Particularly I'm intrested in GUI framworks like Lispworks CAPI.
> 

Hope the above helps. FWIW, I have in the past wrapped GUI frameworks 
from MCL, ACL, and Tcl/Tk. Vasilis Margioulas took my Tk wrapper and 
produced a Gtk wrapper, Cells-Gtk.

Finally, if by chance the CAPI thing was not an idle question, do 
yourself a favor and grab my Celtk project, a module alongside the Cells 
module in the Cells project CVS repository. Then you get portability 
(across Lisps) and more than just a GUI (threads, sockets, file 
management, also portably).

And then I have to make it work, not you. :) Which is OK because I am 
using it for commercial development and will be maintaining it anyway.

kenny

-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
    Attorney for Mary Winkler, confessed killer of her
    minister husband, when asked if the couple had
    marital problems.
From: Ken Tilton
Subject: Celtk and Gears on Lispworks
Date: 
Message-ID: <HeGhg.80$Nb7.9@fe12.lga>
Ken Tilton wrote:
> Finally, if by chance the CAPI thing was not an idle question, do 
> yourself a favor and grab my Celtk project, a module alongside the Cells 
> module in the Cells project CVS repository. Then you get portability 
> (across Lisps) and more than just a GUI (threads, sockets, file 
> management, also portably).
> 
> And then I have to make it work, not you. :) Which is OK because I am 
> using it for commercial development and will be maintaining it anyway.

I just re-tested Celtk (a) building via ASDF (I usually do not) and (b) 
on Lispworks (normally I use ACL), both on win32. I believe Frank 
regularly runs all this on the ACL/OS X platform.

See load.lisp in:

    http://common-lisp.net/cgi-bin/viewcvs.cgi/Celtk/?root=cells

You will also need:

    http://common-lisp.net/cgi-bin/viewcvs.cgi/cells/?root=cells

...and Tcl/Tk, CFFI, and for OpenGL cl-opengl and the Togl shared lib. 
Deets in the load.lisp mentioned above.

I would be happy to help with portability/build issues or hear of other 
platforms successfully running plain Celtk or Gears (Celtk + Togl).

kenny

-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
    Attorney for Mary Winkler, confessed killer of her
    minister husband, when asked if the couple had
    marital problems.
From: Frank Goenninger DG1SBG
Subject: Re: Celtk and Gears on Lispworks
Date: 
Message-ID: <m21wu0llnm.fsf@pcsde001.local>
Ken Tilton <·········@gmail.com> writes:

> Ken Tilton wrote:
> I just re-tested Celtk (a) building via ASDF (I usually do not) and
> (b) on Lispworks (normally I use ACL), both on win32. I believe Frank
> regularly runs all this on the ACL/OS X platform.

To all:

Yes, I do. Works. 

Oh, and my microcontroller (an AVR ATmega16) is sending to a Celtk
text widget. Via a Cells slot: Whenever data from the controller is 
present on the RS232C port (actually, a USB port with a converter) 
on my MacBook Pro the Cells slot gets assigned the new data from the 
port. Cells propagates this to a variety of depending Cells - a 
Voltmeter widget, a safety algorithm checking if any value is out
of legal bounds (which sets an alarm slot which propagates to ... 
some other Cells)... The text widget is a sort of debug window:

(defmodel debug-window (window)  ;; It's a window...
  ()
  (:default-initargs
      :kids (c? (the-kids
		   (mk-stack (:packing (c?pack-self))
 		     (mk-label :text "Receive / debug window"
			       :pady 10)
		     (mk-text-widget :id :debug-window
				     :md-value (c-in "")
				     :height 10
				     :width 80
				     :borderwidth 2
				     :relief 'sunken
				     :pady 5))
		   (mk-fileevent :id :psu-rc-port-event 
				 :read-fn 'USRF
			         :iostream (c-in
					     (open "/dev/cu.usbserial"
						  :direction :input)))))))


;; USRF: User Supplied Read Function -  see Tcl/Tk fileevent and fileevent.lisp
(defmethod USRF ((self tk-fileevent) &optional (operation :read))
  (declare (ignorable operation))
  (let ((stream (^iostream)))
    (let ((data (read-char stream nil nil nil)))
      (if data
	  (let* ((text (md-value (fm-other :debug-window)))
		 (new-text (conc$ text data)))
	    (setf (md-value (fm-other :debug-window)) new-text))
	 (funcall (^eof-fn) self)))))


Yeah, I am close to finishing an application where my homebrew High
Voltage Power Supply for my Ham Radio HF Amplifier is remote
controlled via a Cells-based application. It produces up to 4200 V at
2 A. That Cells-based safety stuff should better be working <g>

If only you could see that smile on my face - "Proud papa" feeling ;-)
That was hobby.

Next step: Interface between an Electronic CAD System and SAP
Product Lifecycle Management (PLM) instances for echanging metadata of
electronic control equipment. Product structure data conversion based
on Cells values -> Data content triggering data structure transformation.
This is business.

Have fun! 

Frank
From: Vagif Verdi
Subject: Re: Celtk and Gears on Lispworks
Date: 
Message-ID: <1149788066.729615.63500@y43g2000cwc.googlegroups.com>
Thank you ! That was exactly my question!
>From examples it was not clear that i can apply cells to existing CLOS
classes.
All your examples use newly created classes via defmethod.

I will check cells-tk. Although i'm reluctant, because I heard that Tk
does not look good on windows.
From: Ken Tilton
Subject: Re: Celtk and Gears on Lispworks
Date: 
Message-ID: <UN_hg.36$Nv7.10@fe12.lga>
Vagif Verdi wrote:
> Thank you ! That was exactly my question!
>>From examples it was not clear that i can apply cells to existing CLOS
> classes.

OK. As a matter of fact, back in the day when Cells were implemented 
using AMOP and a metaclass, I managed to create a new metaclass multiply 
inheriting from the Cells metaclass and the AllegroStore metaclass. Once 
change to the DB actually propagated thru the DB to other changes. Other 
fun and games, too, with the DB. This was a testament, I think, to how 
well Franz executed /their/ metaclass.


> All your examples use newly created classes via defmethod.

Good point.

> 
> I will check cells-tk. Although i'm reluctant, because I heard that Tk
> does not look good on windows.
> 

The Tile classes now seem to have been accepted as Official Tk. I hear 
they look a lot better.

kenneth

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Beaming husband to scowling life, New Yorker cartoon
From: marc spitzer
Subject: Re: Celtk and Gears on Lispworks
Date: 
Message-ID: <slrne8hava.h8g.ms4720@sdf.lonestar.org>
On 2006-06-08, Ken Tilton <·········@gmail.com> wrote:
>
> Vagif Verdi wrote:
>> 
>> I will check cells-tk. Although i'm reluctant, because I heard that Tk
>> does not look good on windows.
>> 
>
> The Tile classes now seem to have been accepted as Official Tk. I hear 
> they look a lot better.

The thing is that tk looks like motif, default unix gui look when it came out.

Also tk has an options database that allows you to tune how the system looks
for your app, here is a good place to start http://wiki.tcl.tk/1852.  Another
place to look is to google comp.lang.tcl for "look and feel" or ugly and there
are some good recipies there to make it look like windows.  

marc

>
> kenneth
>


-- 
······@sdf.lonestar.org
SDF Public Access UNIX System - http://sdf.lonestar.org
From: Alan Crowe
Subject: Re: Novus, Booty, This One's For You
Date: 
Message-ID: <86ac8q5bs2.fsf@cawtech.freeserve.co.uk>
Ken Tilton <·········@gmail.com> writes:

> Available as cells-manifesto.txt in:
> 
>      http://common-lisp.net/cgi-bin/viewcvs.cgi/cells/?root=cells
> 
> 
>                     Cells In A Nutshell
> 
> The Cells library as it stands is all about doing interesting things 
> with slots of CLOS instances. Nothing says a global variable could not 
> be mediated by a Cell, and indeed one Cells user is known to have 
> experimented with that. Also, some work was done on having slots of 
> DEFSTRUCTs mediated by Cells. But for the rest of this exposition let's 
> just talk about CLOS slots and instances.

Permit me to undertake some volunteer editing.

> The Cells library as it stands is all ...
                    ^^^^^^^^^^^^

This is implied by "In A Nutshell". It is The History Of
Cells that talks about Cells as it was. It is Future
Directions For Cells that abouts about how it will be.

> as it stands is all about doing interesting things ....
               ^^^^^^^^^^^^^^^^^^
                    does

> about doing interesting things with slots ....
              ^^^^^^^^^^^^^^^^^^

Your readers are aware that Cells does interesting
things. That is why they are reading Cells In A
Nutshell. But what kinds of interesting things? They have
turned to Cells In A Nutshell rather than Cells in Broad
Brush Strokes because they want to know. So don't keep them
waiting - say "manages dependencies"

> Nothing says a global variable could not be mediated by a
> Cell, and indeed one Cells user is known to have
> experimented with that.

Nutshell accounts don't digress into experimental
work. Leave it for Future Directions For Cells.

> Also, some work was done on having slots of DEFSTRUCTs
> mediated by Cells.

The reader of Cells In A Nutshell doesn't yet know about
Cells. What is he to make of this sentence? Should he stop
reading about Cells and wait a year for this work to come to
fruition? He has not yet got any context into which to place
this. In the context of Cells In A Nutshell this sentence
serve only as an obstacle for the unitiated to stumble over.

So far we have trimmed down the first paragraph to

    The Cells library manages dependencies amongst slots of
    CLOS instances.  But for the rest of this exposition
    let's just talk about CLOS slots and instances.

Obviously it can be trimmed further:

    The Cells library manages dependencies amongst slots of
    CLOS instances.

On to paragraph two.
> 
> The Cells library allows the programmer to specify at make-instance time 
> that a slot of an instance be mediated for the life of that instance by 
> one of:

The biggest problem is the use of the word `mediate'. It is
general word, so it says very little. Nevertheless I think
that it says enough to be a poor choice. Look at the dictionary
definition:

    mediate: form connecting link between

So can we say "A slot is mediated by a cell"? What does the
cell connect it to? 

"Mediate" is currently a fashionable word, used in the sense
that banks mediate between lenders and borrowers. When
companies sell corporate bonds directly to investors they are
disintermediating banks.

When readers get news directly from the websites of those
involved in the stories they are disintermediating
journalists. Notice that in current usage the bank does not
mediate amongs lenders, and the journalist does not mediate
between readers. 

If I'm understanding Cells correctly the connection are from
one CLOS slot to another. The word `mediate' suggests that
Cells connect CLOS slots to some other kind of entity.

Can one be much more specific and say that a Cell assigns a
value to a slot?

>     -- a so-called "input" Cell;
>     -- a "ruled" Cell; or
>     -- no Cell at all.

Here the author gets to create terminology. He could call
the two types of Cell, type 1 and type 2. That would be a
missed opportunity. Good choices here will make the rest of
the text much easier to follow.

Why a SO-CALLED "input" Cell? If that is not a good name,
chose a different one. If it is hard to chose a good name,
follow through on the `so-called' and indicate the nature of
the difficulty to the reader. Don't just leave it hanging as
something to puzzle the reader.

Is "ruled" a good name? It looks to me as though the
distinction is between "input" cells and "dependent" cells,
in the sense that code outside of the cells system assigns
values to the input cells which then propagate to the
dependent cells ultimately producing output beyond the cells
system by the mechanism of "observer callbacks".

I like the terms "exogenous" and "endogenous" instead of
"input" and "ruled". Before you mock me consider this:
writing that lives of the web sits before an international
audience. Whatever terms you chose, many of your readers
will not be native speakers and will use a dictionary in an
attempt to pick up the nuances that have commended a
particular nomenclature to its author. I suggest playing
along with this. Pick the most specific words that you can,
even if they are obscure. When your audience looks it up in
a dictionary there will be a specific translation that will
help them understand and not a long discussion of the many
possible, context dependent, meanings of a common word.

> To allow the emergent data animation model to operate usefully on the 
> world outside the model--if only to update the screen--programmers may 
> specify so-called observer callbacks dispatched according to: slot name,
> instance, new value, old value, and whether the old value actually 
> existed (false only on the first go).

This is great technical writing. I wish I could write this
well. To avoid misunderstanding let me spell out what I love
about it. I expect technical writing to be difficult to
read. I expect to fail to understand, to go away and make a
cup of tea, and to come back and labour at teasing out the
meaning.

The one thing I ask of technical writing is that thinking
harder about what the author has written and why he wrote it
should make things better rather than worse. For example,
when I bump into "mediate" and try thinking about it, I
remember that banks are said to mediate between lenders and
borrowers, but not amongst lenders. Thinking harder makes
things worse.

When I try thinking hard about "emergent data animation
model" I'm reminded of the previous paragraphs, with data
changing automagically and dependencies being discovered in
the course of evaluation. Suddenly I have a stylish phrase
that sums up the previous paragraphs as describing an
emergent data animation model. Thinking harder makes things
better.

Kenny puzzles over the slow take up of Cells. It is all the
more puzzling when one admires some of Kenny's stylishly
written documentation. Perhaps one part of the solution to
the puzzle is that Kenny has yet to find an editor robust
enough to stand up to him.

Alan Crowe
Edinburgh
Scotland
From: Ken Tilton
Subject: I forgot Al! [was Re: Novus, Booty, This One's For You]
Date: 
Message-ID: <LRmhg.79$Wd5.25@fe10.lga>
Alan Crowe wrote:

...way too much to make one joke, and a failed one at that, for a good 
joke must be true. Mediate? Lessee, a couple entries from the Google 
define: option:

# intercede: act between parties with a view to reconciling differences;

Aw, that's cute. They anticipated Cells: when the first slot changes, a 
difference arises, namely, the other slots are no longer consistent with 
the first slot. Cells reconciles them.

# occupy an intermediate or middle position or form a connecting link or 
stage between two others;

Man, they need to update from CVS. I used to have Cell instances 
actually sitting in the slot value, and a reader method literally had to 
go through the Cell to get to the functional value. But functionally 
they have it right, because reader methods indeed first look for a Cell 
that might be mediating the slot.

Well, hang on. The manidesto has not yet introduced "synapses". A 
synapse is (sort of) an anonymous Cell. It is spawned inside a rule and 
has exactly one dependent, the Cell defined by that rule. A synapse can 
have its own arbitrary rule and of course access any number of other 
cells. It can also have state, which will allow it to do things such as 
not fire if its body computes values close to prior values. It needs 
state to avoid being the frog in the frying pan -- after so many tiny 
changes, it may be time to propagate.

Talk about mediation!

Roget offers go-between for the noun mediator. You know, that is exactly 
why a Cell slot not mediated by a Cell in some instance cannot be 
changed. It has no go-between who would have been keeping track of 
interested dependent Cells, and it is too late to create one because the 
rules have come and gone unregistered.

> the puzzle is that Kenny has yet to find an editor robust
> enough to stand up to him.

Editing is always welcome, but the editor needs to know English better 
than you and should not be just trying to win a pissing contest.

> 
> Alan Crowe
> Edinburgh
> Scotland

So much for the "English is not his native language" theory. How's this? 
If you were not merely being boorish, you would have read what you were 
editing and known that mediate would be your Waterloo.

:)

kenny

ps. funny, the PyCells people like the doc. What is /wrong/ with you 
people?! :) k

-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
    Attorney for Mary Winkler, confessed killer of her
    minister husband, when asked if the couple had
    marital problems.
From: Ken Tilton
Subject: Al, you were right! [was Re: Novus, Booty, This One's For You]
Date: 
Message-ID: <uKFhg.41$AZ7.1@fe09.lga>
Actually, I was bluffing: I only skimmed your nonsense. Just noticed this:

Alan Crowe wrote:
> The biggest problem is the use of the word `mediate'. It is
> general word, so it says very little. Nevertheless I think
> that it says enough to be a poor choice. Look at the dictionary
> definition:
> 
>     mediate: form connecting link between

Oh, you did have the right connotation.

Well, the string "link" occurs thirty-five* times in the Cells source, 
twenty of those in link.lisp. The longer string "unlink" appears 18/14 
times. Connecting and disconnecting nodes in the dependency graph.

kenny

* All counts distorted I am sure by appearances in debug code.