In Practical Common Lisp chapter 17. Object Reorientation: Classes section Accessor Functions, I was finding it difficult understanding the way SETF
is being extended.
The functions:
(defun (setf customer-name) (name account)
(setf (slot-value account 'customer-name) name))
bank-account
class definition:
(defclass bank-account ()
((customer-name
:initarg :customer-name
:initform (error "Must supply a customer name."))
(balance
:initarg :balance
:initform 0)
(account-number
:initform (incf *account-numbers*))
account-type))
What I don't understand:
in the expression
(setf (customer-name my-account) "Sally Sue")
does(customer-name my-account)
return a SETFable slot-valuecustomer-name
of the the classbank-account
which thenSETF
uses to set the value to "Sally Sue"?is
(setf (customer-name my-account) "Sally Sue")
actually calling the function above?as defined above is
setf customer-name
a function?in the function above is
customer-name
in(setf customer-name)
and'customer-name
in the body referring to the same thing?the section states
second element is a symbol, typically the name of a function used to access the place the SETF function will set
if that's the case then why use the
slot-value
function inside the function's definition when the function can be used to access the place?
In many cases accessing and setting data, one needs two things:
Thus one would define a setter function and a getter function. For simple cases they also may look simple. But for complex cases they may not. Now if you know the name of the getter, what is the name of the setter? Or: if you know the name of the setter, what is the name of the getter?
Common Lisp has the idea that you only need to know the name of the getter.
the getter is called, say,
GET-FOO
then the setter function is called
(SETF GET-FOO)
. Always.the setter function can be invoked this way:
(setf (get-foo some-bar) new-foo)
. Always.So you write the
GET-FOO
function. You also write the(SETF GET-FOO)
function and Common Lisp registers it as a setter function.(SETF GET-FOO)
is a list. It's also the name of a function. Here we have the exception: Common Lisp sometimes allows a list as a function name. Thus not all function names are symbols, some are actually lists.(setf (customer-name my-account) "Sally Sue")
is actually a call the the defined setter.my-account
is a variable whose value will be bound to theaccount
variable of the setter."Sally Sue"
is a string and it will be bound to thename
variable of the setter.As a developer you only have to know the getter:
use of the getter:
(customer-name my-account)
use of the setter:
(setf (customer-name my-account) "Sally Sue")
.SETF
is a macro, which expands into a call of the setter function.Above defines a setter function called
(setf customer-name)
.When the function gets called via the
SETF
macro, it calls another setter - this time using the access to a slot value via the slot name.