(defun myfn (x) x)
は
(eval-when (:compile-toplevel :load-toplevel :execute)
(setf (fdefinition 'myfn) #'identity))
ターの利点のようなものに置き換えられるかもしれません。心に留めておくべき事柄の
ワン:
シンボルオブジェクトはいくつかの情報を運ぶことができます。 1があった場合たとえば、元の関数名、:
CL-USER 13 > #'identity
#<Function IDENTITY 410003F974>
は、シンボルの関数セルを設定するには、それを変更しません:
CL-USER 14 > #'myfn
#<Function IDENTITY 410003F974>
それは、元の内部名と同じ関数オブジェクトです。一つは、その名前にアクセスすることができるかもしれませんが、一つは、それを変更することはできません。
CL-USER 18 > (nth-value 2 (function-lambda-expression #'identity))
IDENTITY
自己再帰関数での問題もあります:
CL-USER 19 > (defun foo (n)
(if (zerop n)
1
(* n (foo (1- n))))) ; here foo calls the function foo
FOO
は今、私たちは機能を使用するようにBAR
を設定するにはここでFOO
CL-USER 20 > (setf (symbol-function 'bar) #'foo)
#<interpreted function FOO 4060004084>
CL-USER 21 > (bar 10)
3628800
我々はFOO
を再定義:
CL-USER 22 > (defun foo (n)
(if (zerop n)
1
(+ n (foo (1- n)))))
FOO
BAR
は、古いFOO
を引き続き使用します。これは、新しいFOO
を呼び出す場合としない場合があります。
CL-USER 23 > (bar 10)
460
OOPS! FOOを変更しましたが、BARには奇妙な影響があります。最初の繰り返しは古いFOOであり、次の再帰呼び出しは新しいFOOです。
BAR
およびFOO
は、同じ機能の2つの異なるバージョンです。しかし、両方とも関数FOO
を呼び出します。これは、コードをどのように解釈したりコンパイルするかによって、古い関数または新しい関数である可能性があります。
CL-USER 24 > #'foo
#<interpreted function FOO 40600041F4>
CL-USER 25 > #'bar
#<interpreted function FOO 4060004084>
ちょっと考えてみましょう。(defun myfun(&rest args)(identity argsを適用)) 'に展開するマクロを追加することができます。もちろん、Lisp-1では 'myfn identityを定義する 'ことができます。 – Cactus
複製からリンクされている機能の一部を確認してください。周囲に浮かぶ有益な情報がたくさんあります。 ** defunが(setq)と同じではないというタイトルのものは、いくつかの良い議論があります。 –
また、明確にするために、 '# ''表記を使ってシンボルの関数値を得ることができます。つまり、(let((id(lambda(x)x)))(compose id ...)) 'を実行する必要はありません。あなたは '(let((id# 'identity))(compose id ...))'や '(compose#' identity ...)'を実行できます。 –