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:[email protected], http://p-cos.net
Vrije Universiteit Brussel
Software Languages Lab
Pleinlaan 2, B-1050 Brussel, Belgium
_______________________________________________
pro mailing list
[email protected]
http://common-lisp.net/cgi-bin/mailman/listinfo/pro