How to use the SETF function to extend the operation of SETF?

In Practical General Lisp Chapter 17. Reorienting Objects: Classes in the Access Functions Section, it was difficult for me to understand how SETF extends.

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 do not understand:

  • in the expression (setf (customer-name my-account) "Sally Sue") returns (customer-name my-account) the SETFable customer-name value for the bank-account class, which then SETF uses to set the value to "Sally Sue"?

  • is there (setf (customer-name my-account) "Sally Sue") , actually calling the function above?

  • as defined above, is the setf customer-name function?

  • in the above customer-name function in (setf customer-name) and 'customer-name in body related to the same thing?

  • section state

    the second element is a symbol, usually the name of the function used to access the place where the SETF function will be installed

    if in this case why use the slot-value function inside the function definition when this function can be used to access this place?

+6
source share
2 answers

In many cases, accessing and configuring data requires two things:

  • way to get something from a data structure
  • way to set something in the data structure

Thus, one could define the setter function and the getter function. For simple cases, they can also look simple. But for complex cases, they cannot. Now, if you know the name of the recipient, what is the name of the setter? Or: if you know the name of the setter, then what is the name of the recipient?

In general, Lisp has the idea that you only need to know the name of the recipient.

  • getter called let's say GET-FOO

  • then the setter function is called (SETF GET-FOO) . Always.

  • The setter function can be called as follows: (setf (get-foo some-bar) new-foo) . Always.

So you are writing a GET-FOO function. You also write a function (SETF GET-FOO) , and Common Lisp registers it as a setter function.

(SETF GET-FOO) is a list. This is also the name of the function. Here we have an exception: Common Lisp sometimes allows a list as a function name. Thus, not all function names are characters, some are actually lists.

(setf (customer-name my-account) "Sally Sue") actually a call to the given setter. my-account is a variable whose value will be bound to the account variable of the installer. "Sally Sue" is a string and it will be bound to the installer name variable.

As a developer, you only need to know the recipient:

  • recipient use: (customer-name my-account)

  • installer usage: (setf (customer-name my-account) "Sally Sue") . SETF is a macro that expands into a call to the setter function.

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

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

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

When a function is called with the SETF macro, it calls another setter - this time using access to the slot value through the slot name.

+7
source

setf is a very complex macro that can decode its first argument, which usually looks like a function call, like "place", and then calls all the forms necessary to set the place to a new value. It is not useful to think of (customer-name my-account) as returning something in a setf statement. The setf macro applies the rules defined in HyperSpec to its place form and, as a default case, converts

 (setf (foo arg0 arg1 ...) new-val) 

to

 (funcall #'(setf foo) new-val arg0 arg1 ...) 

A walkthrough in Practical Common Lisp explains in a somewhat elliptical way what happens behind the scenes when you specify the :accessor option in the defclass slot defclass .

+1
source

Source: https://habr.com/ru/post/970487/


All Articles