defn
(defn name docstring? [params...] body...)
(defn name docstring? ([params...] body...)+
関数を定義します。多アリティの綴りはアリティごとに 1 節と、引数個数によるディスパッチです。単一の可変長節(& rest)は固定引数を超える任意の個数を受け、それ以外の個数はシグナルを上げます(wrong number of arguments passed to: f)。可変長節は高々 1 つ、アリティごとの節は 1 つです。引数はベクターもマップパターンも destructuring できます。名前は直接呼び出しへ低レベル化されるため、再帰は値参照ではなく呼び出しです。本体中の recur は囲みの節へ新しい引数値で跳び戻ります。head 位置での値束縛(def、引数)の使用は代わりに funcall になります。
^:dynamic な名前は代わりに関数を var に保持します。定義は直接呼び出しの形を保つため(recur はそこへ直接跳び戻ります)、呼び出しは var の値経由になり、binding が動的エクステントで再束縛できます(binding 参照)。マーカーのない defn はオラクルの非 dynamic エラー同様、binding に拒否されたままです。
定義は、下で定義される名前を使えます。ファイルはすべてのトップレベル def/defn(と declare)の名前で事前走査されます。本体の中では defn は文位置でのみ動き、多アリティのものはトップレベルでのみ動きます。
defn を def で再定義すると関数を取り込みます。(def p (memoize p)) は古い FUNCTION 束縛に対して値を評価するため、トップレベル呼び出しはキャッシュに当たる一方、defun 自身の再帰は直接呼び出しのままです。
同じ名前を別の defn で再定義すると、各定義が自分の関数を持ちます。各定義より下の呼び出し位置は最新のものを呼び出す一方、2 つの定義の間の (def g f) は古い方を保持します((g) は古い値を、(f) は新しい値を答えます)。名前空間ごとに版が管理されます。再定義より上で定義された関数は古い定義を呼び出したままです。すべての呼び出し位置から最新を見るのは(呼び出しが var 経由になる)^:dynamic な名前だけです。