James Bielman wrote:
On 27 Apr 2005, Kenny Tilton wrote:
Fascinating. I happen to have done quite a bit of 6502 programming back in my Apple II days. I can't wait to look at your code and see how Cells was able to contribute to that. I will also stare at the cycle and think about how Cells could be enhanced to handle that gracefully, even if just by giving programmers an orderly way to apply domain knowledge.
Cool. I never really did much so I'm learning as I go. :) I put up a more detailed description of what happens during an assembly and where the cycle occurs at:
Thanks for the detailed breakdown of the problem.
You may have noticed that the system does allow a cell to be specified as "cyclic", but then the propagation simply halts if a cycle is detected. This to support cases like a scroll thumb, which both drives and is driven by the text currently displayed in a window.
In that case, the cyclic propagation would be to set the cell to the value it already has, so it can simply be skipped. (I could let it continue and then propagation would stop anyway since the skipped set would result in no change, when propagation stops anyway, but I decided, hey, save a few CPU cycles. anyway...)
Likewise, in your case the cycle is benign and terminates naturally. And as long as we are considering some way to let the programmer apply domain-specific knowledge....
What if we just eliminate entirely the cyclic thing and let programmers shoot themselves in the foot if they like? That is the Grand Lisp Philosophy, after all.
Ironically, I might then consider treating the scroll case as /non/-cyclic. ie, It becomes a special declaration /not/ to cycle, saving a few CPU cycles. Hmmm, but now I am wondering about the CPU cost of cycle detection:
(when (find c *causation*) (case (c-cyclicp c) (:run-on (trc "cyclicity running on" c)) ((t) (progn (trc "cyclicity handled gracefully" c) (c-pulse-update c :cyclicity-1) (return-from md-slot-value new-value))) (otherwise (c-break "(setf md-slot-value) setf looping ~a ~a" c *causation*))))
Omigod. What the hell is :run-on doing there? :) I am going to go try that now on your assembler code.
Anyway, look at that "(find c *causation*)". That runs allllllllllll the time. The only benefit is automatically notifying the developer when they screw up. I could just toss the whole thing (even the cyclic attribute altogether, I think) or we could have a special such as *cell-trap-cyclic-bugs-please* and then try to figure out when something is cyclinc (not that easy, I believe Turing demonstrated).
Of historical interest is that it occurred to me long ago that applications could simply work this way. I mean, it is how the world works. One cause leading to another. And it so happens that one consequence of Cells II is that this endless causal chain no longer means endless recursion, so the timing is good.
Thoughts?
kenny
Kenny Tilton wrote:
Omigod. What the hell is :run-on doing there? :) I am going to go try that now on your assembler code.
Ah, sorry, that was in (setf md-slot-value), not md-slot-value-assume.
I made this change:
(defmodel label () ((name :initarg :name :reader name :documentation "Name of this label, a symbol.") (location :initform (c-input (:cyclicp :run-on) 0) ...etc...
And modified md-slot-value-assume to know about :run-on, and the assembly ran to completion (correctly, I am assuming). I am assuming because I am not so interested in this fix so much as in the grander fix of simply not checking for cycles and letting programmers fend for themselves.
btw. note that there would still be a different kind of cycle which would still be an error, one on the read side: if the rule for A eventually leads back to a read of A, that is a fatal error.
kenny