Skip to content

Commit

Permalink
functions: setf functions better example
Browse files Browse the repository at this point in the history
for #544
  • Loading branch information
vindarel committed Jun 28, 2024
1 parent e808650 commit 0d02396
Showing 1 changed file with 33 additions and 15 deletions.
48 changes: 33 additions & 15 deletions functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -643,29 +643,47 @@ first one, and where the first argument is the new value:
body)
~~~

This mechanism is particularly used for CLOS methods.
This mechanism is often used for CLOS methods.

A silly example:
Let's work towards an example. Let's say we manipulate a hash-table
that represents a square. We store the square width in this
hash-table:

~~~lisp
(defparameter *current-name* ""
"A global name.")
(defparameter *square* (make-hash-table))
(setf (gethash :width *square*) 21)
~~~

(defun hello (name)
(format t "hello ~a~&" name))
During our program life cycle, we can change the square width, with `setf` as we did above.

(defun (setf hello) (new-value)
(hello new-value)
(setf *current-name* new-value)
(format t "current name is now ~a~&" new-value))
We define a function to compute a square area. We don't store it in
the hash-table as it is redundant with the dimension.

(setf (hello) "Alice")
;; hello Alice
;; current name is now Alice
;; NIL
~~~lisp
(defun area (square)
(expt (gethash :width square) 2))
~~~

Now, our programming needs lead to the situation where it would be
very handy to change the *area* of the square… and have this reflected
on the square's dimensions. It can be ergonomic for your program's
application interface to define a setf-function, like this:

~~~lisp
(defun (setf area) (new-area square)
(let ((width (sqrt new-area)))
(setf (gethash :width square) width)))
~~~

<a name="curry"></a>
And now you can do:

~~~lisp
(setf (area *SQUARE*) 100)
;; => 10.0
~~~

and check your square (`describe`, `inspect`…), the new width was set.


## Currying

Expand Down

0 comments on commit 0d02396

Please sign in to comment.