In the CLHS I read for :read-only x: "When x is true, this specifies that this slot cannot be altered; it will always contain the value supplied at construction time."
Bit I can do this (CCL, SBCL):
CL-USER> (defstruct foo
(one 0 :read-only t))
FOO
CL-USER> (defparameter *foo* (make-foo))
*FOO*
CL-USER> *foo*
#S(FOO :ONE 0)
CL-USER> (setf (slot-value *foo* 'one) 1)
1 (1 bit, #x1, #o1, #b1)
CL-USER> *foo*
#S(FOO :ONE 1)
Shouldn't changing this slot be prohibited by Lisp?
slot-value is not how you access the fields of an object whose class was defined with defstruct. Such objects do not portably have named slots at all: they have named accessors.
Some implementations give the fields of such objects names, and may also allow access to them with slot-value: such behaviour is entirely nonportable however.
If you work within the language defined by the standard then you should not be able to modify the value of a structure field defined with a :read-only option.
The specification says:
setfwill not accept the reader function for this slot.
slot-value is not the reader function created by defstruct. The reader function is foo-one (unless you override the naming scheme with the :conc-name keyword). So you should get an error if you try to do
(setf (foo-one *foo) 1)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With