Email list hosting service & mailing list manager

Redefinition of the setter Lars Thomas Hansen 17 Jan 2000 16:04 UTC

I think the hedge in the specification

 >However, I do suggest a rule that that once a setter has been specified
 >for a procedure, then changing the setter property to something else is
 >undefined. This would allow a compiler to optimize setter calls to the
 >same extent that resolve (or inline) calls to specific functions. I see
 >no use for being able to change the setter property once set, except
 >perhaps for debugging.

is not in the spirit of the language and has little practical value.

Say I have a record type Point with a field x and operations

  (define point-x ...)
  (define point-x-set! ...)
  (set! (setter point-x) point-x-set!)

The restriction in the spec guarantees that in cases where the compiler
can determine that point-x has not changed, (setter point-x) also has
not changed.  Without this restriction, the compiler could statically
determine that (setter point-x) has not changed only in cases where all
uses of point-x can be determined, and none of those uses are an
expression like

	(set! (setter point-x) ...)

If all changes to point-x are statically visible, then the compiler is
better off with the restriction: in systems with a module system, in
particular, the restriction may allow the compiler to generate better
code.  But in a system with a module system the compiler may also be
able to perform the analysis to derive the same fact.

Furthermore, it may be useful to redefine setters.  Suppose I want to
track how often point-x-set! is called.  Normally I would say

  (define point-x-set!
    (let ((point-x-set! point-x-set!))
      (lambda (p v)
	(set! point-x-set-counter (+ 1 point-x-set-counter))
	(point-x-set! p v))))

but since the old definition can be called indirectly through set! I
need to change (setter point-x) also.  If redefinition is not possible,
I'm stuck -- only because the compiler's life should be made easier!
That does not seem reasonable.

When the compiler doesn't know _what_ a particular setter is at runtime,
because the getter may change, then it must perform some sort of
run-time lookup and dispatch.  Generally it is possible to compile the
lookup into something that runs in constant time, eg. by hanging the
setter off the getter.  Whatever the technique, the setter can't (in
general) be inlined, the cost of the call will probably dominate the
cost of the lookup and the cost of the operation itself, and the
language restriction has bought us nothing.