I am reading the book Object-Oriented Programming in Common Lisp by Sonja Keene.
In Chapter 9, the author presents the following example:
(defclass window ()
((x :initarg :x-position :accessor x-position)
(y :initarg :y-position :accessor y-position)
(height :initarg :height :accessor window-height)
(width :initarg :width :accessor window-width)
(exposed-p :initform nil :accessor exposed-p))
(:documentation "Foundation of all windows"))
I know the use of :
, ::
or its absence goes beyond pure notation in Common Lisp when talking about packages. There is a logic behind its use!
However, I cannot see a logic behind the use of :
on slot options/specifiers. For instance, consider the example above.
Look at the first slot, the x
. There is the slot option :initarg
associated with :x-position
. OK, both include :
.
Now, on the same slot, look to the :accessor
slot option. It includes the double dot :
. However, the x-position
associated with it does not include the :
.
Is there some logic behind this syntax?
The best hypothesis I have is that the syntax design is used to reflect the difference of moments when dealing with the instances. Thus, the absence of the double-dot would indicate an use related to pos-initialization and the inclusion of the double would be related to the on-going initialization process:
CL-USER> (x-position (make-instance 'window :x-position 3))
3
Is there something else? Did I miss something? Is it pure syntax convention and what I said is just a coincidence?
Thanks
CodePudding user response:
The :accessor
option is used to define a method name. Function names should always be in the application's package, so that you don't have conflicts between two packages that define a slot with the same name.
If you used a keyword :x-position
, and some other package did the same thing, they would conflict with each other.
CodePudding user response:
Remember, a single colon means that the symbol :bar
- is a keyword
- and is in the keyword package
- and is exported from the keyword package
- and has the constant value of itself (->
:bar
).
Try
(defclass foo ()
((x
:initarg x-position
:accessor x-position)))
* (make-instance 'foo 'x-position 3)
#<FOO {7007741DD3}>
* (x-position *)
3
and
(defclass foo ()
((x
:initarg x-position
:accessor :x-position)))
* (make-instance 'foo 'x-position 4)
#<FOO {700778D473}>
* (:x-position *)
4
The initialization argument is a keyword argument to the function make-instance
(and related). The accessor is the name of a function and the name of a setf accessor.
One can make the initarg any symbol, instead of a keyword symbol. It's just usual a keyword, since generally function keywords are given with keyword symbols.
One can also try to make the accessor name a symbol and not specifically a keyword symbol. An implementation might or might not support that. It would mean that the implementation needs to support keywords as function names.
Style and Convention
Usually we write the initarg option as a keyword symbol and the accessor option as a non-keyword symbol.