From: Kenny Tilton
Subject: Cells for CormanLisp
Date: 
Message-ID: <3E766E8F.9030305@nyc.rr.com>
OK, CormanLisp 2.01 now has available patches to fix up the defstruct 
issues. A little fancy footwork on the Cells side and we have...

     Cells for CormanLisp (and ACL, LW, and CLisp):

       http://www.tilton-technology.com/cells_top.html

Same link, so reload page if the "new for..." graph does not mention 
CormanLisp.

One heads up: the :default-initargs option of defclass is effectively 
ignored by my CormanLisp 2.01 patched just with the two files to fix 
defstructs, clos.lisp and structures.lisp. I do not know if this is a 
problem introduced by the patches or if CormanLisp has always been like 
that. I did not hear from anyone on the Corman mailing list re this 
astonishing gap/bug, so I presume all CormanLispers are out celebrating 
St. Patrick's Day, as I will be shortly.

When I recover, I plan to start a little Cello tutorial project. A port 
to CMUCL will be running in parallel, and with luck Cello will cover 
win32 and X11 by the time the Cello doc is worth a damn.

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore

From: reini urban
Subject: Re: Cells for CormanLisp
Date: 
Message-ID: <3e776aa5$1@e-post.inode.at>
Kenny Tilton wrote:
> OK, CormanLisp 2.01 now has available patches to fix up the defstruct 
> issues. A little fancy footwork on the Cells side and we have...
> 
>     Cells for CormanLisp (and ACL, LW, and CLisp):
>       http://www.tilton-technology.com/cells_top.html

I still don't get it exactly. So in short:
Is it something like the garnet object-system, only on top of CLOS?

(I think it was called KR)
-- 
Reini Urban
http://xarch.tu-graz.ac.at/home/rurban/
From: Thomas F. Burdick
Subject: Re: Cells for CormanLisp
Date: 
Message-ID: <xcv4r60hz70.fsf@conquest.OCF.Berkeley.EDU>
reini urban <······@x-ray.at> writes:

> Kenny Tilton wrote:
> > OK, CormanLisp 2.01 now has available patches to fix up the defstruct 
> > issues. A little fancy footwork on the Cells side and we have...
> > 
> >     Cells for CormanLisp (and ACL, LW, and CLisp):
> >       http://www.tilton-technology.com/cells_top.html
> 
> I still don't get it exactly. So in short:
> Is it something like the garnet object-system, only on top of CLOS?
> 
> (I think it was called KR)

Like KR, it's a one-way constraints system.  Cells simply lets you
specify a formula to constrain the value of a slot of a
standard-object -- it doesn't have any of the other parts of KR,
though (which is not necessarily a bad thing).

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Kenny Tilton
Subject: Re: Cells for CormanLisp
Date: 
Message-ID: <f06747e2.0303182009.3d2b00fe@posting.google.com>
reini urban <······@x-ray.at> wrote in message news:<··········@e-post.inode.at>...
> Kenny Tilton wrote:
> > OK, CormanLisp 2.01 now has available patches to fix up the defstruct 
> > issues. A little fancy footwork on the Cells side and we have...
> > 
> >     Cells for CormanLisp (and ACL, LW, and CLisp):
> >       http://www.tilton-technology.com/cells_top.html
> 
> I still don't get it exactly. So in short:
> Is it something like the garnet object-system, only on top of CLOS?

Yes.

> 
> (I think it was called KR)

Disclaimer: I read a lot of the KR doc, never once used it, and I am a
lousy reader. Corrections welcome (if phrased pleasantly, Marc <g>).

From the KR manual: "In addition, the system supports a constraint
maintenance mechanism which allows any value to be computed from a
combination of other values."

Check. Scarily similar (even when one is accustomed to independent
discovery) on the face of it.

Cells have cleaner, more transparent syntax (sometimes none), and
Cells have more features such as varieties of Cells (normal,
ephemeral, delta, stream, and more as necessary to suit new
requirements) and Synapses (lotsa games can be played here) which
mediate dependencies.

KR has an on-change callback mechanism called demon invocation,
similar to the Cells echo mechanism, but again not as rich.

Here we are very close: "Formulas represent one-directional
connections between a dependent value and any number of depended
values. Formulas specify an expression which computes the dependent
value based upon the depended values, as well as a permanent
dependency ...."

Check, except dependencies in Cells are not permanent (and I wonder if
they /really/ are in KR or if that is a doc error). In Cells, if the
rule is:

  (if (a) (b) (c))

... the dependencies arising from only one of (b) or (c) are in place,
depending on the Lispian truth of (a). ie, dependencies are
dynamically (re)determined on each evaluation of the rule.

As for: "Formulas can contain arbitrary Lisp expressions, which
generally reference at least one particular depended value."

yep. Don't know about KR, but Cells are smart enough to optimize
themselves away if after any evaluation they are not dependent on
anything which might actually change. Saves a lot of time, that.

But now Cells and KR constraints deviate wildly: "Formulas are not
recomputed immediately when one of the depended values changes. This
reduces the amount of unnecessary computation."

A Cells application /works/ by cell-driven dataflow, so eager
evaluation is essential. And all the computation is necessary. That
said, if someone comes up with a requirement that /certain/ Cells not
be recomputed until accessed, we could do that, but I think in a case
like that, just don't use Cells.

The problem with lazy evaluation is this. If A depends on B which
depends on C and C changes, KR doc says B gets marked as invalid. What
about A? That's invalid, too. Now an example in the doc suggests KR
does know that, so... while KR is running all over the dependency
graph merely marking things as invalid, all of which will get
recomputed when something far away dependency-wise gets read, in the
meantime Cells is simply recalculating stuff and "making it so". If a
recalculation produces the same value as the cache, no further
propagation takes place. But lazy evaluation cannot determine that, in
the case above, the change to C would not produce a change to B absent
the recalculation of B, so it must continue along the dependency graph
erroneously and inefficiently marking stuff as invalid. That's what I
call unnecessary computation.

"Moreover, formulas are not recomputed every time their value is
accessed. Each formula, instead, keeps a cache of the last value it
computed. Unless the formula is marked invalid, and thus needs to be
recomputed, the cached value is simply reused."

Same with Cells.

"This factor causes a dramatic improvement in the performance of the
constraint maintenance system, since under ordinary circumstances the
rate of change is low and most changes are local in nature."

Which is why eager evaluation is so efficient. :)

Another difference: "Constraints may involve circular chains of
dependency."

They say they use the cached value when calculating A requires A. I
wonder what they use on the first calculation? Probably nil or 42. The
Cells system would prefer the programmer figure out what the hell they
mean. :)

Another difference: "It is possible for a dependency path to become
temporarily unavailable. This would happen, for instance, if schema
POINT-1 in Figure 5-1 was deleted..[snip]. KR handles such situations
automatically. If a formula needs to be evaluated but one of its
dependency paths is broken, the current cached value of the formula is
simply reused. This makes it completely safe to modify schemata that
happen to be involved in a dependency path, since the system
handles the situation gracefully."

You say "gracefully", we say "erroneously". The world has changed, the
cached value is not good enough. With cells the schemata is itself
cell-based. If the schema is going to change, the parent slot for its
children is mediated by a cell. (Cells internals arbitrarily enforce
this.) Any other cell that accesses that slot gets recalculated as the
schema changes. This is huge, btw, having the /population/ of the
model determined by a cell on which other state can depend, and having
the population depend on other state.

To me the lazy/eager thing is decisive. Without eager evaluation, the
programmer still has their hands on the controls. The paradigm shift
(to a dataflow model) does not occur. It took me a while to get used
to it, but early on in the development of Cells I realized I would
have to "let go" and commit to the declarative model: write the rules
then let 'er rip.

This felt reckless, but then again I think the power of the
declarative model is well-understood. Looked at another way, if we are
going to find a significantly more productive way of programming,
mustn't it involve relieving the programmer of some onerous
responsibility?

I get into this in the doc at the link below: Simple, linear
constraints combined with eager evaluation make our models run by
themselves, according to the rules we set. Cells effectively endow
state change with causal power over other state. They provide
automatic animation of models. Without Cells and esp. eager
evaluation, we programmers are puppeteers hand-animating the dataflow
required by any interesting model. That's a lot of work, hard even to
get right. I never realized how much work it was until I started using
Cells.

Again, KR veterans please weigh in with corrections.

