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.
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.
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
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.
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.
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.
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.
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
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.
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
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
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.