3

記号と名前は違うのですか?一般的な Lisp に焦点を当てている Paul Graham によるLisp では、そのように思われるいくつかの議論があります。

ラムダ式は関数の名前でもあるため、関数呼び出しの最初に現れることもあります:
((lambda (x) (* x 2) 3)
6

これにより、シンボルは名前のように聞こえますが、名前はシンボルではありません。しかし、私は Lisp の「オブジェクト」シンボルがどのようなものであるか、またはその可能性があるかを理解していません。

これは、ここでのシャープクォート ( ) 演算子 v.に関する私の質問にも由来しています。これらが異なる唯一の理由は、すべての名前が記号であるとは限らないためだと思いますが、それらの答えを理解するのに十分な背景がまだありません(したがって、この質問です)。#'symbol-function

私はまた、elisp 対 common lisp の説明を求めています。これは、バージョン 24 (24.1 だと思います) まで elisp に導入されなかった語彙形式に関係していると思います。

4

2 に答える 2

4

レイナーの答えはこれで正しいと思いますが、質問は別の質問への私の回答に対するコメントに表示されたので、そのコメントからの私の回答を(更新して)含めます。

シンボルは実際のオブジェクトです。それを検査したり、 make-symbolなどで作成したりできます。重要なことに、シンボルは Common Lisp のソース コードの主要なコンポーネントの 1 つです。関数名、特にこの問題が発生したコンテキスト (関数特殊演算子の引数) は、用語集のエントリによると、シンボルまたは形式(setf symbol )のリストのいずれかです。

関数名n. 1. (環境で) その環境での関数の名前であるシンボルまたはリスト (setf シンボル)。2. シンボルまたはリスト (setf シンボル)。

関数は引数を評価しない特別な演算子であるため、シンボルまたはsetfリストを渡すことは次のようなことを意味します。

(function car)
(function (setf car))

ではない:

(function 'car)
(function '(setf car))

ここで、x in (let ((x 42)) x)などのレキシカル変数は、ソース コードではシンボルで表されますが、実際には実行時にシンボルとは何の関係もありません。(let ((x 42)) x)のコンパイル済みバージョンは、シンボルxについて何も知る必要はありません。コード(let ((y 42)) y)が同じものにコンパイルされると予想されるため、直感的にこれは理にかなっています。ただし、変数が特殊な場合は、シンボルとの関連があります。違いは次の場合に最も明確です。

(let ((x 42))
  (symbol-value x))
;=> NIL

(let ((x 42))
  (declare (special x))  ; or (defparameter x ...) or (defvar x ...) earlier
  (symbol-value x))
;=> 42

レキシカル スコープの関数についても同じことが当てはまると予想されます。たとえば、実行時のシンボルxとローカル関数の間に接続がないため、次のコードはエラーを引き起こします。

(flet ((x () 42)) 
  (symbol-function 'x)) ; ERROR, no function value for symbol x

それでも、次のことができます。

(flet ((x () 42))
  (function x))

これは、functionが特別な演算子であり、 is が発生する環境にアクセスできるためです。つまり、(これは特殊であり、実装によって機能するため) xがここで関数として定義されていることを知ることができます。fletlabelsは関数名を取るように定義されているため、次のことができることに注意してください。

(flet (((setf kar) (value kons)
          ...))
  ...)
于 2015-03-29T20:30:27.827 に答える