1

関数を使用して、commonlispの関数を返そうとしています。しかし、説明したい奇妙な状況に遭遇しました。

これが私がやりたいことです:

(defun makefun(x) ;1
  (lambda (z)
    (+ x z)))

((makefun 1) 2) ;2

これにより、不正な関数呼び出しが発生します。ただし、以下が有効です。

((lambda (z) (+ 1 z)) 2) ;3

(funcall (makefun 1) 2) ;4

最初の例のようにmakefunを使用できないのはなぜですか?2の呼び出しが評価されるので、3行目と同等になると思います。

4

2 に答える 2

4

Common Lispにはいくつかの異なる名前空間があり、関数形式では、演算子の関数値が使用されます。ラムダフォームは評価ルールの独立したブランチであるlambdaため、この例は機能します。詳細については、「CommonLisp名前空間」「Lisp-1vs。Lisp-2」をグーグルで検索できます。SOには、これらのトピックをカバーするかなりの数の質問と回答があります

ただし、特定の質問に答えるには、次を使用しますfuncall(を参照することもできますapply)。

(funcall (makefun 1) 2)
于 2013-01-07T22:42:54.673 に答える
4

Stackoverflowですでに同様の質問に回答した場合。重複しています。それを見つける必要があります。

ともかく。

(defun makefun(x) ;1
  (lambda (z)
    (+ x z)))

((makefun 1) 2)

Common Lispは、関数位置での評価を許可しません。そこにシンボルまたは実際のラムダ式を配置する必要があります。

注意:CommonLispには別の関数名前空間があります。値の名前空間は異なります。ここでMAKEFUNは値を返しますが、この値は関数の名前空間では使用できません。

関数を呼び出す構文上の方法は2つだけです。

(foo 1 2)

((lambda (a b) (list a b)) 1 2)

CLHS(Conses as Forms)を参照してください。ここにラムダフォームがあります。

書き込む機能を追加すると、 ((some-function-returning-function) 1 2)CommonLispでの関数呼び出しがより混乱します。

  • (foo 1 2)関数の名前空間を使用します
  • ((some-function-returning-function) 1 2)値の名前空間を使用します
于 2013-01-07T22:56:08.183 に答える