1
0
Fork 0
cl-sites/lispcookbook.github.io/cl-cookbook/functions.html

811 lines
28 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta name="generator" content=
"HTML Tidy for HTML5 for Linux version 5.2.0">
<title>Functions</title>
<meta charset="utf-8">
<meta name="description" content="A collection of examples of using Common Lisp">
<meta name="viewport" content=
"width=device-width, initial-scale=1">
<link rel="icon" href=
"assets/cl-logo-blue.png"/>
<link rel="stylesheet" href=
"assets/style.css">
<script type="text/javascript" src=
"assets/highlight-lisp.js">
</script>
<script type="text/javascript" src=
"assets/jquery-3.2.1.min.js">
</script>
<script type="text/javascript" src=
"assets/jquery.toc/jquery.toc.min.js">
</script>
<script type="text/javascript" src=
"assets/toggle-toc.js">
</script>
<link rel="stylesheet" href=
"assets/github.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<h1 id="title-xs"><a href="index.html">The Common Lisp Cookbook</a> &ndash; Functions</h1>
<div id="logo-container">
<a href="index.html">
<img id="logo" src="assets/cl-logo-blue.png"/>
</a>
<div id="searchform-container">
<form onsubmit="duckSearch()" action="javascript:void(0)">
<input id="searchField" type="text" value="" placeholder="Search...">
</form>
</div>
<div id="toc-container" class="toc-close">
<div id="toc-title">Table of Contents</div>
<ul id="toc" class="list-unstyled"></ul>
</div>
</div>
<div id="content-container">
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> &ndash; Functions</h1>
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
<!-- <p class="announce"> -->
<!-- 📢 🤶 ⭐ -->
<!-- <a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a> -->
<!-- <strong> -->
<!-- Recently added: 18 videos on MACROS. -->
<!-- </strong> -->
<!-- <a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>. -->
<!-- </p> -->
<p class="announce">
📢 New videos: <a href="https://www.youtube.com/watch?v=h_noB1sI_e8">web dev demo part 1</a>, <a href="https://www.youtube.com/watch?v=xnwc7irnc8k">dynamic page with HTMX</a>, <a href="https://www.youtube.com/watch?v=Zpn86AQRVN8">Weblocks demo</a>
</p>
<p class="announce-neutral">
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
</p>
<div id="content"
<p><a name="return"></a></p>
<h2 id="named-functions-defun">Named functions: <code>defun</code></h2>
<p>Creating named functions is done with the <code>defun</code> keyword. It follows this model:</p>
<pre><code class="language-lisp">(defun &lt;name&gt; (list of arguments)
"docstring"
(function body))
</code></pre>
<p>The return value is the value returned by the last expression of the body
(see below for more). There is no “return xx” statement.</p>
<p>So, for example:</p>
<pre><code class="language-lisp">(defun hello-world ()
;; ^^ no arguments
(print "hello world!"))
</code></pre>
<p>Call it:</p>
<pre><code class="language-lisp">(hello-world)
;; "hello world!" &lt;-- output
;; "hello world!" &lt;-- a string is returned.
</code></pre>
<h2 id="arguments">Arguments</h2>
<h3 id="base-case-required-arguments">Base case: required arguments</h3>
<p>Add in arguments like this:</p>
<pre><code class="language-lisp">(defun hello (name)
"Say hello to `name'."
(format t "hello ~a !~&amp;" name))
;; HELLO
</code></pre>
<p>(where <code>~a</code> is the most used <code>format</code> directive to print a variable
<em>aesthetically</em> and <code>~&amp;</code> prints a newline)</p>
<p>Call the function:</p>
<pre><code class="language-lisp">(hello "me")
;; hello me ! &lt;-- this is printed by `format`
;; NIL &lt;-- return value: `format t` prints a string
;; to standard output and returns nil.
</code></pre>
<p>If you dont specify the right amount of arguments, youll be trapped
into the interactive debugger with an explicit error message:</p>
<p>(hello)</p>
<blockquote>
<p>invalid number of arguments: 0</p>
</blockquote>
<h3 id="optional-arguments-optional">Optional arguments: <code>&amp;optional</code></h3>
<p>Optional arguments are declared after the <code>&amp;optional</code> keyword in the
lambda list. They are ordered, they must appear one after another.</p>
<p>This function:</p>
<pre><code class="language-lisp">(defun hello (name &amp;optional age gender) …)
</code></pre>
<p>must be called like this:</p>
<pre><code class="language-lisp">(hello "me") ;; a value for the required argument,
;; zero optional arguments
(hello "me" "7") ;; a value for age
(hello "me" 7 :h) ;; a value for age and gender
</code></pre>
<h3 id="named-parameters-key">Named parameters: <code>&amp;key</code></h3>
<p>It is not always convenient to remember the order of the arguments. It
is thus possible to supply arguments by name: we declare them using
<code>&amp;key &lt;name&gt;</code>, we set them with <code>:name &lt;value&gt;</code> in the function call,
and we use <code>name</code> as a regular variable in the function body. They are
<code>nil</code> by default.</p>
<pre><code class="language-lisp">(defun hello (name &amp;key happy)
"If `happy' is `t', print a smiley"
(format t "hello ~a " name)
(when happy
(format t ":)~&amp;")))
</code></pre>
<p>The following calls are possible:</p>
<pre><code>(hello "me")
(hello "me" :happy t)
(hello "me" :happy nil) ;; useless, equivalent to (hello "me")
</code></pre>
<p>and this is not valid: <code>(hello "me" :happy)</code>:</p>
<blockquote>
<p>odd number of &amp;KEY arguments</p>
</blockquote>
<p>A similar example of a function declaration, with several key parameters:</p>
<pre><code class="language-lisp">(defun hello (name &amp;key happy lisper cookbook-contributor-p) …)
</code></pre>
<p>it can be called with zero or more key parameters, in any order:</p>
<pre><code class="language-lisp">(hello "me" :lisper t)
(hello "me" :lisper t :happy t)
(hello "me" :cookbook-contributor-p t :happy t)
</code></pre>
<p>Last but not least, you would quickly realize it, but we can choose the keys programmatically (they can be variables):</p>
<pre><code class="language-lisp">(let ((key :happy)
(val t))
(hello "me" key val))
;; hello me :)
;; NIL
</code></pre>
<h4 id="mixing-optional-and-key-parameters">Mixing optional and key parameters</h4>
<p>It is generally a style warning, but it is possible.</p>
<pre><code class="language-lisp">(defun hello (&amp;optional name &amp;key happy)
(format t "hello ~a " name)
(when happy
(format t ":)~&amp;")))
</code></pre>
<p>In SBCL, this yields:</p>
<pre><code>; in: DEFUN HELLO
; (SB-INT:NAMED-LAMBDA HELLO
; (&amp;OPTIONAL NAME &amp;KEY HAPPY)
; (BLOCK HELLO (FORMAT T "hello ~a " NAME) (WHEN HAPPY (FORMAT T ":)~&amp;"))))
;
; caught STYLE-WARNING:
; &amp;OPTIONAL and &amp;KEY found in the same lambda list: (&amp;OPTIONAL (NAME "John") &amp;KEY
; HAPPY)
;
; compilation unit finished
; caught 1 STYLE-WARNING condition
</code></pre>
<p>We can call it:</p>
<pre><code class="language-lisp">(hello "me" :happy t)
;; hello me :)
;; NIL
</code></pre>
<h3 id="default-values-to-key-parameters">Default values to key parameters</h3>
<p>In the lambda list, use pairs to give a default value to an optional or a key argument, like <code>(happy t)</code> below:</p>
<pre><code class="language-lisp">(defun hello (name &amp;key (happy t))
</code></pre>
<p>Now <code>happy</code> is true by default.</p>
<h3 id="was-a-key-parameter-specified">Was a key parameter specified?</h3>
<p>You can skip this tip for now if you want, but come back later to it as it can turn handy.</p>
<p>We saw that a default key parameter is <code>nil</code> by default (<code>(defun hello
(name &amp;key happy) …)</code>). But how can be distinguish between “the value
is NIL by default” and “the user wants it to be NIL”?</p>
<p>We saw how to use a tuple to set its default value:</p>
<p><code>&amp;key (:happy t)</code></p>
<p>To answer our question, use a triple like this:</p>
<p><code>&amp;key (happy t happy-p)</code></p>
<p>where <code>happy-p</code> serves as a <em>predicate</em> variable (using <code>-p</code> is only a
convention, give it the name you want) to know if the key was
supplied. If it was, then it will be <code>T</code>.</p>
<p>So now, we will print a sad face if <code>:happy</code> was explicitely set to
NIL. We dont print it by default.</p>
<pre><code class="language-lisp">(defun hello (name &amp;key (happy nil happy-p))
(format t "Key supplied? ~a~&amp;" happy-p)
(format t "hello ~a " name)
(when happy-p
(if happy
(format t ":)")
(format t ":("))))
</code></pre>
<h3 id="variable-number-of-arguments-rest">Variable number of arguments: <code>&amp;rest</code></h3>
<p>Sometimes you want a function to accept a variable number of
arguments. Use <code>&amp;rest &lt;variable&gt;</code>, where <code>&lt;variable&gt;</code> will be a list.</p>
<pre><code class="language-lisp">(defun mean (x &amp;rest numbers)
(/ (apply #'+ x numbers)
(1+ (length numbers))))
</code></pre>
<pre><code class="language-lisp">(mean 1)
(mean 1 2) ;; =&gt; 3/2 (yes, it is printed as a ratio)
(mean 1 2 3 4 5) ;; =&gt; 3
</code></pre>
<h3 id="defining-key-arguments-and-allowing-more-allow-other-keys">Defining key arguments, and allowing more: <code>&amp;allow-other-keys</code></h3>
<p>Observe:</p>
<pre><code class="language-lisp">(defun hello (name &amp;key happy)
(format t "hello ~a~&amp;" name))
(hello "me" :lisper t)
;; =&gt; Error: unknown keyword argument
</code></pre>
<p>whereas</p>
<pre><code class="language-lisp">(defun hello (name &amp;key happy &amp;allow-other-keys)
(format t "hello ~a~&amp;" name))
(hello "me" :lisper t)
;; hello me
</code></pre>
<p>We might need <code>&amp;allow-other-keys</code> when passing around arguments or
with higher level manipulation of functions.</p>
<p>Heres a real example. We define a function to open a file that always
uses <code>:if-exists :supersede</code>, but still passes any other keys to the
<code>open</code> function.</p>
<pre><code class="language-lisp">(defun open-supersede (f &amp;rest other-keys &amp;key &amp;allow-other-keys)
(apply #'open f :if-exists :supersede other-keys))
</code></pre>
<p>In the case of a duplicated <code>:if-exists</code> argument, our first one takes precedence.</p>
<h2 id="return-values">Return values</h2>
<p>The return value of the function is the value returned by the last
executed form of the body.</p>
<p>There are ways for non-local exits (<code>return-from &lt;function name&gt; &lt;value&gt;</code>), but they are usually not needed.</p>
<p>Common Lisp has also the concept of multiple return values.</p>
<h3 id="multiple-return-values-values-multiple-value-bind-and-nth-value">Multiple return values: <code>values</code>, <code>multiple-value-bind</code> and <code>nth-value</code></h3>
<p>Returning multiple values is <em>not</em> like returning a tuple or a list of
results ;) This is a common misconception.</p>
<p>Multiple values are specially useful and powerful because a change in
them needs little to no refactoring.</p>
<pre><code class="language-lisp">(defun foo (a b c)
a)
</code></pre>
<p>This function returns <code>a</code>.</p>
<pre><code class="language-lisp">(defvar *res* (foo :a :b :c))
;; :A
</code></pre>
<p>We use <code>values</code> to return multiple values:</p>
<pre><code class="language-lisp">(defun foo (a b c)
(values a b c))
</code></pre>
<pre><code class="language-lisp">(setf *res* (foo :a :b :c))
;; :A
</code></pre>
<p>Observe here that <code>*res*</code> <em>is still <code>:A</code></em>.</p>
<p>All functions that use the return value of <code>foo</code> need <em>not</em> to change, they
still work. If we had returned a list or an array, this would be
different.</p>
<p><strong>multiple-value-bind</strong></p>
<p>We destructure multiple values with <code>multiple-value-bind</code> (or
<code>mvb</code>+TAB in Slime for short) and we can get one given its position
with <code>nth-value</code>:</p>
<pre><code class="language-lisp">(multiple-value-bind (res1 res2 res3)
(foo :a :b :c)
(format t "res1 is ~a, res2 is ~a, res2 is ~a~&amp;"
res1 res2 res3))
;; res1 is A, res2 is B, res2 is C
;; NIL
</code></pre>
<p>Its general form is</p>
<pre><code class="language-lisp">(multiple-value-bind (var-1 .. var-n) expr
body)
</code></pre>
<p>The variables <code>var-n</code> are not available outside the scope of <code>multiple-value-bind</code>.</p>
<p>With <strong>nth-value</strong>:</p>
<pre><code class="language-lisp">(nth-value 0 (values :a :b :c)) ;; =&gt; :A
(nth-value 2 (values :a :b :c)) ;; =&gt; :C
(nth-value 9 (values :a :b :c)) ;; =&gt; NIL
</code></pre>
<p>Look here too that <code>values</code> is different from a list:</p>
<pre><code class="language-lisp">(nth-value 0 '(:a :b :c)) ;; =&gt; (:A :B :C)
(nth-value 1 '(:a :b :c)) ;; =&gt; NIL
</code></pre>
<p>Note that <code>(values)</code> with no values returns… no values at all.</p>
<p><strong>multiple-value-list</strong></p>
<p>While we are at it: <a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_mult_1.htm">multiple-value-list</a> turns multiple values to a list:</p>
<pre><code class="language-lisp">(multiple-value-list (values 1 2 3))
;; (1 2 3)
</code></pre>
<p>The reverse is <strong>values-list</strong>, it turns a list to multiple values:</p>
<pre><code class="language-lisp">(values-list '(1 2 3))
;; 1
;; 2
;; 3
</code></pre>
<h2 id="anonymous-functions-lambda">Anonymous functions: <code>lambda</code></h2>
<p>Anonymous functions are created with <code>lambda</code>:</p>
<pre><code class="language-lisp">(lambda (x) (print x))
</code></pre>
<p>We can call a lambda with <code>funcall</code> or <code>apply</code> (see below).</p>
<p>If the first element of an unquoted list is a lambda expression, the
lambda is called:</p>
<pre><code class="language-lisp">((lambda (x) (print x)) "hello")
;; hello
</code></pre>
<h2 id="calling-functions-programmatically-funcall-and-apply">Calling functions programmatically: <code>funcall</code> and <code>apply</code></h2>
<p><code>funcall</code> is to be used with a known number of arguments, when <code>apply</code>
can be used on a list, for example from <code>&amp;rest</code>:</p>
<pre><code class="language-lisp">(funcall #'+ 1 2)
(apply #'+ '(1 2))
</code></pre>
<h3 id="referencing-functions-by-name-single-quote--or-sharpsign-quote-">Referencing functions by name: single quote <code>'</code> or sharpsign-quote <code>#'</code>?</h3>
<p>In the example above, we used <code>#'</code>, but a single quote also works, and
we can encounter it in the wild. Which one to use?</p>
<p>It is generally safer to use <code>#'</code>, because it respects lexical scope. Observe:</p>
<pre><code class="language-lisp">(defun foo (x)
(* x 100))
(flet ((foo (x) (1+ x)))
(funcall #'foo 1))
;; =&gt; 2, as expected
;; But:
(flet ((foo (x) (1+ x)))
(funcall 'foo 1))
;; =&gt; 100
</code></pre>
<p><code>#'</code> is actually the shorthand for <code>(function …)</code>:</p>
<pre><code class="language-lisp">(function +)
;; #&lt;FUNCTION +&gt;
(flet ((foo (x) (1+ x)))
(print (function foo))
(funcall (function foo) 1))
;; #&lt;FUNCTION (FLET FOO) {1001C0ACFB}&gt;
;; 2
</code></pre>
<p>Using <code>function</code> or the <code>#'</code> shorthand allows us to refer to local
functions. If we pass instead a symbol to <code>funcall</code>, what is
called is always the function named by that symbol in the <em>global environment</em>.</p>
<p>In addition, <code>#'</code> catches the function by value. If the function is redefined, bindings that refered to this function by <code>#'</code> will still run its original behaviour.</p>
<p>Lets assign a function to a parameter:</p>
<pre><code class="language-lisp">(defparameter *foo-caller* #'foo)
(funcall *foo-caller* 1)
;; =&gt; 100
</code></pre>
<p>Now, if we redefine <code>foo</code>, the behaviour of <code>*foo-caller*</code> will <em>not</em> change:</p>
<pre><code class="language-lisp">(defun foo (x) (1+ x))
;; WARNING: redefining CL-USER::FOO in DEFUN
;; FOO
(funcall *foo-caller* 1)
;; 100 ;; and not 2
</code></pre>
<p>If we bind the caller with <code>'foo</code>, a single quote, the function will be resolved at runtime:</p>
<pre><code class="language-lisp">(defun foo (x) (* x 100)) ;; back to original behavior.
(defparameter *foo-caller-2* 'foo)
;; *FOO-CALLER-2*
(funcall *foo-caller-2* 1)
;; 100
;; We change the definition:
(defun foo (x) (1+ x))
;; WARNING: redefining CL-USER::FOO in DEFUN
;; FOO
;; We try again:
(funcall *foo-caller-2* 1)
;; 2
</code></pre>
<p>The behaviour you want depends on your use case. Generally, using sharpsign-quote is less surprising. But if you are running a tight loop and you want live-update mechanisms (think a game or live visualisations), you might want to use a single quote so that your loop picks up the users new function definition.</p>
<h2 id="higher-order-functions-functions-that-return-functions">Higher order functions: functions that return functions</h2>
<p>Writing functions that return functions is simple enough:</p>
<pre><code class="language-lisp">(defun adder (n)
(lambda (x) (+ x n)))
;; ADDER
</code></pre>
<p>Here we have defined the function <code>adder</code> which returns an <em>object</em> of <em>type</em> <a href="http://www.lispworks.com/documentation/HyperSpec/Body/t_fn.htm"><code>function</code></a>.</p>
<p>To call the resulting function, we must use <code>funcall</code> or <code>apply</code>:</p>
<pre><code class="language-lisp">(adder 5)
;; #&lt;CLOSURE (LAMBDA (X) :IN ADDER) {100994ACDB}&gt;
(funcall (adder 5) 3)
;; 8
</code></pre>
<p>Trying to call it right away leads to an illegal function call:</p>
<pre><code class="language-lisp">((adder 3) 5)
In: (ADDER 3) 5
((ADDER 3) 5)
Error: Illegal function call.
</code></pre>
<p>Indeed, CL has different <em>namespaces</em> for functions and variables, i.e. the same <em>name</em> can refer to different things depending on its position in a form thats evaluated.</p>
<pre><code class="language-lisp">;; The symbol foo is bound to nothing:
CL-USER&gt; (boundp 'foo)
NIL
CL-USER&gt; (fboundp 'foo)
NIL
;; We create a variable:
CL-USER&gt; (defparameter foo 42)
FOO
* foo
42
;; Now foo is "bound":
CL-USER&gt; (boundp 'foo)
T
;; but still not as a function:
CL-USER&gt; (fboundp 'foo)
NIL
;; So let's define a function:
CL-USER&gt; (defun foo (x) (* x x))
FOO
;; Now the symbol foo is bound as a function too:
CL-USER&gt; (fboundp 'foo)
T
;; Get the function:
CL-USER&gt; (function foo)
#&lt;FUNCTION FOO&gt;
;; and the shorthand notation:
* #'foo
#&lt;FUNCTION FOO&gt;
;; We call it:
(funcall (function adder) 5)
#&lt;CLOSURE (LAMBDA (X) :IN ADDER) {100991761B}&gt;
;; and call the lambda:
(funcall (funcall (function adder) 5) 3)
8
</code></pre>
<p>To simplify a bit, you can think of each symbol in CL having (at least) two “cells” in which information is stored. One cell - sometimes referred to as its <em>value cell</em> - can hold a value that is <em>bound</em> to this symbol, and you can use <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_boundp.htm"><code>boundp</code></a> to test whether the symbol is bound to a value (in the global environment). You can access the value cell of a symbol with <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_symb_5.htm"><code>symbol-value</code></a>.</p>
<p>The other cell - sometimes referred to as its <em>function cell</em> - can hold the definition of the symbols (global) function binding. In this case, the symbol is said to be <em>fbound</em> to this definition. You can use <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_fbound.htm"><code>fboundp</code></a> to test whether a symbol is fbound. You can access the function cell of a symbol (in the global environment) with <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_symb_1.htm"><code>symbol-function</code></a>.</p>
<p>Now, if a <em>symbol</em> is evaluated, it is treated as a <em>variable</em> in that its value cell is returned (just <code>foo</code>). If a <em>compound form</em>, i.e. a <em>cons</em>, is evaluated and its <em>car</em> is a symbol, then the function cell of this symbol is used (as in <code>(foo 3)</code>).</p>
<p>In Common Lisp, as opposed to Scheme, it is <em>not</em> possible that the car of the compound form to be evaluated is an arbitrary form. If it is not a symbol, it <em>must</em> be a <em>lambda expression</em>, which looks like <code>(lambda </code><em>lambda-list</em> <em>form*</em><code>)</code>.</p>
<p>This explains the error message we got above - <code>(adder 3)</code> is neither a symbol nor a lambda expression.</p>
<p>If we want to be able to use the symbol <code>*my-fun*</code> in the car of a compound form, we have to explicitly store something in its <em>function cell</em> (which is normally done for us by the macro <a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_defun.htm"><code>defun</code></a>):</p>
<pre><code class="language-lisp">;;; continued from above
CL-USER&gt; (fboundp '*my-fun*)
NIL
CL-USER&gt; (setf (symbol-function '*my-fun*) (adder 3))
#&lt;CLOSURE (LAMBDA (X) :IN ADDER) {10099A5EFB}&gt;
CL-USER&gt; (fboundp '*my-fun*)
T
CL-USER&gt; (*my-fun* 5)
8
</code></pre>
<p>Read the CLHS section about <a href="http://www.lispworks.com/documentation/HyperSpec/Body/03_aba.htm">form evaluation</a> for more.</p>
<h2 id="closures">Closures</h2>
<p>Closures allow to capture lexical bindings:</p>
<pre><code class="language-lisp">(let ((limit 3)
(counter -1))
(defun my-counter ()
(if (&lt; counter limit)
(incf counter)
(setf counter 0))))
(my-counter)
0
(my-counter)
1
(my-counter)
2
(my-counter)
3
(my-counter)
0
</code></pre>
<p>Or similarly:</p>
<pre><code class="language-lisp">(defun repeater (n)
(let ((counter -1))
(lambda ()
(if (&lt; counter n)
(incf counter)
(setf counter 0)))))
(defparameter *my-repeater* (repeater 3))
;; *MY-REPEATER*
(funcall *my-repeater*)
0
(funcall *my-repeater*)
1
(funcall *my-repeater*)
2
(funcall *my-repeater*)
3
(funcall *my-repeater*)
0
</code></pre>
<p>See more on <a href="http://www.gigamonkeys.com/book/variables.html">Practical Common Lisp</a>.</p>
<h2 id="setf-functions"><code>setf</code> functions</h2>
<p>A function name can also be a list of two symbols with <code>setf</code> as the
first one, and where the first argument is the new value:</p>
<pre><code class="language-lisp">(defun (setf &lt;name&gt;) (new-value &lt;other arguments&gt;)
body)
</code></pre>
<p>This mechanism is often used for CLOS methods.</p>
<p>Lets work towards an example. Lets say we manipulate a hash-table
that represents a square. We store the square width in this
hash-table:</p>
<pre><code class="language-lisp">(defparameter *square* (make-hash-table))
(setf (gethash :width *square*) 21)
</code></pre>
<p>During our program life cycle, we can change the square width, with <code>setf</code> as we did above.</p>
<p>We define a function to compute a square area. We dont store it in
the hash-table as it is redundant with the dimension.</p>
<pre><code class="language-lisp">(defun area (square)
(expt (gethash :width square) 2))
</code></pre>
<p>Now, our programming needs lead to the situation where it would be
very handy to change the <em>area</em> of the square… and have this reflected
on the squares dimensions. It can be ergonomic for your programs
application interface to define a setf-function, like this:</p>
<pre><code class="language-lisp">(defun (setf area) (new-area square)
(let ((width (sqrt new-area)))
(setf (gethash :width square) width)))
</code></pre>
<p>And now you can do:</p>
<pre><code class="language-lisp">(setf (area *SQUARE*) 100)
;; =&gt; 10.0
</code></pre>
<p>and check your square (<code>describe</code>, <code>inspect</code>…), the new width was set.</p>
<h2 id="currying">Currying</h2>
<h3 id="concept">Concept</h3>
<p>A related concept is that of <em><a href="https://en.wikipedia.org/wiki/Currying">currying</a></em> which you might be familiar with if youre coming from a functional language. After weve read the last section thats rather easy to implement:</p>
<pre><code class="language-lisp">CL-USER&gt; (defun curry (function &amp;rest args)
(lambda (&amp;rest more-args)
(apply function (append args more-args))))
CURRY
CL-USER&gt; (funcall (curry #'+ 3) 5)
8
CL-USER&gt; (funcall (curry #'+ 3) 6)
9
CL-USER&gt; (setf (symbol-function 'power-of-ten) (curry #'expt 10))
#&lt;Interpreted Function "LAMBDA (FUNCTION &amp;REST ARGS)" {482DB969}&gt;
CL-USER&gt; (power-of-ten 3)
1000
</code></pre>
<h3 id="with-the-alexandria-library">With the Alexandria library</h3>
<p>Now that you know how to do it, you may appreciate using the
implementation of the
<a href="https://common-lisp.net/project/alexandria/draft/alexandria.html#Data-and-Control-Flow">Alexandria</a>
library (in Quicklisp).</p>
<pre><code class="language-lisp">(ql:quickload "alexandria")
(defun adder (foo bar)
"Add the two arguments."
(+ foo bar))
(defvar add-one (alexandria:curry #'adder 1) "Add 1 to the argument.")
(funcall add-one 10) ;; =&gt; 11
(setf (symbol-function 'add-one) add-one)
(add-one 10) ;; =&gt; 11
</code></pre>
<h2 id="documentation">Documentation</h2>
<ul>
<li>functions: http://www.lispworks.com/documentation/HyperSpec/Body/t_fn.htm#function</li>
<li>ordinary lambda lists: http://www.lispworks.com/documentation/HyperSpec/Body/03_da.htm</li>
<li>multiple-value-bind: http://clhs.lisp.se/Body/m_multip.htm</li>
</ul>
<p class="page-source">
Page source: <a href="https://github.com/LispCookbook/cl-cookbook/blob/master/functions.md">functions.md</a>
</p>
</div>
<script type="text/javascript">
// Don't write the TOC on the index.
if (window.location.pathname != "/cl-cookbook/") {
$("#toc").toc({
content: "#content", // will ignore the first h1 with the site+page title.
headings: "h1,h2,h3,h4"});
}
$("#two-cols + ul").css({
"column-count": "2",
});
$("#contributors + ul").css({
"column-count": "4",
});
</script>
<div>
<footer class="footer">
<hr/>
&copy; 2002&ndash;2023 the Common Lisp Cookbook Project
<div>
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">our contributor's Common Lisp video course on Udemy</a>
</div>
</footer>
</div>
<div id="toc-btn">T<br>O<br>C</div>
</div>
<script text="javascript">
HighlightLisp.highlight_auto({className: null});
</script>
<script type="text/javascript">
function duckSearch() {
var searchField = document.getElementById("searchField");
if (searchField && searchField.value) {
var query = escape("site:lispcookbook.github.io/cl-cookbook/ " + searchField.value);
window.location.href = "https://duckduckgo.com/?kj=b2&kf=-1&ko=1&q=" + query;
// https://duckduckgo.com/params
// kj=b2: blue header in results page
// kf=-1: no favicons
}
}
</script>
<script async defer data-domain="lispcookbook.github.io/cl-cookbook" src="https://plausible.io/js/plausible.js"></script>
</body>
</html>