-- 

 kenny tilton
 clinisys, inc
 http://www.tilton-technology.com/
 ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
 the bath water is cold." -- Lorraine Lee Cudmore
From: Fred Gilham
Subject: Re: Cells for CormanLisp
Date: 
Message-ID: <u7he9z5ipt.fsf@snapdragon.csl.sri.com>
Kenny Tilton writes (at the very end):
> Again, KR veterans please weigh in with corrections.

I guess "veteran" is true of me.  If you had said "expert" I would
have had to beg off. :-)

Cells sounds (sound?) interesting.  Because of your emphasis on
portability it has the potential to become a de-facto standard.
Because it's based on CLOS, I think people will be more comfortable
with it than with Garnet.  I should say, though, that I really like
the prototype-instance object model for GUI stuff, but that's just me
I suppose.

> Check, except dependencies in Cells are not permanent (and I wonder
> if they /really/ are in KR or if that is a doc error).

The dependency can actually change as the system runs.  KR is pretty
flexible, allowing you to remove slots from schemas dynamically,
automatically handling the effects on the dependency graph of doing
that.  You can create a new schema that inherits from another schema
and adds slots dynamically as well (though it doesn't look like you
can modify a particular schema to add slots).

> yep. Don't know about KR, but Cells are smart enough to optimize
> themselves away if after any evaluation they are not dependent on
> anything which might actually change. Saves a lot of time, that.

KR has a similar feature called "constant formulas" (section 8.5 in
the Garnet docs.)  It allows the user to declare that a slot is
constant.  If a formula depends only on constant slots, it will be
optimized away as you describe.  Note that this happens at run time.

Slots can also become constant by inference, which will allow the
system to automatically determine that formulas are unneeded even when
the slot wasn't declared constant.

> But now Cells and KR constraints deviate wildly: "Formulas are not
> recomputed immediately when one of the depended values changes. This
> reduces the amount of unnecessary computation."
> 
> A Cells application /works/ by cell-driven dataflow, so eager
> evaluation is essential. And all the computation is necessary. That
> said, if someone comes up with a requirement that /certain/ Cells
> not be recomputed until accessed, we could do that, but I think in a
> case like that, just don't use Cells.

I wouldn't be surprised if, as you claim, the approach Cells takes is
more efficient at least part of the time.  On the other hand, I
suspect the reverse will be true as well.  I guess the problem that
could arise is that repeated changes to a particular slot (Cell) would
cause repeated evaluations with Cells, while that wouldn't happen with
KR.  If the evaluation was expensive you could waste a lot of work.
But I'm sure you know the tradeoff already.

You do short-circuit the process if the computed value doesn't change,
but I wonder how often the short-circuiting would happen.  Do you have
any way of instrumenting things to see how effective the various
strategies are?

> They say they use the cached value when calculating A requires A. I
> wonder what they use on the first calculation? Probably nil or
> 42. The Cells system would prefer the programmer figure out what the
> hell they mean. :)

If you intend a circular dependency, you just supply an initial value
for at least one of the slots in the dependency cycle.  It's actually
a nice technique to have available.  Maybe this would fit in with your
eager model as it stands, since you short-circuit recalculation once a
value doesn't change.  On the other hand, I guess I'm assuming that
you'll always hit some kind of fixpoint; probably that's not the case.

> Another difference: "It is possible for a dependency path to become
> temporarily unavailable. This would happen, for instance, if schema
> POINT-1 in Figure 5-1 was deleted..[snip]. KR handles such
> situations automatically. If a formula needs to be evaluated but one
> of its dependency paths is broken, the current cached value of the
> formula is simply reused. This makes it completely safe to modify
> schemata that happen to be involved in a dependency path, since the
> system handles the situation gracefully."
> 
> You say "gracefully", we say "erroneously". The world has changed,
> the cached value is not good enough. With cells the schemata is
> itself cell-based. If the schema is going to change, the parent slot
> for its children is mediated by a cell. (Cells internals arbitrarily
> enforce this.) Any other cell that accesses that slot gets
> recalculated as the schema changes. This is huge, btw, having the
> /population/ of the model determined by a cell on which other state
> can depend, and having the population depend on other state.
> 
> To me the lazy/eager thing is decisive. Without eager evaluation,
> the programmer still has their hands on the controls. The paradigm
> shift (to a dataflow model) does not occur. It took me a while to
> get used to it, but early on in the development of Cells I realized
> I would have to "let go" and commit to the declarative model: write
> the rules then let 'er rip.
> 
> This felt reckless, but then again I think the power of the
> declarative model is well-understood. Looked at another way, if we
> are going to find a significantly more productive way of
> programming, mustn't it involve relieving the programmer of some
> onerous responsibility?

The above sounds pretty compelling to me.  When Cells becomes
(become?) available for CLX/CMUCL, I'll be one of the first to try it
out.

-- 
Fred Gilham                                         ······@csl.sri.com
When an economist criticizes any human institution because it has
failed to convey to mankind an incommunicable attribute of God, we can
safely dismiss that economist. The trouble is, there remains a market
for these economists in academia. I regard this fact as one more piece
of evidence for the failure of tax-subsidized education. -- Gary North
From: Kenny Tilton
Subject: Re: Cells for CormanLisp
Date: 
Message-ID: <3E78D29D.8030601@nyc.rr.com>
Fred Gilham wrote:
> Kenny Tilton writes (at the very end):
> Cells sounds (sound?) interesting.  Because of your emphasis on
> portability it has the potential to become a de-facto standard.
> Because it's based on CLOS, I think people will be more comfortable
> with it than with Garnet.  I should say, though, that I really like
> the prototype-instance object model for GUI stuff, but that's just me
> I suppose.

I think I like prototyping, too, tho I have never used it. Sounds like 
it makes it possible to handle custom situations without forever making 
new classes--one just keeps sculpting away at the object to make new ones.

> KR has a similar feature called "constant formulas" (section 8.5 in
> the Garnet docs.)

whoa, glad I said I was a bad reader. i missed that whole section this 
time thru, tho i had read it years ago. maybe it is a good thing i 
missed it this time, i would have written twice as much.

having read it I do see many more similarities, and one big difference: 
KR is just jam-packed with backdoors that let the user subvert the 
constraints mechanism.

Cells is the complete opposite, the philosophy being that the 
productivity benefit comes from living within the system so the system 
can manage everything. One /really/ does not want to fly an F-16 without 
computer assist.

When I cannot do what I need to do in Cells, i extend the mechanism. In 
practice, half of these hacks have been backed out when I realized the 
problems they solved were solvable with vanilla Cells.

> I guess the problem that
> could arise is that repeated changes to a particular slot (Cell) would
> cause repeated evaluations with Cells, while that wouldn't happen with
> KR.  If the evaluation was expensive you could waste a lot of work.
> But I'm sure you know the tradeoff already.

Yes. Hey, let's wait for a good example to come along. I think better in 
concrete. I have trouble imagining a situation in which state has 
changed and i do not want it manifested outside the model. If we are 
talking about a flood of input which needs only periodic inspection, 
Synapses can handle that by mediating a specific dependency.

