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

Reply via email to