2

Ubuntu で MIT-Scheme を実行すると、関数がプロシージャとして表示されます。

1 ]=> (define (sq x) (* x x))

;Value: sq

1 ]=> (sq 3)

;Value: 9

1 ]=> sq

;Value 11: #[compound-procedure 11 sq]

バークレーの STk はsqクロージャーとして表示されます。

STk> (define (sq x) (* x x))
sq
STk> (sq 3)
9
STk> sq
#[closure arglist=(x) b73fab48]

Lisp (Common Lisp clisp) では、同じことを行うと、代わりにエラーが発生し、関数を値 (ファースト クラスの値/オブジェクト) として表示するにはどうすればよいでしょうか?

[1]> (defun sq(x) (* x x))
SQ
[2]> (sq 3)
9
[3]> sq

*** - SYSTEM::READ-EVAL-PRINT: variable SQ has no value
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead of SQ.
STORE-VALUE    :R2      Input a new value for SQ.
ABORT          :R3      Abort main loop
4

2 に答える 2

7

Common Lisp は、Scheme とは異なり、変数と関数名に対して個別の名前空間を保持します。#'sqCLで試してみてください。また、'Lisp1 vs Lisp2' をグーグルで検索して、この件に関する際限のない言い回しを探してください。

于 2015-12-13T19:22:16.477 に答える
7

名前空間の違いによる、Scheme と Common Lisp の構文上の違いを示します。スキームには、関数と変数用の名前空間が 1 つあります。Common Lisp には、関数と変数に対して異なる名前空間があります。Common Lisp の名前は、変数、関数などの異なる意味を同時に持つことができます。

関数定義

これらの違いは、名前空間の違いによるものではありません。

図式 :(define (foo a) (+ a 1))

一般的な Lisp:(defun foo (a) (+ a 1))

関数オブジェクトを値として取得する

図式 :foo

Common Lisp:(function foo)またはそれより短い#'foo. このフォームは関数オブジェクトを返します。

0 個以上の引数を指定して関数オブジェクトを呼び出す

スキーム: 関数式の最初の位置が評価されます。

(let ((bar foo))
  (bar 10))

Common Lisp:funcall関数オブジェクトを引数で呼び出すために使用する必要があります。最初の引数は関数オブジェクトでなければなりません。

(let ((bar #'foo))
  (funcall bar 10))

名前の衝突: 1 つの名前空間と 2 つの名前空間

スキーム: 定義された関数と衝突しないようにローカル変数に名前を付ける必要があります:

(define (foo lst)
  (list lst))

Common Lisp: 関数と変数の間で名前が衝突することはありません。

(defun foo (list)
  (list list))
于 2015-12-13T21:29:01.733 に答える