Synapses are filters between a cell and a value on which it depends. 
These filters can transform the value (perhaps yielding the delta since 
the last sampling instead of the absolute value) and/or suppress 
re-calculation ("dear used value: don't bother me until you have changed 
by 5%, or five minutes have gone by, which ever comes first. tia.")

Finally, I could add lazy Cells pretty easily, the plumbing is all there.

> 
> You do short-circuit the process if the computed value doesn't change,
> but I wonder how often the short-circuiting would happen.  Do you have
> any way of instrumenting things to see how effective the various
> strategies are?

Short-circuiting is pretty common when it comes to GUI layout. Yes, I 
have done up ad hoc metrics to count such things. And there is a general 
counting utility I use which lets me spot overactive Cells. There is a 
lot of room here for diagnostics.

I also think Cells will provide a decent objective measure of an 
application's complexity (after it is developed, unfortunately). Just 
lexically count the models, the rules, the dataflow inputs (c-variables) 
and the echos. maybe look at the runtime dependency graph as well. I bet 
that correlates well with development cost.


> If you intend a circular dependency, you just supply an initial value
> for at least one of the slots in the dependency cycle.

oh, Cells have something like that. I call them Drifters... they start 
with an initial value and then /change/ according to some rule; the rule 
result is taken to be a delta, not the new value.

>  It's actually
> a nice technique to have available.  Maybe this would fit in with your
> eager model as it stands, since you short-circuit recalculation once a
> value doesn't change. 

I do handle circularity in data propagation vs calculation. A and B can 
both be dataflow inputs, and their echos can setf each other (this would 
normally be a multi-way constraint, which I try to avoid as it seems to 
have been a tar pit for the constraints crowd). But if A sets B, when B 
goes to set A it sees the circularity and stops.

This is how a scroll thumb widget can scroll a page and a scrolling page 
canmove a scroll thumb. I hate this circular setf stuff and plan someday 
RSN to work out a SeeSaw mechanism for two Cells so they can just 
declare rules which are circular (and yeah, we'll have to start 
someplace such as zero or nil.

> The above sounds pretty compelling to me.  When Cells becomes
> (become?) available for CLX/CMUCL, I'll be one of the first to try it
> out.

Watch this space. :) Cells (just the dataflow, not the GUI which I call 
"Cello") breaks even the new PCL. Gerd Moellmann has fixed that for a 
future release, but made the source available. Thomas Burdick is helping 
me out on this, and at some point soon there should exist binaries that 
include Gerd's latest as well as Thomas's brainstorm: a CMUCL callback 
mechanism suitable for C libraries such as GLUT. Then comes Cello for 
CMUCL and X11.

Meanwhile I actually have started today on a Cello tutorial, and with luck
I can get enough done by the time CMUCL comes on line that we can release a
primodial Cello+tutorial for win32 (ACL and LW) and X11 (CMUCL first, 
then MCL).

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Alan Baljeu
Subject: Re: Cells for CormanLisp
Date: 
Message-ID: <gfsea.4278$lQ4.926973@news20.bellglobal.com>
> > I guess the problem that
> > could arise is that repeated changes to a particular slot (Cell) would
> > cause repeated evaluations with Cells, while that wouldn't happen with
> > KR.  If the evaluation was expensive you could waste a lot of work.
> > But I'm sure you know the tradeoff already.
>
> Yes. Hey, let's wait for a good example to come along. I think better in
> concrete. I have trouble imagining a situation in which state has
> changed and i do not want it manifested outside the model. If we are
> talking about a flood of input which needs only periodic inspection,
> Synapses can handle that by mediating a specific dependency.
>
Apologies if I get the notation wrong.

Semi-concrete:
(defparameter *s2* (to-be (make-instance 'sheet
                            :a1 (cv 2)
                            :a2 (c? (f (a1 self)))
                            :a3 (c? (slow-computation (a2 self)))

Now loop incrementing a1 until (> (a2 self) 11).  In this case, you hope
a3 doesn't recompute every time a1 changes.

Second reason:
(defparameter *s3* (to-be (make-instance 'sheet
                            :a1 (cv 2)
                            :a2 (cv 3)
                            :a3 (c? (slow-computation2 (a2 self) (a1 self)))

Suppose you decide to change a1 and a2.  Or suppose instead of a3 you have
a large network of dependencies on a1 and a2, and you want to change a1 and
a2.  It would be good if you put this on hold.

What would be good in such cases is to have a
(delayed-update (change a1) (change a2)) form.  However, if
1. b depends on a,
2. c depends on b, d,
3. You change a and d.
then you hope the update process updates b first and then c, rather than
c first then b, because c would need re-refreshing.

On the other hand, you want the update mechanism to be efficient, so there's
a trade-off.

I also don't know KR, but lazy update can be equally as accurate as eager
if every cell reference forces the values to be updated.  The pain comes
when you have to go around to every cell manually and say "please
update".  It would be better if the cell came to you and told you a
refresh is needed.  I suppose Cells does that.

Alan
From: Kenny Tilton
Subject: Re: Cells for CormanLisp
Date: 
Message-ID: <3E7AB2C9.6030507@nyc.rr.com>
Alan Baljeu wrote:
> Semi-concrete:

zero concrete! what is A1? A2? A3? The slow computation?

> (defparameter *s2* (to-be (make-instance 'sheet
>                             :a1 (cv 2)
>                             :a2 (c? (f (a1 self)))
>                             :a3 (c? (slow-computation (a2 self)))
> 
> Now loop incrementing a1 until (> (a1 self) 11).
>  In this case, you hope
> a3 doesn't recompute every time a1 changes.

Why not? A1 has changed, A2 has changed. If A3 does not recompute,
A3 is now out of whack with the model. It holds a logically inconsistent 
value. That's a bug, unless there is a concrete example which can go 
un-recomputed because of some concrete real quality.

If you say, well, A1 is a flood of inputs coming in a FireWire 
connection, and A3 only needs to be checked when A2 has changed by a 
certain percentage, then we have something to talk about. And we
would say, place a synapse on the dependency on A2:

    :a3 (c? (slow-computation (^a2 self (fsensitivity 0.05))))

The effect is that the formula does not get kicked off until A2 has
changed by 5%. Or if A3 does not need to be calculated until the user 
asks to see the current status, then we just write the rule accordingly

    :a3 (c? (if (eql (request user) :refresh)
                 (slow-compute (a2 self))
                .cache.))

That alone would make things hum because even tho A2 is changing wildly, 
the rule quickly determines (request user) is null and then returns the 
.cache. Alternatively, there /is/ a without-dependency macro to suppress 
unwanted recalculations:

    :a3 (c? (if (eql (request user) :refresh)
                 (slow-compute (without-dependency (a2 self)))
                .cache.))


> 
> Second reason:
> (defparameter *s3* (to-be (make-instance 'sheet
>                             :a1 (cv 2)
>                             :a2 (cv 3)
>                             :a3 (c? (slow-computation2 (a2 self) (a1 self)))
> 
> Suppose you decide to change a1 and a2.  Or suppose instead of a3 you have
> a large network of dependencies on a1 and a2, and you want to change a1 and
> a2.  It would be good if you put this on hold.

Background: I am all for speed. I noticed once that most things to be 
documented about cells have to do with performance optimizations -- all 
explanations lead to speed. I have solved a lot of over-calculation 
problems several different ways with cells, but I have never had to put 
the eager-evaluation model or any part of it on hold.

Cells help manage complexity. If I have just one situation where they 
are a bottleneck and Synapses won't help and other tricks I have used 
won't help and I cannot think of a new trick to help, hey, don't use 
Cells right here. Like any hairy optimization, it's not a problem if you 
just have to do it in one nasty little corner of the algorithm. 
Complexity does not explode when I optimize one intractable 
computational overload.

> 
> What would be good in such cases is to have a
> (delayed-update (change a1) (change a2)) form.  However, if
> 1. b depends on a,
> 2. c depends on b, d,
> 3. You change a and d.
> then you hope the update process updates b first and then c, rather than
> c first then b, because c would need re-refreshing.

I had to address that anyway, because you could have:

b depends on a
c depends on b and a

if a changes and c gets calculated first, it would use an obsolete value 
of b to compute a value inconsistent with the facts, and perhaps launch 
an ICBM before the next phase in which b finally gets recalculated and c 
gets recalculated a second time (correctly, but too late to recall the 
missile).

> 
> On the other hand, you want the update mechanism to be efficient, so there's
> a trade-off.
> 
> I also don't know KR, but lazy update can be equally as accurate as eager
> if every cell reference forces the values to be updated.

In the dataflow model, the inputs drive the application. That is how 
things happen. The model you describe is the traditional 
programmer-driven model, where programmers are at the controls. We get a 
mouseclick and then start running all over the place (in our logic) 
trying to make the right things happen in the right order. we usually 
forget something.

cells makes you stop and think about how to set up (declare) a model 
which will work by itself via dataflow. that's a lot of fun, by the way, 
and, once you work it out, everything Just Works (as early cell users 
marveled (until we got used to it)) .

>  The pain comes
> when you have to go around to every cell manually and say "please
> update".  It would be better if the cell came to you and told you a
> refresh is needed.  I suppose Cells does that.

right. KR came close to getting this right, but in the end they panicked 
and did not force the developer to live within a natural dataflow model. 
They provided endless opportunities for me to write code which 
discontinuously fucked with my models.

Why? Because they responsed poorly to problems with a purer form of 
constraints. Instead of keeping the declarative model pure, they elected 
to punt and throw the burden back on the poor programmer: "Here, we'll 
let you change the formula of a slot on the fly, we cannot think of any 
other way out of this bind." programmers soon enough resumed manual 
control of the application and wrote procedural, imperative code which 
dynamically tweaked the reality of their models -- which they still 
thought ran automatically.

Hey, it's probably easiest to just watch me develop an object inspector 
and see if one likes cells/cello.


-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Thomas F. Burdick
Subject: Cells and KR (was: Cells for CormanLisp)
Date: 
Message-ID: <xcvllz87cqt.fsf_-_@famine.OCF.Berkeley.EDU>
Kenny Tilton <·······@nyc.rr.com> writes:

> If you say, well, A1 is a flood of inputs coming in a FireWire 
> connection, and A3 only needs to be checked when A2 has changed by a 
> certain percentage, then we have something to talk about. And we
> would say, place a synapse on the dependency on A2:

  [snip]

It sounds like Synapses essentially let you get carefully-controlled
delayed evaluation, which is probably good enough in practice.  With
KR, you pretty much know when you're depending on the lazy evaluation,
so I don't think this would be different there.  On the flip side, you
sometimes unnecessarily check a value in order to force evaluation, so
it sounds like Cells just inverts this.  Again, in practice, I think
most cells/formulas (>= 90%?) would work correctly under both models.

> right. KR came close to getting this right, but in the end they panicked 
> and did not force the developer to live within a natural dataflow model. 
> They provided endless opportunities for me to write code which 
> discontinuously fucked with my models.
> 
> Why? Because they responsed poorly to problems with a purer form of 
> constraints. Instead of keeping the declarative model pure, they elected 
> to punt and throw the burden back on the poor programmer: "Here, we'll 
> let you change the formula of a slot on the fly, we cannot think of any 
> other way out of this bind." programmers soon enough resumed manual 
> control of the application and wrote procedural, imperative code which 
> dynamically tweaked the reality of their models -- which they still 
> thought ran automatically.

Well.  It sounds like you also provide endless opportunities to
unnecessarily delay computation.  Providing tools is different than
creating an environment where they need to be used.  In my own code, I
found programming with KR (both Garnet and non-Garnet code) to be very
declarative.  Within the KR-managed parts of the code, there were
little bits of imperative code that were mostly used to setup initial
state, or to construct the declarative world -- essentially to
bootstrap the declarative part of the program.  IMO, it would raise a
zillion bad-style flags if KR code looked super-imperative.

I'm sure that the designers of KR made an intentional choice to use
lazy evaluation, which might have been along the lines you're
theorizing, or maybe it was for entirely different reasons.  It was
originally developed for non-Garnet-related Knowledge Representation,
and I would imagine that there might be more discussion of *why* KR
does things the way it does, in some of the papers cited in the Garnet
docs.  Unfortunately, I've never tracked down a copy of any of those.
In case anyone has a copy they want to send me ;) or, has something to
say on the matter, the papers I mean are:

    Dario Giuse.  KR: an Efficient Knowledge Representation System.
    Technical Report CMU-RI-TR-87-23, Carnegie Mellon University
    Robotics Institute, October, 1987.

    Dario Giuse.  KR: Constraint-Based Knowledge Representation.
    Technical Report CMU-CS-89-142, Carnegie Mellon University
    Computer Science Department, April, 1989.

    Giuse, D.A.  Efficient Knowledge Representation Systems.
    Knowledge Engineering Review 5(1):35-50, 1990.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Kenny Tilton
Subject: Re: Cells and KR (was: Cells for CormanLisp)
Date: 
Message-ID: <3E7B9AC8.2070605@nyc.rr.com>
Thomas F. Burdick wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
> 
> 
>>If you say, well, A1 is a flood of inputs coming in a FireWire 
>>connection, and A3 only needs to be checked when A2 has changed by a 
>>certain percentage, then we have something to talk about. And we
>>would say, place a synapse on the dependency on A2:
> 
> 
>   [snip]
> 
> It sounds like Synapses essentially let you get carefully-controlled
> delayed evaluation, which is probably good enough in practice.

Yeah, and I forgot to mention that Synapses can be programmed with any 
logic one likes, so the determination of whether to trigger reevaluation 
can be made on any basis one likes. This is in contrast with Cells, 
which come in a few predetermined variets. (One direction Cells could 
take would be to carve out an interface to the Cell engine so users 
could define new kinds of Cells.)


>  With
> KR, you pretty much know when you're depending on the lazy evaluation,
> so I don't think this would be different there.  On the flip side, you
> sometimes unnecessarily check a value in order to force evaluation, ...

yecch. As soon as we stumbled onto cells we knew we had a winner. But 
the win was productivity, so I have a policy of rejecting any "fix" or 
feature in which the user has to think about the internals. Or at least 
that is a design goal, we'll see how successful I have been if others 
oblivious to the internals start using Cells.

One good example was deleting a character at the end of a line. In two 
separate and independent development efforts (of mini text editors) the 
same bug arose: the programmer first truncated the text, then moved the 
cursor back one. So the app crashed when some code went out of range 
trying to process the old cursor (at the end of the text when backspace 
was hit). I realized I could avoid the problem by first moving the 
cursor left one and then deleting the last character, but then I 
pictured FAQs on comp.constraints.cells where the answer was "you have 
to think about the order in which you change the program state, or hit 
it over the head and use (with-one-propagation ...)".

yecch, end of productivity win. this is supposed to be a declarative 
programming model, now I am compensating in my code for constraint 
engine internals issues.

in this case I trapped the runtime error and put the cell which failed 
because the cursor was outside the text (probably the cell deciding the 
cursor's new position) into a "pending" state. pending meaning "I hope 
the next imperative statement or two changes some other state so I can 
compute myself without error." as long as no one tried to use the 
pending value before a curing state change came to pass, no runtime 
error resulted.

That code is gone, I think, but could be resurrected. Pretty sure I just 
learned to program with Cells a little better and managed to code so 
that kind timing bind did not arise.

> Well.  It sounds like you also provide endless opportunities to
> unnecessarily delay computation.  Providing tools is different than
> creating an environment where they need to be used.

Touche. I /was/ wondering as I wrote how often KR veterans actually 
availed themselves of the myriad backdoors. Sounds like you eschewed 
those. If so, was that because you were simply never tempted (ie, yer a 
natural), or because you resisted occasional temptation deliberately to 
protect the declarative purity (for its productivity advantage)? Other?

BTW, without pretending I do not have an epee tip lodged in my side, I 
would like to point out that Synapses are still declarative and nicely 
encapsulated and that there is nothing semantically discontinuous about 
them. They simply offer one more rule which runs when the dataflow 
engine says it should run, offering the programmer a chance to optimize 
model performance by working within the system, not by defeating the system.

Gosubs got tossed because, well, there's a line between 
within-the-system and without, and they crossed it. And I got to delete 
code.

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Thomas F. Burdick
Subject: Re: Cells and KR (was: Cells for CormanLisp)
Date: 
Message-ID: <xcv7kaqkbrv.fsf@famine.OCF.Berkeley.EDU>
Kenny Tilton <·······@nyc.rr.com> writes:

> Thomas F. Burdick wrote:
>
> > Well.  It sounds like you also provide endless opportunities to
> > unnecessarily delay computation.  Providing tools is different than
> > creating an environment where they need to be used.
> 
> Touche. I /was/ wondering as I wrote how often KR veterans actually 
> availed themselves of the myriad backdoors. Sounds like you eschewed 
> those. If so, was that because you were simply never tempted (ie, yer a 
> natural), or because you resisted occasional temptation deliberately to 
> protect the declarative purity (for its productivity advantage)? Other?

Well, I made an effort to do KR programming on its own terms, and not
mess with the internals of the constraints system.  After that effort,
it was pretty natural to just do things declaratively, which I think
mostly a testament to KR.  As you already said in a later message, you
noticed the "not for most users" note at the top of this section in
the documentation.  Having thought about it, I think I like the idea
of eager-evaluation+Synapses better than the way KR managed the same
problems, but KR's model is pretty nice and easily useable nonetheless.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Kenny Tilton
Subject: Re: Cells and KR (was: Cells for CormanLisp)
Date: 
Message-ID: <3E7BBD9F.4020909@nyc.rr.com>
kenny tilton wrote:
>>right. KR came close to getting this right, but in the end they panicked 
>>and did not force the developer to live within a natural dataflow model. 
>>They provided endless opportunities for me to write code which 
>>discontinuously fucked with my models.

uh-oh. Just found a disclaimer at the beginning of the chapter offering 
those endless opportunities:

"This section describes features of KR that are seldom needed by casual 
Garnet users. These features are useful for large application programs, 
especially ones which manipulate constraints directly, or for
application programs which use the more advanced knowledge 
representation features of KR."

Never mind. :)

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Joerg Hoehle
Subject: Cells&Cycles (Was: Cells for CormanLisp)
Date: 
Message-ID: <ubrzwu97g.fsf_-_@dont.t-systems.UCE.spam.no.com>
Kenny Tilton <·······@nyc.rr.com> writes:
> I do handle circularity in data propagation vs calculation. A and B can 
> both be dataflow inputs, and their echos can setf each other (this would 
> normally be a multi-way constraint, which I try to avoid as it seems to 
> have been a tar pit for the constraints crowd). But if A sets B, when B 
> goes to set A it sees the circularity and stops.

Even if the new value is (sligthly) different?
- beware of oscillating systems!

> This is how a scroll thumb widget can scroll a page and a scrolling page 
> canmove a scroll thumb. I hate this circular setf stuff and plan someday 
> RSN to work out a SeeSaw mechanism for two Cells so they can just 
> declare rules which are circular (and yeah, we'll have to start 
> someplace such as zero or nil.

When I looked into GUI programming a decade ago, I remember a nice demo:
Something like a volume control with two ways of setting it:
 - a proportional slider with a knob
 - a digital input where you could type the number (0-100)
Modifying with mouse or keyboard changed the other's display.
I believe this requires cycles in the dependency graph, if it were
done via cells.

It would be nice if one of your papers would include an example similar
to this. So far, I found nothing which looked like this (the .pdf
from 2001 are very loosely structured, so it seems to me). BTW, 2.5
and 2.6 of the hello-world.pdf seem identical: "dataflow change direction".


Here's an example of a two-iteration, but non-oscillating system:
Suppose the propotional slider has internal resolution 0-65535. Even
though you cannot actually use that resolution via the GUI, suppose
your mouse movements sets it to 32970. The digital display must then
update itself to 50(%).  Then the system may conclude: "the digital
display was changed to 50(%), so let's put the proportional slider at
32768".  Good?  Wrong?  Bad?

For some systems this may be a resonable thing to do. It depends on
the application.  For a GUI, I don't like sliders moving slightly away
from where I put them with the mouse, unless there's a compelling
reason to do so (e.g. the slider actually has only two positions,
e.g. for showing a 2-9-page document page by page: it can then exihit
jumping instead of sliding behaviour).
MS-Windows application's GUIs tend to behave badly.

In this particular example (volume or gain control), I believe it's
acceptable for the slider to provide higher resolution that the 0-100
keyboard input. As a consequence, the slider must not be set to 32768
and keep the position corresponding to 32970 (~50,3%).

For another application, e.g. choosing a number from 1-10, a jumping
scrollbar with values limited to 0, 656, ..., 65535 may be the right
choice instead.

Regards,
	Jorg Hohle
Telekom/T-Systems Technology Center
From: Kenny Tilton
Subject: Re: Cells&Cycles (Was: Cells for CormanLisp)
Date: 
Message-ID: <3E834392.8010605@nyc.rr.com>
Joerg Hoehle wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
> 
>>But if A sets B, when B 
>>goes to set A it sees the circularity and stops.
> 
> 
> Even if the new value is (sligthly) different?

yep. mind you, this hack simply supports a couple of (what i call) 
see-saw dependencies, where I know that only one value is driving the 
other /at any one point in the user interaction/. hmm, maybe see-saw is 
not such a good metaphor. :)

a falling stone is a tougher case. the distance is one-half acceleration 
times the square of the time, and the acceleration increases as the 
distance fallen increases, so it occured to me at one point that we 
could take a model like this and just let it run with one change 
triggering another: oh, time has changed, my position has changed, the 
gravitational pull has changed, i should recompute the distance--hang 
on, time is supposed to be driving this model, now we are about to start 
running, well, naturally, as the effect of each cause becomes a cause 
itself of some new effect.

we would not need to have a global time variable to cause things to 
happen. of course the model would run slower the more stuff there was 
changing, because there would be more work to do with more 
interdependencies. i conclude this is why gravity slows time. :)


> When I looked into GUI programming a decade ago, I remember a nice demo:
> Something like a volume control with two ways of setting it:
>  - a proportional slider with a knob
>  - a digital input where you could type the number (0-100)
> Modifying with mouse or keyboard changed the other's display.
> I believe this requires cycles in the dependency graph, if it were
> done via cells.

the circularity can be avoided at a price. the trick is to have the 
controls operate directly on some "volume" vector, then have their 
appearance be dependent on the "volume" vector. ie, the mouse does not 
really move the slider, it changes the volume which the slider is 
watching for its position.

the price is that one is then not using cells to their fullest, and it 
can cause a visible lag in how tightly the slider follows the mouse 
because of the delay in propagating the change thru the volume and back 
to the slider's position.

anyway, the cyclic setf hack works for this, unless they are typing and 
using the mouse at the same time. (just kidding, it would still work.) 
but i do want to extend cells someday to handle better these simple 
binary cycles.

> 
> It would be nice if one of your papers would include an example similar
> to this.

will do. and maybe i will make the enhancement i have in mind before 
doing so--why document a kludge one is about to fix?

> So far, I found nothing which looked like this (the .pdf
> from 2001 are very loosely structured, so it seems to me).

you are a very nice person. those old docs are garbage, as my web page 
proudly states.

i am working on some new doc now. i am developing a graphical CLOS (and 
other) object inspector incrementally, just as I would anyway. when I 
hit a Cell-related problem, I am documenting that and explaining the 
workaround. i call it reality documentation.

one very cool thing here is that Cells went upside my head in a way they 
never have before, which is not easy to do after all these years of 
intensive use. this is like George Willig falling for real when a 
sandstone hold broke off on a "show" climb for Wide World of Sports 
during his fifteen minutes of fame after climbing the WTC. Jim McKay had 
a cow. I hope the doc readers enjoy my face plant as much as I enjoyed 
Willig's tumble.

> 
> 
> Here's an example of a two-iteration, but non-oscillating system:
> Suppose the propotional slider has internal resolution 0-65535.  Even
> though you cannot actually use that resolution via the GUI, suppose
> your mouse movements sets it to 32970. The digital display must then
> update itself to 50(%).  Then the system may conclude: "the digital
> display was changed to 50(%), so let's put the proportional slider at
> 32768".  Good?  Wrong?  Bad?

Not so. :) The digital display should have an internal value which gets 
set to 32970/65535 and which merely gets shown as "50". It has to take a 
/typed/ "50" and publish 1/2 in its internal value anyway unless we want 
each of its clients to determine for itself the semantics of "50".

> 
> For some systems this may be a resonable thing to do. It depends on
> the application.  For a GUI, I don't like sliders moving slightly away
> from where I put them with the mouse, unless there's a compelling
> reason to do so (e.g. the slider actually has only two positions,
> e.g. for showing a 2-9-page document page by page: it can then exihit
> jumping instead of sliding behaviour).

Yikes, hopalong widgets? Sounds horrid, but i usually turn on 
"snap-to-grid" when doing gui layout, and that's ok. but there the 
dragged element is larger than the grid resolution, so my mouse need not 
leave the element by much or at all before the element snaps to a new 
location.

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Wolfgang Mederle
Subject: Re: Cells&Cycles
Date: 
Message-ID: <h2mv5b.bs.ln@DS9.mederle.de>
Joerg Hoehle wrote:

> When I looked into GUI programming a decade ago, I remember a nice
> demo: Something like a volume control with two ways of setting it:
>  - a proportional slider with a knob
>  - a digital input where you could type the number (0-100)
> Modifying with mouse or keyboard changed the other's display.

Sounds like Garnet. (Even if it wasn't, Garnet has sliders and
scrollbars with this functionality.) I'm working on a small program at
the moment that uses it, and it is really a joy.

-- 
Wolfgang Mederle

$BONMOT
From: Kenny Tilton
Subject: Re: Cells&Cycles
Date: 
Message-ID: <3E83787A.4060705@nyc.rr.com>
Wolfgang Mederle wrote:
> Joerg Hoehle wrote:
> 
> 
>>When I looked into GUI programming a decade ago, I remember a nice
>>demo: Something like a volume control with two ways of setting it:
>> - a proportional slider with a knob
>> - a digital input where you could type the number (0-100)
>>Modifying with mouse or keyboard changed the other's display.
> 
> 
> Sounds like Garnet. (Even if it wasn't, Garnet has sliders and
> scrollbars with this functionality.) I'm working on a small program at
> the moment that uses it, and it is really a joy.
> 

You know, I always am encouraged in re Cells and the Cell-powered gui 
Cello by encomiums to Garnet, but should I be? Garnet is not dead, but 
at the risk of pissing off its maintainers it seems to be dead in the 
water. If it is so wonderful, how come it is not thriving?

Let me offer two tentative answers: Amulet (a dead end itself, it seems) 
and "CLOS not spoken here"?

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Wolfgang Mederle
Subject: Re: Cells&Cycles
Date: 
Message-ID: <r3606b.761.ln@DS9.mederle.de>
Kenny Tilton wrote:

> You know, I always am encouraged in re Cells and the Cell-powered gui
> Cello by encomiums to Garnet, but should I be? Garnet is not dead, but
> at the risk of pissing off its maintainers it seems to be dead in the
> water. If it is so wonderful, how come it is not thriving?
> 
> Let me offer two tentative answers: Amulet (a dead end itself, it
> seems) and "CLOS not spoken here"?

Amulet, which is for C++, I don't know. I rather wonder why C++ was
chosen at all, when CMUCL with its good performance was developed at the
same University. Was the speed difference so big at the time? 

The lack of CLOS, though, might be a drawback today. In 1994, when the
docs (which are excellent) were written, performance issues with CLOS
were given as one of the reasons for using a custom object system.
Should not be a problem anymore.

Plus:

* No Debian package available. I don't use Debian myself, but I
  converted many packages for Slackware and use common-lisp-controller.
  Debian seems to be the preferred Linux platform for Lispers.
* No asdf/defsystem installer. Install is easy, but still not as
  comfortable. 
* No transparency, no 3D look. I like the look, but it is not "modern". 
* Other toolkits packaged with commercial Lisps.
* Not much talk about it anymore. I was glad to receive a few answers
  for a question on the Garnet Users mailing list, but basically they
  said "I don't remember it well" or "I don't use it now".
* comp.windows.garnet is dead. Absolutely no response to my question
  there. This /could/ mean that the total user base at this very moment
  is me. On the other hand, the total user base of Common Lisp at my
  institute at University is me, too. I'm working on leveraging it,
  though.

-- 
Wolfgang Mederle

$BONMOT
From: CY
Subject: Re: Cells&Cycles
Date: 
Message-ID: <12f50208.0303280903.27ea1a37@posting.google.com>
Kenny Tilton <·······@nyc.rr.com> wrote in message news:<················@nyc.rr.com>...
> Wolfgang Mederle wrote:
> > Joerg Hoehle wrote:
> > 
> > 
> >>When I looked into GUI programming a decade ago, I remember a nice
> >>demo: Something like a volume control with two ways of setting it:
> >> - a proportional slider with a knob
> >> - a digital input where you could type the number (0-100)
> >>Modifying with mouse or keyboard changed the other's display.
> > 
> > 
> > Sounds like Garnet. (Even if it wasn't, Garnet has sliders and
> > scrollbars with this functionality.) I'm working on a small program at
> > the moment that uses it, and it is really a joy.
> > 
> 
> You know, I always am encouraged in re Cells and the Cell-powered gui 
> Cello by encomiums to Garnet, but should I be? Garnet is not dead, but 
> at the risk of pissing off its maintainers it seems to be dead in the 
> water. If it is so wonderful, how come it is not thriving?

Not too much maintainance going on right now really.  That may change
in the future when it becomes useful for a project, but currently it's
not high on the priority list.  Basically the SF site is a place for
bug fixes to be added, if/when people find and fix them.

> Let me offer two tentative answers: Amulet (a dead end itself, it seems) 
> and "CLOS not spoken here"?

Amulet... I don't think Amulet is a reason anymore, since if people
are looking to use Garnet they are looking for a Lisp toolkit.  It was
one of the reasons CMU discontinued development on Garnet, IIRC.  CLOS
is also another big issue, although bridging is apparently possible. 
I think the look of it doesn't help, either - it's quite advanced and
powerful, but looks like a really old MacOS interface out of box.  The
Motif look is a bit better, but a Windows look would help quite a bit.
From: Thomas F. Burdick
Subject: Re: Cells&Cycles
Date: 
Message-ID: <xcvwuij5pzh.fsf@apocalypse.OCF.Berkeley.EDU>
Kenny Tilton <·······@nyc.rr.com> writes:

> Wolfgang Mederle wrote:
> > Joerg Hoehle wrote:
> > 
> > 
> >>When I looked into GUI programming a decade ago, I remember a nice
> >>demo: Something like a volume control with two ways of setting it:
> >> - a proportional slider with a knob
> >> - a digital input where you could type the number (0-100)
> >>Modifying with mouse or keyboard changed the other's display.
> > 
> > 
> > Sounds like Garnet. (Even if it wasn't, Garnet has sliders and
> > scrollbars with this functionality.) I'm working on a small program at
> > the moment that uses it, and it is really a joy.
> 
> You know, I always am encouraged in re Cells and the Cell-powered gui 
> Cello by encomiums to Garnet, but should I be? Garnet is not dead, but 
> at the risk of pissing off its maintainers it seems to be dead in the 
> water. If it is so wonderful, how come it is not thriving?
> 
> Let me offer two tentative answers: Amulet (a dead end itself, it seems) 
> and "CLOS not spoken here"?

Here's my $0.02 on this: it looks like it stalled when it lost its
institutional support from CMU.  Amulet caused Garnet to be orphaned
around the same time that CMU orphaned CMUCL.  The lisp implementation
succeeded in getting a volunteer development group supporting it,
largely, I think, because it's compatible with the commercial
implementations (ie, it's an ANSI Common Lisp).  Garnet, on the other
hand, is completely incompatible with any other GUI kit for CL, and is
pretty conceptually different, too.

Why hasn't it regained mindshare?  This might be due in part to the
docs' use of the old-style look&feel, instead of the Motif l&f --
anyone just glancing through the docs is going to say "wow, that looks
weird".  Or, "wow, that looks like my Mac 512K", depending on their
personal history.  And it suffers greatly from the fact that there are
other good (commercial) toolkits, and you have to try it to realize
how cool KR is.

For any lurkers at UC-Berkeley: if you want to try out Garnet, it's
installed at the OCF.  Get an OCF account, start CMUCL, and type
(require :garnet) at the toplevel.  Bada-bing, bada-boom.  The docs
are in /opt/local/packages/garnet/docs/.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Vladimir S.
Subject: Re: Cells&Cycles
Date: 
Message-ID: <87of3vebqk.fsf@shawnews.cg.shawcable.net>
Kenny Tilton <·······@nyc.rr.com> writes:

> Wolfgang Mederle wrote:
> > Joerg Hoehle wrote:
> >
> >>When I looked into GUI programming a decade ago, I remember a nice
> >>demo: Something like a volume control with two ways of setting it:
> >> - a proportional slider with a knob
> >> - a digital input where you could type the number (0-100)
> >>Modifying with mouse or keyboard changed the other's display.
> > Sounds like Garnet. (Even if it wasn't, Garnet has sliders and
> > scrollbars with this functionality.) I'm working on a small program at
> > the moment that uses it, and it is really a joy.
> >
> 
> You know, I always am encouraged in re Cells and the Cell-powered gui
> Cello by encomiums to Garnet, but should I be? Garnet is not dead, but
> at the risk of pissing off its maintainers it seems to be dead in the
> water. If it is so wonderful, how come it is not thriving?
> 
> Let me offer two tentative answers: Amulet (a dead end itself, it
> seems) and "CLOS not spoken here"?

I guess I can weigh in my ignorant opinion as well since there is
something about Garnet that's been frustrating me for the past couple
of days. For something written in CL by competent CL programmers, it
sure seems un-Lispy.

You immediatly notice this in the manual - every example encourages
you to use the 's-value' function to change slot values (I think
there's only one place (in the KR docs) where the setf method for
changing schema (KR object) values is mentioned). The 'interesting'
function names (I really don't understand why 'create-instance' is the
external function for making schema, and 'make-schema' is the internal
one). Many functions are just redundant - 'add-component' can only add
one schema to an aggregate, but 'add-components' signals an error if
you try to add only one schema.

Then there's the thing that has gotten on my nerves - virtual
aggregates (containers for static screen elements that draw them
without making a separate object for each one) - I wanted to write the
plot routines for Mark Watson's _Common Lisp Modules_ book, but when
using the regular aggregate and objects, the fractal examples spent
most of the time just adding rectangles. The interface to virtual
aggregates is messy (not to mention the bad function naming and
redundancy - 'add-component' only works on regular aggregates, and
'add-item' only on virtual ones), and I can't get the damn things to
work on rectangles (I subscribe to CMU's Garnet mailing list, but
judging by the replies Wolfgang received (sorry for not answering, but
I don't know anything about aggrelists) they can't offer me much help
either).

So not everything is peachy about Garnet. While the above complaints
aren't very difficult to resolve (and I guess I am a bit sensetive
about these things as I am re-reading Kent and Norvig's "Good Lisp
Style" talk papers), and actually I am planning to resolve them by
making a new interface to Garnet after I'm done wrangling with
Multi-Garnet, the CLOS integration issue is more hairy. So yes,
Mr. Tilton, you do have reason to be encouraged :). Personally I am
really looking forward to Cello.
From: Kenny Tilton
Subject: Re: Cells&Cycles
Date: 
Message-ID: <3E84DAFE.2040500@nyc.rr.com>
Vladimir S. wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
>>You know, I always am encouraged in re Cells and the Cell-powered gui
>>Cello by encomiums to Garnet, but should I be? Garnet is not dead, but
>>at the risk of pissing off its maintainers it seems to be dead in the
>>water. If it is so wonderful, how come it is not thriving?
>>
...
> So not everything is peachy about Garnet. While the above complaints
> aren't very difficult to resolve (and I guess I am a bit sensetive
> about these things as I am re-reading Kent and Norvig's "Good Lisp
> Style" talk papers), and actually I am planning to resolve them by
> making a new interface to Garnet after I'm done wrangling with
> Multi-Garnet, the CLOS integration issue is more hairy. So yes,
> Mr. Tilton, you do have reason to be encouraged :). Personally I am
> really looking forward to Cello.

Thanks to you and everyone for your insights on Garnet. I'll keep going 
on Cello. :)

I have thought of doing something like aggregates in the past, but so 
far they have not been necessary, and that is how Cello grows, in 
response to new demands.

Fractals are computationally expensive, but it does not sound like 
somehting that is hard to keep straight the way a big application is. I 
would likely just have a fractal widget and let it worry about how to 
create the fratal image.

It would be /fun/ to do with Cells and Cello, and probably instructive, 
but too slow.

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Wolfgang Mederle
Subject: Re: Cells&Cycles
Date: 
Message-ID: <glq26b.nq1.ln@DS9.mederle.de>
Vladimir S. wrote:

> I guess I can weigh in my ignorant opinion as well since there is
> something about Garnet that's been frustrating me for the past couple
> of days. 

Which already doubles the user base from my point of view.

> So yes, Mr. Tilton, you do have reason to be encouraged :). Personally
> I am really looking forward to Cello.

I'll just add a "me too" here. 

-- 
Wolfgang Mederle
From: Kenny Tilton
Subject: Cells and KR Compared [was Re: Cells for CormanLisp]
Date: 
Message-ID: <3E7787FB.8080308@nyc.rr.com>
reini urban wrote:
> Kenny Tilton wrote:
> 
>> OK, CormanLisp 2.01 now has available patches to fix up the defstruct 
>> issues. A little fancy footwork on the Cells side and we have...
>>
>>     Cells for CormanLisp (and ACL, LW, and CLisp):
>>       http://www.tilton-technology.com/cells_top.html
> 
> 
> I still don't get it exactly. So in short:
> Is it something like the garnet object-system, only on top of CLOS?
> 
> (I think it was called KR)

Disclaimer: I read a lot of the KR doc, never once used it, and I am a 
lousy reader. Corrections welcome (if phrased pleasantly, Marc <g>).

 From the KR manual: "In addition, the system supports a constraint
maintenance mechanism which allows any value to be computed from a 
combination of other values."

Check. Scarily similar (even when one is accustomed to independent 
discovery) on the face of it.

Cells have cleaner, more transparent syntax (sometimes none), and Cells 
have more features such as varieties of Cells (normal, ephemeral, delta, 
stream, more as necessary to suit new requirements) and Synapses (lotsa 
games can be played here) which mediate dependencies.

KR has an on-change callback mechanism called demon invocation, similar 
to the Cells echo mechanism, but again not as rich.

Here we are very close: "Formulas represent one-directional connections 
between a dependent value and any number of depended values. Formulas 
specify an expression which computes the dependent value based upon the 
depended values, as well as a permanent dependency ...."

Check, except dependencies in Cells are not permanent (and I wonder if 
they /really/ are in KR or if that is a doc error). In Cells, if the 
rule is:

   (if (a) (b) (c))

... the dependencies arising from (b) or (c) are in place, depending on 
the Lispian truth of (a). ie, dependencies are dynamically 
(re)determined on each evaluation of the rule.

As for: "Formulas can contain arbitrary Lisp expressions, which 
generally reference at least one particular depended value."

yep. Don't know about KR, but Cells are smart enough to optimize 
themselves away if after any evaluation they are not dependent on 
anything which might actually change.

Now Cells and KR constraints deviate wildly: "Formulas are not 
recomputed immediately when one of the depended values changes. This 
reduces the amount of unnecessary computation."

A Cells application /works/ by cell-driven dataflow, so eager evaluation 
is essential. That said, if someone comes up with a requirement that 
certain Cells not be recomputed until accessed, we could do that.

The problem with lazy evaluation is this. If A depends on B which 
depends on C and C changes, KR doc says B gets marked as invalid. What 
about A? That's invalid, too. Now an example in the doc suggests KR does 
know that, so... while KR is running all over the dependency graph 
merely marking things as invalid, all of which will get recomputed when 
something far away dependency-wise gets read, in the meantime Cells is 
simply recalculating stuff and "making it so". If a recalculation 
produces the same value as the cache, no further propagation takes 
place. But lazy evaluation cannot determine that, so it must continue 
along the dependency graph erroneously and inefficiently marking stuff 
as invalid.

"Moreover, formulas are not recomputed every time their value is
accessed. Each formula, instead, keeps a cache of the last value it 
computed. Unless the formula is marked invalid, and thus needs to be 
recomputed, the cached value is simply reused."

Same with Cells.

"This factor causes a dramatic improvement in the performance of the 
constraint maintenance system, since under ordinary circumstances the 
rate of change is low and most changes are local in nature."

Which is why eager evaluation is so efficient. :)

Another difference: "Constraints may involve circular chains of 
dependency."

They say they use the cached value when calculating A requires A. I 
wonder what they use on the first calculation? Probably nil or 42. The 
Cells system would prefer the programmer figure out what the hell they 
mean. :)

Another difference: "It is possible for a dependency path to become 
temporarily unavailable. This would happen, for instance, if schema 
POINT-1 in Figure 5-1 was deleted..[snip]. KR handles such situations 
automatically. If a formula needs to be evaluated but one of its
dependency paths is broken, the current cached value of the formula is 
simply reused. This makes it completely safe to modify schemata that 
happen to be involved in a dependency path, since the system
handles the situation gracefully."

You say "gracefully", we say "erroneously". The world has changed, the 
cached value is not good enough. With cells the schemata is itself 
cell-based. If the schema is going to change, the parent slot for its 
children is mediated by a cell. (Cells internals arbitrarily enforce 
this.) Any other cell that accesses that slot gets recalculated as the 
schema changes. This is huge, btw, having the /population/ of the model 
determined by a cell on which other state can depend, and having the 
population depend on other state.

To me the lazy/eager thing is decisive. Without eager evaluation, the 
programmer still has their hands on the controls. The paradigm shift 
does not occur. It took me a while to get used to it, but early on in 
the development of Cells I realized I would have to "let go" and commit 
to the declarative model: write the rules then let 'er rip.

This felt reckless, but then again I think the power of the declarative 
model is well-understood. Looked at another way, if we are going to find 
a significantly more productive way of programming, must it not involve 
relieving the programmer of some onerous responsibility?

I get into this in the doc at the link below: Simple, linear constraints 
combined with eager evaluation make our models run by themselves, 
according to the rules we set. Cells effectively endow state change with 
causal power over other state. They provide automatic animation of 
models. Without Cells and esp. eager evaluation, we programmers are 
puppeteers hand-animating the dataflow required by any interesting 
model. That's a lot of work never mind how hard it is to get right, and 
I never realized how much until I started using Cells.

I said it before, I'll say it again: KR veterans please weigh in with 
corrections.

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Kenny Tilton
Subject: Cells - KR Compared [Re: Cells for CormanLisp]
Date: 
Message-ID: <3E77CD6F.5000002@nyc.rr.com>
reini urban wrote:
> Kenny Tilton wrote:
> 
>> OK, CormanLisp 2.01 now has available patches to fix up the defstruct 
>> issues. A little fancy footwork on the Cells side and we have...
>>
>>     Cells for CormanLisp (and ACL, LW, and CLisp):
>>       http://www.tilton-technology.com/cells_top.html
> 
> 
> I still don't get it exactly. So in short:
> Is it something like the garnet object-system, only on top of CLOS?
> 
> (I think it was called KR)

I posted a longer answer but it has not shown up even on my own news 
server after six hours. I'll chop it up or put it on my web site in a 
few hours, but for now:

Yes.

To be precise, the KR doc talks about a few major accomplishments, only 
one of which is a simple, linear constraint mechanism much like Cells 
which, yes, messes CLOS.

The big difference between Cells and KR constraints is eager vs lazy 
evaluation.

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Vlad S.
Subject: Re: Cells - KR Compared [Re: Cells for CormanLisp]
Date: 
Message-ID: <76c4da8e.0303211019.295ce9d8@posting.google.com>
Kenny Tilton <·······@nyc.rr.com> wrote in message news:<················@nyc.rr.com>...

> I posted a longer answer but it has not shown up even on my own news 
> server after six hours. I'll chop it up or put it on my web site in a 
> few hours, but for now:
> 
> Yes.
> 
> To be precise, the KR doc talks about a few major accomplishments, only 
> one of which is a simple, linear constraint mechanism much like Cells 
> which, yes, messes CLOS.
> 
> The big difference between Cells and KR constraints is eager vs lazy 
> evaluation.

There is an extension to Garnet called Multi-Garnet written by Michael
Sannella at U of Washington sometime in the early 90s. It supports
multi-way constraints (hence the name) by replacing KR's constraint
solver with their constraint system called SkyBlue, which besides
being based on eager evaluation also has a separate constraint
propagation planning stage that it uses to resolve the constraint
hierarchy (it supports required and 'weak' constraints) and perform a
bunch of optimizations. I've recently obtained permission from
Sannella to modify and redistribute the original sources, and I'm
reading through the Multi-Garnet paper right now. Hopefully I'll
understand enough to at least fix it up to work right on Garnet 3.0.
The nice thing is that it can coexist with regular Garnet in the same
image.

The bad thing about Garnet is that it doesn't play nicely with CLOS.
The best approach seems to be the one by Russell Almond, which
involves putting an after method on the setf method for the particular
CLOS object in question.

http://groups.google.ca/groups?q=garnet+clos&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=9304290000.AA17234%40bass.statsci.com&rnum=3

http://groups.google.ca/groups?q=garnet+clos&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=9310140045.AA25086%40herb.statsci.com&rnum=1
(details on Russell's KR-CLOS method)

http://www.cs.washington.edu/research/constraints/ui/multi-garnet-92.html

http://www.cs.washington.edu/research/constraints/index.html
(the aforementioned pages on Multi-Garnet and Alan Borning's
Constraints research group. their ftp site seems to be down right
now).
From: Kenny Tilton
Subject: Re: Cells - KR Compared [Re: Cells for CormanLisp]
Date: 
Message-ID: <3E7B900A.2020209@nyc.rr.com>
Vlad S. wrote:
> I've recently obtained permission from
> Sannella to modify and redistribute the original sources, and I'm
> reading through the Multi-Garnet paper right now. Hopefully I'll
> understand enough to at least fix it up to work right on Garnet 3.0.
> The nice thing is that it can coexist with regular Garnet in the same
> image.

Sounds like fun. When I get some spare time I would like to do a simple 
multi-way trick in Cells by creating a SeeSaw structure which links 
exactly two Cells. I have had that come up a couple of times (the scroll 
bar thumb position-text scroll position being a classic pair) and don't 
like the way I got around it.

Early on I did something interesting (before dumping it in favor of the
workaround I do not like either). I created the concept of a cellular 
Gosub. When one of these was instantiated, it installed temporarily new 
rules in any abitrary number of instances' slots. With the scroll thumb 
example, the normal rule was that it slavishly reflected the amount the 
page had been scrolled by cursor movements, pagedowns, text searches, 
etc. But if there were a mousedown in the scroll thumb, a Gosub was 
instantiated which had the scroll thumb dependent on mouse movement and 
made the text scroll position dependent on the scroll thumb. the neat 
thing was that the Gosub was itself Cellular, and a "return" cell (with 
rule (c? (mouseUp (window self)))) was echoed by snuffing the Gosub, 
including backing out the temporary rules and restoring the originals.

Cute, but eventually the discontinuity got to me. Reality does not 
suddenly swap in new rules, I should I have to do that? And of course 
yanking Gosubs eliminated a whole wadge of code, which is nice.

Anyway, getting back to multi-way (MW), I think that is a tool for an 
entirely different class of problem than making an application run. MW 
lets one have a logic engine find solutions for us, when all we have are 
partial constraints on a problem. But if I the developer am not faced 
with such a problem--if I know how I want my model to work--I think 
one-way (1W), fully-determinative rules suffice. (Except for scroll 
thumbs.) But for quite a few different kinds of application (tutorial, 
crossword puzzlr, modeling of a pendulum as a physical system, the vast 
CiniSys application) 1W has been enough.

Of course MW is a superset of 1W, so I would guess any of the MW systems 
could be used to power something like Cells.

> 
> The bad thing about Garnet is that it doesn't play nicely with CLOS.
> The best approach seems to be the one by Russell Almond, which
> involves putting an after method on the setf method for the particular
> CLOS object in question.

Why not just carve out the constraints logic so you don't end up with an 
app with two object models and this glue (thx for the links):

> 
> http://groups.google.ca/groups?q=garnet+clos&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=9304290000.AA17234%40bass.statsci.com&rnum=3

 From there I pulled:

> Here is how I solve the problems:
> 
> +--------+ announcement +----------+ notification  +--------+
> |        |------------->| Mediator |-------------->|        |
> | CLOS   |              +----------+               | KR     |
> | object |    call-back (action function)          | object |
> |        |<----------------------------------------|        |
> +--------+                                         +--------+
> 
...snip...
> 
> Although this seems a bit convoluted, 

Ya think? :) But one thing I am learning is that some folks just plain 
like the Prototype OO model, esp. for GUI stuff, so maybe that is a win 
big enough to justify the effort of splicing CLOS and KR.

Good luck with Multi-Garnet.

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Jakub Travnik
Subject: Re: Cells for CormanLisp
Date: 
Message-ID: <pan.2003.03.21.12.51.43.458601@sh.cvut.cz>
On Tue, 18 Mar 2003 00:49:21 +0000, Kenny Tilton wrote:

> OK, CormanLisp 2.01 now has available patches to fix up the defstruct
> issues. A little fancy footwork on the Cells side and we have...
> 
>      Cells for CormanLisp (and ACL, LW, and CLisp):
> 
>        http://www.tilton-technology.com/cells_top.html
> 

Hello,

what are license conditions for Cells?


Jakub Travnik
·············@jabber.com
From: Kenny Tilton
Subject: Re: Cells for CormanLisp
Date: 
Message-ID: <3E7B2D12.7050808@nyc.rr.com>
Jakub Travnik wrote:
> what are license conditions for Cells?

One version was released under the GPL. Anyone using that could get a 
different, uninfectious license for the terms described below.

The current version is just plain proprietary, until events sway me back 
towards GPL or even LGPL.

My plan would be to have free runtime use, with developer seats costing 
something (which would include some base level of support).

When I do start selling it, my thinking was to start silly-cheap and 
then increase the price to some reasonable level over time. That way if 
it just dies, no one has paid very much.

It also compensates early adopters for the pain they will endure reading 
my doc (which will be evolving in response to user feedback) and 
watching me change the whole thing every month so they have to rewrite 
all their code. (Well, not Cells, that is stable, but Cello...)

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore