FWIW: Probably the most elegant answer would be one in which one could rely on just one element of a vector, although I can also see how one would then need a way to have just one dependency if one was iterating over the whole vector. This would prolly mean a whole new entry point (md-slot-vector-value and (setf md-slot-vector-value)) and in the end not be all that hard, just some straightforward effort in the dependency-tracking code to keep it efficient.
This would not be transparent or foolproof -- if one forgets to use the slot-vector API the dependencies will mysteriously not work, but that is the kind of thing one recognizes after ten seconds of stunned astonishment (like CLOS methods whose signatures I change but neglect to expunge).
kt
Peder Chr. Nørgaard wrote:
Larry, thanks for the answer. Yes, a trick (OK, a technique) like this would probably do the job for me. I was kind of leaning in the same direction myself, Kenneth Tilton's response pointing to Peter Hildebrandt's "cells-store" extension which is actually a part of the Cells package that I am using and using more or less the same hack (OK, same technique) :-).
So, everybody, thanks for your help, Kenneth, Jakub, Larry. And Peter Hildebrandt, I found the Aug 2008 mail describing the rationale for cells-store (not to be churlish, but that text ought to be in cells source code package, not in a mail somewhere. It is valuable!).
I have the answer to my problem now. Just have to decide what to do.
best regards --peder chr.
On Monday 18 May 2009, Larry Clapp wrote:
On Sat, May 16, 2009 at 04:23:41PM +0200, Peder Chr. Nørgaard wrote:
I am attempting to use a vector as the value in a slot. It does not work well in first attempt:
CL-USER> (use-package :cells) T CL-USER> (defparameter a1 (make-instance 'model :value (c-in #(1 2 3 4)))) A1 CL-USER> (defparameter a2 (make-instance 'model :value (c? (apply #'+ (map 'list #'identity (value a1)))))) A2 CL-USER> (value a2) 10 CL-USER> (setf (elt (value a1) 1) 5) 5 CL-USER> (value a1) #(1 5 3 4) CL-USER> (value a2) 10
The VALUE slot of A2, depending on (VALUE A1) is not changing when (VALUE A1) is, shall we call it "changed in place".
The cells version is from :pserver:anonymous:anonymous@common-lisp.net:/project/cells/cvsroot.
The Lisp system is SBCL is 1.0.18.0-2.
I would like to enquire whether I am simply doing something trivially wrong, or whether this is something that simply cannot be done without a major CELLS extension for support of vector values (like, FAMILY, can be viewed as a kind of support for list values). The latter answer may force me to reconsider an implementation that I had in mind.
I asked a similar question almost exactly a year ago. Hmmm. :) Anyway, see http://common-lisp.net/pipermail/cells-devel/2008-May/002035.html . The general answer hasn't changed since then: either don't do that, or recons the sequence, or make the cell formula depend on something else that changes directly in addition to the stuff it actually depends on. (In last year's thread, Peter Hildebrandt noted that this last option is how cells-store works.)
I played with the last option a bit today, and came up with this (which may or may not work very well in real usage, but the toy example below works):
(defmodel change-counter () ((count :initform (c-in 0) :accessor count-of)))
(defmethod kick ((self change-counter)) (incf (count-of self)))
(defmacro change-watcher ((model) &body body) `(progn (count-of ,model) ,@body))
(defmacro with-changes ((&rest models) &body body) `(unwind-protect (progn ,@body) (with-integrity (:change) (dolist (model (list ,@models)) (kick model)))))
Example (Lispworks, if it matters):
CELLS-PLAY 217 > (defmodel test (change-counter) ((slot :initarg :slot :accessor slot-of))) NIL
CELLS-PLAY 218 > (defparameter a1 (make-instance 'test :slot (c-in #(1 2 3 4)))) A1
CELLS-PLAY 219 > (defparameter a2 (make-instance 'test :slot (c? (change-watcher (a1) (format t "recalc a2's s~%") (apply '+ (coerce (slot-of a1) 'list)))))) recalc a2's s A2
CELLS-PLAY 220 > (slot-of a2) 10
CELLS-PLAY 221 > (with-changes (a1) (setf (aref (slot-of a1) 1) 5)) recalc a2's s 5
CELLS-PLAY 222 > (slot-of a2) 13
CELLS-PLAY 223 > (slot-of a1) #(1 5 3 4)
Hope that's helpful.
-- Larry
No virus found in this incoming message. Checked by AVG - www.avg.com Version: 8.5.329 / Virus Database: 270.12.32/2118 - Release Date: 05/16/09 17:05:00