[cells-devel] More newbie questions

Kenny Tilton ktilton at nyc.rr.com
Sat Mar 5 17:45:35 UTC 2005



Mike J. Bell wrote:

>I wasn't thinking totally clearly at 3am, so around 4:30 I thought of
>some things that I didn't ask.  =)
>
>(You may notice that I'm coming from an event-driven paradigm...
>
No problem. I am usually developing GUI apps--all events all the time.

>I'm
>trying to map my understanding of how mine works onto Cells and "make
>sure" Cells is a superset of what I'm using).
>
>5) Multi-method (?) calculations:  I've seen simple examples in the
>Cells docs that show a slot being dependent on another slot.  It looks
>like you install this computation in the "destination" slot, i.e. the
>one that's dependent.  What if you've got a situation where you have
>five slots, A B C D and E, that are parts of say three different
>objects, O1 O2 and O3.  There's one computation that needs A B C D and
>E, and ends up modifying slots F G H and I in objects O4 and O5.  Can
>it be done, making a single computation that depends on many slots in
>different instances that then updates slots in many instances?  Or do
>you need to decompose this computation into (complicated!) pieces to
>be installed in each of the destination slots (F G H and I)?
>
You say complicated, I say "divide and conquer". Have you ever developed 
a finite state machine, breaking some complex problem down into a 
kazillion states? It seems painfully slow at first, until you realize 
how effortlessly the approach deals with the overall computation, which 
had you so confused that you resorted to using a finite state machine. :)

Cells is all about exposing the semantics of a slot in the one formula 
which determines the value of a slot. What you are describing is 
"classic" imperative programming, where this point in the code decides 
FGHI, another decides GH, another decides GHZ, etc etc. At which point 
no one can really tell us the semantics of H.

Now if you promise me that there is one and only one computation which 
decides FGHI, what I do in cases like that is simply create a new slot 
called FGHI (I wager the real name will be quite meaningful to anyone 
reading your code) and then F, G, H, and I can have extremely simple rules:

   :f (c? (get-f (^fghi)))
   :g (c? (get-g (^fghi)))
   ..etc...

>  Can a
>change in one or more of A B C D and E cause a computation that
>updates C D F and G?  (I.e. C and D are both inputs *and* outputs of
>the calculation.  Note that self-cycling must be avoided!).
>
Again, sounds like you are resisting "divide and conquer". <g> I have 
been doing cells for about nine years now, and I have never had a 
problem decomposing big computations into so many slots mediated by so 
many cells. The cyclicity thing rarely materializes, but see my 
discussion of scrollbars in an earlier reply for how I handle that 
cyclic case.

>
>6) Multiple "owners" of responsibility, or aspect separation:  (this
>is related to #5 above)  What if you have a normal calculation that
>happens 99% of the time that changes slot A into slot B (B is
>dependent on A).  You write the formula into the slot code for B, and
>you're happy.  But then, because of some strange requirement or other
>complicated design issue, you realize that B also depends, every once
>in a while (say 1%), on C D and E.  But you don't want to stick this
>new computation and dependency code with the original code, because it
>will not only clutter reading, but also the complicated process may
>change in the future.
>
You say "clutter", I say "completely specified". <g> What is wrong with:

      (c? (if (one-chance-in-a-million self)
               (big-hairy-mess (^c) (^d) (e)))
               (nice-and-easy (^a))))
 
And who cares if it changes in the future? Just maintain the formula, 
which will always fully document the semantics of a slot. One of the 
nice things about not using GOTOs is just /knowing/ without worrying 
that any given point in the code is always reached via visible control flow.

>  So you want to keep the concerns separate, i.e.
>the two different "times" when B can change.  Is there a way in Cells
>to make two different pieces of code that show two different ways that
>slot B is dependent on other slots?
>
Not sure what you mean. Are you aware that different instances of the 
same class can have different rules for the same slot. This might help 
with your question above. Perhaps the rare situation is known at 
make-instance time? In which case you can indeed supply a different rule 
which goes after CDE.

>
>7) "Lazy" updates:  Probably a bad term for this, not to be confused
>with strict and non-strict argument evaluation.  Nonetheless, let's
>say you have a slot A that depends on B C D and E.  B and C are
>absolutely critical to A's computation, and every single time they
>change, you need to enforce that A is recomputed.  My guess is that
>Cells works like this already, automatically.  However, let's say D
>and E change their values inordinately fast, like maybe they're mouse
>X and Y coordinates on the screen.  Let's also say that the
>computation for A is non-trivial, and you want to run it only when
>absolutely necessary.  Further, although A needs the current mouse X
>and Y coordinates, it doesn't make sense to recompute A every time
>they change.  Is there a way to tell Cells that A should be recomputed
>*every* time that B and C change, but also needs access to cells D and
>E while not "firing" every time they change?
>
Yes. See "synapses". I believe Bill's blog on Cells covers that, as well 
as some of my awful doc.

>
>Sorry if this sounds stupidly simple, but remember, I'm projecting my
>domain onto yours, so I'm pretty new at this.
>
>8) Phase-based calculation, or data "wave" propagation:  If a slot A
>depends on slots B C and D...when will A get recomputed?  Every time
>that B C or D change, right?  What if two other computations change
>both C and D as a result of a single slot change in E...does Cells
>defer the running of A until *both* C and D have been recalculated
>(i.e. enforced breadth-first dependency graph traversal), or will the
>calculation of A happen twice, once when C changes and once when D
>changes (i.e. random, depth-first, or other traversal)?
>
Some recent work I playfully christened "Cells II" addressed this 
concern. Now A will be calculated only once. Each wave gets an ID (just 
an incremented count) and, if A gets calculated too early, no problem. 
The engine sees that C and/or D are obsolete (we are calculating wave N, 
but C and/or D are stamped N-1) and recomputes them Just In Time before 
completeing the calculation of A.

>
>9) Introspection:  How easy is it to determine the full dependency
>graph of interrelated computation given a system coded using Cells? 
>I.e., other than of course looking at the code, can I use a
>programmatic method to determine the topology of the dependencies in
>order to, for instance, produce a visual graph of the system?  Is this
>introspection system static, or dynamic (i.e. allow callback hooks or
>the like to update changes in the system as they happen)?
>
A visual graph would be easy to do and probably great fun to watch. I 
imagine little sparks shooting around, like an animation of the brain. I 
have long been tempted to do something like that. I guess the thing that 
holds me back is the problem of how to lay out the visual elements so 
the whole thing looks good. I always hate the way graphical class 
browsers end up looking.

kt





More information about the cells-devel mailing list