20

defunマクロがどのように機能するかについて混乱しています。

(defun x () "hello")

関数xを作成しますが、シンボルxはバインドされません。

ラムダをxにバインドすると、xには値が付きますが、インタープリターでは次のような形式の関数として扱われません。

(x)

defunが地球環境で機能を定義する必要があるという事実に関係していると思いますが、それが正確に何を意味するのかはわかりません。現在の環境でシャドウできないのはなぜですか?

ラムダがバインドされている場合、インタープリターがシンボルを関数として処理するように強制する方法はありますか?例えば:

(setq y (lambda () "I want to be a named function"))
(y)

PS:私はSBCLを使用しています。

4

2 に答える 2

22

Common Lispには、関数と値の異なる名前空間があります。

関数名前空間で関数を定義するには、、、DEFUNおよびその他を使用します。FLETLABELS

関数オブジェクトを値として取得する場合は、を使用しますFUNCTION

(defun foo (x) (1+ x))

(function foo)   ->  #<the function foo>

以下:

#'foo    ->   #<the function foo>

関数を呼び出したい場合は、を記述し(foo 100)ます。

関数を値として呼び出したい場合は、FUNCALLまたはAPPLY:を使用する必要があります。

(funcall #'foo 1)

関数を渡して呼び出すことができます。

(defun bar (f arg)
  (funcall f arg arg))

(bar #'+ 2)  ->  4

DEFUNの場合:

そうではありません(setf (symbol-value 'FOO) (lambda ...))

のようなもの(setf (symbol-function 'foo) (lambda ...))です。

2つの名前空間を使用すると、次のように記述できることに注意してください。

(defun foo (list)
  (list list))

(foo '(1 2 3))  ->  ((1 2 3))

組み込み関数LISTと変数の間に競合はありませんLIST。2つの異なる名前空間があるため、2つの異なる目的に同じ名前を使用できます。

ローカル関数の場合、シンボルが含まれていないことにも注意してください。名前空間は必ずしもシンボルに関連付けられているわけではありません。したがって、ローカル変数の場合、シンボル名を介した関数ルックアップはできません。

于 2012-06-26T18:21:07.387 に答える
7

Common Lispには、値スロットや関数スロットなど、シンボルごとに複数のスロットがあります。構文を使用する場合、(x)commonlispは。のfunction-slot-bindingを探しますx。値バインディングを呼び出す場合は、funcallまたはを使用しますapply

http://cl-cookbook.sourceforge.net/functions.htmlを参照してください

于 2012-06-26T17:26:29.783 に答える