1)変数の新しい概念。Lispでは、すべての変数は事実上ポインタです。値は、変数ではなく型を持つものであり、変数の割り当てまたはバインドは、ポインタが指すものではなく、ポインタのコピーを意味します。
(defun print-twice (it)
(print it)
(print it))
「それ」は変数です。任意の値にバインドできます。変数に関連付けられている制限やタイプはありません。関数を呼び出す場合、引数をコピーする必要はありません。変数はポインターに似ています。変数にバインドされている値にアクセスする方法があります。メモリを予約する必要はありません。関数を呼び出すときに、任意のデータオブジェクト(任意のサイズと任意の型)を渡すことができます。
データオブジェクトには「タイプ」があり、すべてのデータオブジェクトはその「タイプ」を照会できます。
(type-of "abc") -> STRING
2)シンボルタイプ。シンボルは文字列とは異なり、ポインタを比較することで等価性をテストできます。
シンボルは、名前を持つデータオブジェクトです。通常、名前はオブジェクトの検索に使用できます。
|This is a Symbol|
this-is-also-a-symbol
(find-symbol "SIN") -> SIN
シンボルは実際のデータオブジェクトなので、同じオブジェクトかどうかをテストできます。
(eq 'sin 'cos) -> NIL
(eq 'sin 'sin) -> T
これにより、たとえば、記号付きの文を書くことができます。
(defvar *sentence* '(mary called tom to tell him the price of the book))
これで、文中のTHEの数を数えることができます。
(count 'the *sentence*) -> 2
Common Lispでは、シンボルは名前を持つだけでなく、値、関数、プロパティリスト、パッケージを持つこともできます。したがって、シンボルを使用して変数または関数に名前を付けることができます。プロパティリストは通常、メタデータをシンボルに追加するために使用されます。
3)シンボルのツリーを使用するコードの表記。
Lispは、その基本的なデータ構造を使用してコードを表します。
リスト(* 3 2)は、データとコードの両方にすることができます。
(eval '(* 3 (+ 2 5))) -> 21
(length '(* 3 (+ 2 5))) -> 3
木:
CL-USER 8 > (sdraw '(* 3 (+ 2 5)))
[*|*]--->[*|*]--->[*|*]--->NIL
| | |
v v v
* 3 [*|*]--->[*|*]--->[*|*]--->NIL
| | |
v v v
+ 2 5
4)常に利用可能な言語全体。読み取り時、コンパイル時、および実行時に実際の違いはありません。読み取り中にコードをコンパイルまたは実行し、コンパイル中にコードを読み取りまたは実行し、実行時にコードを読み取りまたはコンパイルできます。
Lispは、テキストからデータとコードを読み取るREAD関数、コードをロードするLOAD関数、コードを評価するEVAL関数、コードをコンパイルするCOMPILE関数、およびデータとコードをテキストに書き込むPRINT関数を提供します。
これらの機能は常に利用可能です。彼らは消えません。それらは任意のプログラムの一部にすることができます。つまり、すべてのプログラムがコードを読み取り、ロード、評価、または印刷できます-常に。
CやJavaなどの言語ではどのように違うのですか?
これらの言語では、シンボル、データとしてのコード、またはデータとしてのランタイム評価をコードとして提供していません。Cのデータオブジェクトは通常、型指定されていません。
LISPファミリ言語以外の他の言語には、これらの構成要素が含まれていますか?
多くの言語には、これらの機能のいくつかがあります。
違い:
Lispでは、これらの機能は使いやすいように言語に組み込まれています。