emacs.d/clones/lispcookbook.github.io/cl-cookbook/functions.html

741 lines
24 KiB
HTML
Raw Normal View History

2022-08-02 12:34:59 +02:00
<!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="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 href="https://www.udemy.com/course/common-lisp-programming/?couponCode=6926D599AA-LISP4ALL">NEW! Learn Lisp in videos and support our contributors with this 40% discount.</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 class="language-lisp">; 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>
<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 particularly used for CLOS methods.</p>
<p>A silly example:</p>
<pre><code class="language-lisp">(defparameter *current-name* ""
"A global name.")
(defun hello (name)
(format t "hello ~a~&amp;" name))
(defun (setf hello) (new-value)
(hello new-value)
(setf *current-name* new-value)
(format t "current name is now ~a~&amp;" new-value))
(setf (hello) "Alice")
;; hello Alice
;; current name is now Alice
;; NIL
</code></pre>
<p><a name="curry"></a></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;2021 the Common Lisp Cookbook Project
</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>