<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Sorry for the delay; here are my comments.<br>
<br>
Meta-point: I prefer to work out these issues by first disregarding<br>
speed issues, and figuring out what the best semantics is. Then,<br>
later, if there is real need for speedup, we can do that, but keep in<br>
place the original intention of the code, for the benefit of future<br>
programmers working with the code. So, separate semantics from speed.<br>
<br>
Hans raised what I think are two separate issues, both of them very<br>
interesting, which I'd like to address separately, and I'll do it<br>
in two emails since there may be two separate threads.<br>
<br>
Using slot-value inside initialization methods.<br>
<br>
Background: Some objects have a set of invariants. To be more<br>
precise, the state of the object as seen by its callers is represented<br>
internally by more than one thing, and the state of those things must<br>
be kept consonant with each other in order for the state seen by the<br>
callers to make sense at the caller's level of abstraction. Ideally,<br>
these invariants should be carefully commented; in practice<br>
programmers often leave them out, which is too bad.<br>
<br>
A "consistent state" means that the invariants are true. When there<br>
is no method actively running that's "inside the object", i.e. at the<br>
level of abstraction below the "consistent view", namely the ones that<br>
*makes* things consistent, then the object must be consistent.<br>
<br>
The methods called by the callers (1) expect to find the object in a<br>
consistent state, and (2) must leave the object in a consistent state<br>
when they terminate, whether they terminate normally (return) or<br>
abruptly (signal, return, throw, etc.)<br>
<br>
It is possible that there are :before or :after methods on the reader<br>
or writer. In fact, it's even possible that the primary method was<br>
overridden, if this is a subclass. These methods must also keep the<br>
object in a consistent state.<br>
<br>
Under normal circumstances, to use slot-value operates at a lower<br>
level of abstraction. This is, in general, dangerous, beacause<br>
setting a slot-value could subvert the higher level's goal of keeping<br>
the object consistent. (If you are old enough to remember this, it's<br>
like "peek and poke", i.e. reading and writing words in memory that<br>
are really implementing some higher-level construct.)<br>
<br>
However, initialize-instance is not a normal circumstance.<br>
<br>
As Hans says, for a CLOS object, sometimes :initform is too simple,<br>
and you need to have an initialize-instance method. While the<br>
instance is being initialized, in general it is not yet in its<br>
consistent state. The invariant says that when the object has been<br>
created such that it's ready to be seen by callers, it must be<br>
consistent, but not until then. Therefore, you do NOT want to invoke<br>
methods during the initialize-instance that will assume that the<br>
object is consistent. That inclues :before and :after methods (and<br>
overridden primaries) of the accessors.<br>
<br>
So I think Hans is right. Not only is it OK to use slot-value here,<br>
in fact it should be mandatory, or at least recommended, or<br>
encouraged, or considered as the first option, or something.<br>
(There might be times when you really know that the<br>
method is right, although that might actually be a modularity<br>
violation; too complicated to go into here.)<br>
<br>
-- Dan<br>
<br>
Hans Hübner wrote:
<blockquote
cite="mid:AANLkTim6uAmbGNiz_C1BnfOs6D+bBPfeENQV24NBFonb@mail.gmail.com"
type="cite">
<p>Hi,</p>
<p>The company I work for has a Common Lisp style guide that
generally disallows using SLOT-VALUE. Instead, accessor should be used
so that: BEFORE and :AFTER methods are always invoked when accessing a
slot. Generally, I think this is a good idea when looking at classes
and instances from the outside. Slots should be considered as being an
implementation detail, and users (i.e. client code and derived class
methods) should not make assumptions about how functionality is
implemented.</p>
<p>Now, I often have the need for class instances that are constant
in some respect, i.e. some properties of the instance that are
implemented using slots can't directly be changed. I often declare
such slots havin only a: READER in the class definition, which makes
the read-only nature of this slot apparent right away.</p>
<p>Of course, such slots need to be initialized somehow. An :INITARG
sometimes does the trick, but it is more common that the value of such
slots is calculated and recalculated during the lifetime of the
instance, and as such the slot's value must be set.</p>
<p>Now, from the perspective of seeing the class declaration as
documenting the visible behavior of instances of a class, it does not
seem to be proper to declare an accessor to be used in class-internal
code so that the slot's value can be updated. Instead, I think that it
is better to use SLOT-VALUE to mess with the guts of an instance from
code that is part of the guts itself.</p>
<p>Of course, one may want to argue that DEFCLASS forms should not be
considered to be an interface definition. Instead, one could call for a
series of DEFGENERIC forms to define the external interface of some
"module" and make class definitions be internal. From a more practical
perspective, though, class definitions in CL serve both as interface
and implementation definition, thus it seems to be appropriate using
the mechanisms provided by CLOS to support both uses.</p>
<p>How do others use or avoid SLOT-VALUE? Is it frowned upon in your
company's or project's (verbal) style guide?</p>
<p>Thanks for your input,<br>
Hans<br>
</p>
<pre wrap="">
<hr size="4" width="90%">
_______________________________________________
pro mailing list
<a class="moz-txt-link-abbreviated" href="mailto:pro@common-lisp.net">pro@common-lisp.net</a>
<a class="moz-txt-link-freetext" href="http://common-lisp.net/cgi-bin/mailman/listinfo/pro">http://common-lisp.net/cgi-bin/mailman/listinfo/pro</a>
</pre>
</blockquote>
</body>
</html>