See subject.
In other words, say I have a class with two slots, a and b, with b sort-of dependant on a:
(defmodel test () ((a :initarg :a :initform (c-in (list 'a)) :accessor a) (b :initarg :b :initform (c? (car (^a))) :accessor b)))
(defmethod print-object ((self test) stream) (print-unreadable-object (self stream :type t :identity t) (format stream "a: ~S, b: ~S" (^a) (^b))))
(setf *a* (make-instance 'test))
CELLS 11 > *a* #<TEST a: (A), b: A 22ED4D93>
CELLS 12 > (setf (car (a *a*)) 'd) D
CELLS 13 > *a* #<TEST a: (D), b: A 22ED4D93>
Slots a and b are now out of sync. What's the ideo-cells-ic way to do this?
What I'm really trying to do is wrap a class around somebody else's object. The internal state of the object changes, and I'd like to figure out some way to make the Cells system aware of the change.
"Native" use of the object is something like this
(some-other-package:perturb-test self)
Do I need to wrap perturb-test too? e.g.
(defmodel test () ((a :initarg :a :initform (c-in (list 'a)) :accessor a) (a-changed :initform (c-in 0) :accessor a-changed) (b :initarg :b :initform (c? (and (^a-changed) (car (^a)))) :accessor b)))
(defmethod print-object ((self test) stream) (print-unreadable-object (self stream :type t :identity t) (format stream "a: ~S, b: ~S" (^a) (^b))))
(setf *a* (make-instance 'test))
(defun perturb-test (self y) (prog1 (setf (car (^a)) y) (incf (^a-changed))))
CELLS 34 > *a* #<TEST a: (D), b: D 200A742F>
CELLS 35 > (perturb-test *a* 'e) E
CELLS 36 > *a* #<TEST a: (E), b: E 200A742F>
-- Larry
Larry Clapp wrote:
See subject.
In other words, say I have a class with two slots, a and b, with b sort-of dependant on a:
(defmodel test () ((a :initarg :a :initform (c-in (list 'a)) :accessor a) (b :initarg :b :initform (c? (car (^a))) :accessor b)))
(defmethod print-object ((self test) stream) (print-unreadable-object (self stream :type t :identity t) (format stream "a: ~S, b: ~S" (^a) (^b))))
(setf *a* (make-instance 'test))
CELLS 11 > *a* #<TEST a: (A), b: A 22ED4D93>
CELLS 12 > (setf (car (a *a*)) 'd) D
CELLS 13 > *a* #<TEST a: (D), b: A 22ED4D93>
Slots a and b are now out of sync. What's the ideo-cells-ic way to do this?
What I'm really trying to do is wrap a class around somebody else's object. The internal state of the object changes, and I'd like to figure out some way to make the Cells system aware of the change.
Ah, now it is really tough. If it was my code accessing my internal structure I would Just Create the Glue to drive the Cells engine (eg. Peter Hildebrandt is playing with some glue to make hash tables Cellsy), but if some else is mutating an object /and not telling me/ I am stuck unless I can find some way to hook into that process.
Cells is more about me making /my/ model work automatically and also does well working with external libs with callback schemes or something like Tcl/Tk does something similar linking state but also gives me a hook so I can propagate into Cells-land. But if you have an external library mutating state you care about but there is no way normally for you to know... well, what would you do anyway? Poll the state? If so, that is where I would put a hook to feed the Cells beast with dataflow.
Beating a dead horse: When dealing with OS events, it gives me an event and that is it, it does not change that event afterwards in ways that would matter to me, for obvious reasons.
hth, kenny
"Native" use of the object is something like this
(some-other-package:perturb-test self)
Do I need to wrap perturb-test too? e.g.
(defmodel test () ((a :initarg :a :initform (c-in (list 'a)) :accessor a) (a-changed :initform (c-in 0) :accessor a-changed) (b :initarg :b :initform (c? (and (^a-changed) (car (^a)))) :accessor b)))
(defmethod print-object ((self test) stream) (print-unreadable-object (self stream :type t :identity t) (format stream "a: ~S, b: ~S" (^a) (^b))))
(setf *a* (make-instance 'test))
(defun perturb-test (self y) (prog1 (setf (car (^a)) y) (incf (^a-changed))))
CELLS 34 > *a* #<TEST a: (D), b: D 200A742F>
CELLS 35 > (perturb-test *a* 'e) E
CELLS 36 > *a* #<TEST a: (E), b: E 200A742F>
-- Larry
cells-devel site list cells-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/cells-devel
On Sun, May 18, 2008 at 10:17 PM, Larry Clapp larry@theclapp.org wrote:
Do I need to wrap perturb-test too? e.g.
(defmodel test () ((a :initarg :a :initform (c-in (list 'a)) :accessor a) (a-changed :initform (c-in 0) :accessor a-changed) (b :initarg :b :initform (c? (and (^a-changed) (car (^a)))) :accessor b)))
...
(defun perturb-test (self y) (prog1 (setf (car (^a)) y) (incf (^a-changed))))
Interesting side note: This is exactly how the cells-store (the cellsy hash table) works. If you can live with the hackish nature of it, it will probably work fine.
If you have access to the way some-other-package is compiled, you could try and shadow car/cdr so that they trigger an appropriate update.
Peter
Larry Clapp wrote:
See subject.
In other words, say I have a class with two slots, a and b, with b sort-of dependant on a:
(defmodel test () ((a :initarg :a :initform (c-in (list 'a)) :accessor a) (b :initarg :b :initform (c? (car (^a))) :accessor b)))
(defmethod print-object ((self test) stream) (print-unreadable-object (self stream :type t :identity t) (format stream "a: ~S, b: ~S" (^a) (^b))))
(setf *a* (make-instance 'test))
CELLS 11 > *a* #<TEST a: (A), b: A 22ED4D93>
CELLS 12 > (setf (car (a *a*)) 'd) D
CELLS 13 > *a* #<TEST a: (D), b: A 22ED4D93>
Slots a and b are now out of sync. What's the ideo-cells-ic way to do this?
What I'm really trying to do is wrap a class around somebody else's object. The internal state of the object changes, and I'd like to figure out some way to make the Cells system aware of the change.
"Native" use of the object is something like this
(some-other-package:perturb-test self)
Do I need to wrap perturb-test too? e.g.
(defmodel test () ((a :initarg :a :initform (c-in (list 'a)) :accessor a) (a-changed :initform (c-in 0) :accessor a-changed) (b :initarg :b :initform (c? (and (^a-changed) (car (^a)))) :accessor b)))
(defmethod print-object ((self test) stream) (print-unreadable-object (self stream :type t :identity t) (format stream "a: ~S, b: ~S" (^a) (^b))))
(setf *a* (make-instance 'test))
(defun perturb-test (self y) (prog1 (setf (car (^a)) y) (incf (^a-changed))))
[Sorry, I did not even read this far last time because I thought I understood what you were asking.]
If this last bit is an option, ie, if /I/ am the one setf-ing the car, then we do not have the case I feared of the foreign package mutating state behind my back, and in fact this problem arises even without a foreign object: I would have the same problem any time I was mutating state in a slot of even a vanilla Cells-powered class. So...
It does not come up a lot, so I Just Do Not Go There -- I am careful to recons the list. This flies in the face of a Cells design imperative (no exposed wiring) but like I said, it does not come up much. Usually the kids slot of a GUI composite widget, where I really do not want to regenerate all the sub-widgets just to add/remove one. Then I map over the .cache (this usually being in a Cell rule for kids) making a new list but generally keeping the car of each cons copied.
I think if it /did/ become a problem I would jazz up Cells with a cells-aware accessor (^elt? ^nth?) to read and write elements of a list/sequence, leaving elt and nth (and (setf car)) as backdoors.
Not as transparent as shadowing CAR, but the self-documentation quality is a nice compensation for that, and shadowing CAR scares me performance-wise and in general.
Even then I think there would be an inefficient (but ineluctable) dependency not on the car per se but on any change to the list. What if the case were CADDR instead of CAR? Now there are dependencies on two CDRs and one CAR, yes? Because if I, say, (rplacd X (cddr X)), then the result of (caddr X) is different and anyone accessing that cellsily will need to recalculate.
Hmmm. I am reminded why I do not address these things until an application forces me to. :)
kenny