[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
dependent update protocol
- To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
- Subject: dependent update protocol
- From: Gregor.pa@Xerox.COM
- Date: Wed, 20 Apr 88 10:00 PDT
- Cc: common-lisp-object-system@SAIL.STANFORD.EDU
- Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
- In-reply-to: <19880411195010.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
- Line-fold: no
Date: Mon, 11 Apr 88 15:50 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Actually your example shows that it's not really true that the format
of the information is unspecified. What is specified is that it is a list
with one element for each interested class, in most-specific-first order.
What is unspecified is the format of the list elements.
No, the format of the information itself is unspecified. Any given
layer could choose to encapsulate the next layer of information any way
it wants. Its true that the example I used builds a list, but some
level might just as well use an array.
It's usually better not to try to pass extra args through a mapping
function; instead the function being mapped can be a closure that knows
the extra args. This is more flexible, and is how all eight functions
in CLtL whose names start with "map" work. Thus I would make
map-dependents take only two arguments.
Good point. We will make this change.
(defmethod reinitialize-instance :around
((object updatable-object-mixin) &rest reinitargs)
(let ((before (apply #'before-reinitialization object reinitargs)))
(call-next-method)
(let ((update-args
(apply #'after-reinitialization object before reinitargs)))
(map-dependents object #'update-dependent object update-args))))
I don't see how this can work if reinitialize-instance changes the set
of dependents. The map-dependents will map over the new dependents, and
any old dependents that were removed will never be updated. Maybe you
can say that remove-dependent, or by convention each caller of it, calls
update-dependent or a variant of it on the dependent being removed.
However, I suspect that is not flexible enough. I know some of our
analogues to this have to start by collecting all the dependents into a
table that is independent of the dependency structure. I don't have an
answer here; I think more thought is required.
As Danny said, the method on reinitialize-instance itself wan't intended
to change the set of dependents. We could get that functionality easily
enough by having the :around method collect all the dependents ahead of
time as you mentioned. We will make this change.
If that's true I would prefer to have the style (collecting lists of values
returned by each interested method, and taking them apart again) be enforced
by method combination, instead of leaving it up to each programmer to get
it right.
Also, since the style you propose depends on three methods for three different
generic functions to be kept in sync, and does something unpredictable without
necessarily signalling an error if one of the methods is left out, it doesn't
seem very robust. I would prefer to see either a more abstract data structure
than a list, so that leaving out a method (or forgetting to call cdr) for one
class would not damage the data seen by other class's methods, or else to use
one generic function instead of three, so that all the code for one class would
be in a single place and hence less likely to be out of sync. In the latter
case, this generic function would be called multiple times and one of its
arguments would indicate whether state was being collected or
distributed.
I think these might be good ideas. Unfortunately, in the abscence of a
specific proposal for how to make this work I think we are going to make
only the two changes described in this message. We don't have the time
to figure out how to incorporate this comment given that what we have
will clearly work.
-------