Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does using the SETF function to extend SETF work?

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-value customer-name of the the class bank-account which then SETF 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?

like image 557
Bleeding Fingers Avatar asked Jun 06 '14 21:06

Bleeding Fingers


People also ask

What is setf function in Lisp?

setf is actually a macro that examines an access form and produces a call to the corresponding update function. Given the existence of setf in Common Lisp, it is not necessary to have setq, rplaca, and set; they are redundant. They are retained in Common Lisp because of their historical importance in Lisp.

What is the difference between Setf and SETQ?

What is the difference between setf and setq? Explanation: Setq is used only for setting the values of symbols but setf can be used for anything. Setf can be used for setting value of any data-type and not only symbols.

What is SETQ in Lisp?

(setq var1 form1 var2 form2 ...) is the simple variable assignment statement of Lisp. First form1 is evaluated and the result is stored in the variable var1, then form2 is evaluated and the result stored in var2, and so forth. setq may be used for assignment of both lexical and dynamic variables.

What is let in Lisp?

The let expression is a special form in Lisp that you will need to use in most function definitions. let is used to attach or bind a symbol to a value in such a way that the Lisp interpreter will not confuse the variable with a variable of the same name that is not part of the function.


1 Answers

In many cases accessing and setting data, one needs two things:

  • a way to retrieve something from a data-structure
  • a way to set something in a data-structure

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 the account variable of the setter. "Sally Sue" is a string and it will be bound to the name 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.

(defun (setf customer-name) (name account)
  (setf (slot-value account 'customer-name) name))

Above defines a setter function called (setf customer-name).

CL-USER 80 > (function (setf customer-name))
#<interpreted function (SETF CUSTOMER-NAME) 40A00213FC>

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.

like image 93
Rainer Joswig Avatar answered Nov 02 '22 08:11

Rainer Joswig