On 16 Nov 2010, at 11:05, Hans Hübner wrote: > Hi, > > 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. > > 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. > > 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. > > 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. > > 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. > Note that it is always possible to have several accessors with different names. So you could define something like this:
(defclass foo () ((some-slot :reader official-slot-reader :accessor %internal-slot-accessor) ...)) I recall doing this in some code. I agree that using slot-value directly is stylistically the better option, but it is not unusual that the automatically generated readers/writers are more efficient than the equivalent slot-value counterparts. > How do others use or avoid SLOT-VALUE? Is it frowned upon in your company's > or project's (verbal) style guide? > In general, I agree with you that slot-value has its uses for internal implementation details. A favorite example of mine is delayed initialization of slots: (defclass bar () ((some-slot :reader some-slot-reader))) (defmethod slot-unbound ((class t) (instance bar) (slot (eql 'some-slot))) (setf (slot-value instance 'some-slot) ... initialization code ...)) I think using a writer for such a case is conceptually wrong. (An internal writer, as above, is ok for efficiency reasons, although the performance difference shouldn't matter for such delayed initialization anyway.) Best, Pascal -- Pascal Costanza, mailto:p...@p-cos.net, http://p-cos.net Vrije Universiteit Brussel Software Languages Lab Pleinlaan 2, B-1050 Brussel, Belgium
_______________________________________________ pro mailing list pro@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/pro