<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On 16 Nov 2010, at 11:05, Hans Hübner wrote:</div><br class="Apple-interchange-newline"><blockquote 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></blockquote><div>Note that it is always possible to have several accessors with different names. So you could define something like this:</div><div><br></div><div>(defclass foo ()</div><div>  ((some-slot :reader official-slot-reader :accessor %internal-slot-accessor) ...))</div><div><br></div><div>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.</div><blockquote type="cite"><p>How do others use or avoid SLOT-VALUE? Is it frowned upon in your company's or project's (verbal) style guide?</p></blockquote></div><div>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:</div><div><br></div><div>(defclass bar ()</div><div>  ((some-slot :reader some-slot-reader)))</div><div><br></div><div>(defmethod slot-unbound ((class t) (instance bar) (slot (eql 'some-slot)))</div><div>   (setf (slot-value instance 'some-slot)</div><div>           ... initialization code ...))</div><div><br></div><div>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.)</div><div><br></div><div><br></div><div>Best,</div><div>Pascal</div><br><div>
<span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; -webkit-text-decorations-in-effect: none; text-indent: 0px; -webkit-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>-- </div><div>Pascal Costanza, <a href="mailto:pc@p-cos.net">mailto:pc@p-cos.net</a>, <a href="http://p-cos.net">http://p-cos.net</a></div><div>Vrije Universiteit Brussel</div><div>Software Languages Lab</div><div>Pleinlaan 2, B-1050 Brussel, Belgium</div><div><br></div></div></span></div></span></div></span></div></span></div></span></div></span><br class="Apple-interchange-newline"></div></span><br class="Apple-interchange-newline"></div></span><br class="Apple-interchange-newline"></span><br class="Apple-interchange-newline">
</div>

<br></body></html>