Peter Hildebrandt wrote:
Ken,
First of all, thanks for the quick fix. However, it does not behave quite as it should: cell slots now return t during not-to-be. I think the reason is in md-slot-value.lisp:ensure-value-is-current, more exactly:
(when *not-to-be* (return-from ensure-value-is-current t))
While the function returns otherwise:
(bwhen (v (c-value c)) (if (mdead v) (progn #+shhh (format t "~&on pulse ~a ensure-value still got and still not returning ~a dead value ~a" *data-pulse-id* c v) nil) v)))
That is, (c-value c).
I changed it accordingly:
(when *not-to-be* (return-from ensure-value-is-current (c-value c)))
Right, thanks, sorry for the head fake. Eventually something should be added to the regression test.
Which works fine with my example code (that is, the cells-tree-view). I checked it into cvs.
I am not quite sure about the implications, though.
Yeah, it is not clear what to do. The instance is no longer part of the model, so some rules will outright fail and those that do not would possibly be circular or at least form crazy dependencies of things no longer extant on those that are.
I think what I am doing here is return the value of a cell without recalculating it -- That is, I get the value calculated the last time the cell was accessed alive. That means -- if I am right -- the value I work on might be quite old, and a more granular check of the *not-to-be* special might be appropriate.
However, I did a quick test:
;; make two nodes to create a cell dependency CTEST> (defparameter *val* (make-instance 'node :value (c-in 1))) *VAL* CTEST> (defparameter *root* (make-instance 'node :kids (c?n (list (make-kid 'node :value (c? (value *val*))))))) *ROOT*
;; check whether it works CTEST> (value (first (kids *root*))) 1 CTEST> (setf (value *val*) 2) 2 CTEST> (value (first (kids *root*))) 2 ;; yep
;; look at not-to-be, CTEST> (defmethod not-to-be :before ((self node)) (trc "not-to-be :before" (value self))) #<STANDARD-METHOD NOT-TO-BE :BEFORE (NODE) {CEFE609}>
;; make a change CTEST> (setf (value *val*) 3) 3
;; and see ... CTEST> (setf (kids *root*) nil) 0> not-to-be :before 3 0> not-to-be :before 3 NIL ;; wonderful!
Hmmm. I see 'not-to-be gets called pretty early, pretty much as soon as a slot value has changed and owned things are seen to be no longer in that slot, right during propagation. So where a dying instance reads slot X and slot X is still alive and would normally update when read (and still will later during this same propagation (I think <g>)) then the dying instance will see either an obsolete value or (I just realized) a new value if propagation got to X first by another path.
Nothing like a little non-determinism to start the day. :)
Well, The Lisp Way is to let people shoot themselves in the foot, we can probably just leave it as it is and see what happens.
If there was any documentation we could document not-to-be and point all this out and remind them that code in not-to-be should not be doing things in or with the model, it should be, eg, notifying C libraries that blocks they allocated can be scavenged.
Hmmm, those /could/ be the result of Cell rules, I guess it is good to return the old value.
kt