:immutable slot option
Immutability is far more valued nowadays than when CLOS was designed. Back then, basically the system allows programmers to change almost everything, assuming he knows what he was doing.
However, specifying something immutable is not only to protect users from shooting their own foot; it communicates to the readers. Here the readers can be a programmer who reads and uses the code years later (who can be the same programmer who wrote it bot has forgotten the details), or a program-processing programs such as optimizer to take advantage of immutablity.
CLOS (and Gauche's object system) have enough flexibility to implement immutable slots, but it is somewhat awkward. It's not as simple as having a custom setter that throws an error; for, the slot setter is also called in the instance initializer which runs at the instance construction. You have to distinguish whether the slot setter is invoked during initialization or outside initialization, but such dynamic introspection would be costly.
We came up an alternative mechanism which is effectively realizes immutable slots in practical situations, but does not require to distinguish whether it's in initialization or not.
If a slot has a true value for
:immutable slot option, the slot can only
be initialized once--that is, the setter sets the value if the slot is previously
unbound, but throws an error if not. If you give the slot an initial value,
:init-value etc., then that one chance
to set the value is used within initializer. Uninitialized immutable slots
don't make much sense, so we expect almost always immutable slots are initialized
It is possible that the initializer leaves the slot unbound, and later
the user call
slot-set! to set it once. It can be viewed as delayed
(We first named this option
init-once, for the slot can be set once,
but changed our mind for it could be confusing.)