Lispの上の奇妙な引用リストの例
-
20-12-2019 - |
質問
On Lisp
からのこの箇所は、本当に混乱しています - '(oh my)
などの引用符付きリストの返信は実際に関数が Future でどのように動作するかを変更する方法は明らかではありません。もう一度最初からの関数で、次回呼ばれたときは?
exclaimを返した場合、戻り値を定義する場合 引用符付きリストを組み込んでいます、
.(defun exclaim (expression) (append expression ’(oh my)))
その後戻り値を破壊的に変更する
.(exclaim ’(lions and tigers and bears)) -> (LIONS AND TIGERS AND BEARS OH MY) (nconc * ’(goodness)) -> (LIONS AND TIGERS AND BEARS OH MY GOODNESS)
関数内のリストを変更することができます:
.(exclaim ’(fixnums and bignums and floats)) -> (FIXNUMS AND BIGNUMS AND FLOATS OH MY GOODNESS)
そのような問題に対して命名証は、書かれるべきです:
.(defun exclaim (expression) (append expression (list ’oh ’my)))
exclaim
の最後の呼び出しは、goodness
を結果に追加するのでしょうか。関数は外部変数を参照していません。
解決
a)リテラルリストを変更する効果は、共通LISP規格では未定義です。例としてあなたがここに見えるものは可能な行動の1つです。
(1 2 3 4)
はリテラルリストです。ただし、LIST
のような(list 1 2 3 4)
への呼び出しは、実行時に新たな節約リストを返します。
b)リストは関数のコード内のリテラルデータです。すべての呼び出しはこのデータオブジェクトを正確に返します。各通話に新規リストを提供したい場合は、リストやコピーリストのようなものを使用する必要があります。
c)返されたリストは常に同じリテラルデータオブジェクトであるため、説明しているように変更することができます。コードとそのオブジェクトが読み取り専用メモリに割り当てられている場合、エラーが発生したことも想像できます。リストを変更すると、読み取り専用メモリに書き込もうとします。
d)ソースコード内のリテラルリストデータを処理するときに留意することは、次のとおりです.Lispコンパイラは保管を自由に最適化できます。ソースコード内のリストが複数回行われる場合、コンパイラはこれを検出し、1つのリストを作成することができます。さまざまな場所はすべてこのリストを指します。したがって、リストを変更すると、これらの変更がいくつかの場所で表示される可能性があります。
これは、配列/ベクトルのような他のリテラルデータオブジェクトでも発生する可能性があります。
データ構造体がコードの一部である場合は、この内部データ構造を返し、このデータ構造を変更してください。その後、コードを変更しようとします。
Lispはインタプリタによって実行できることにも注意してください。インタプリタは通常LISPソース構造で動作します。コードはマシンコードではありませんが、LispデータとしてLispコードを解釈しました。ここでは、実行時にソースコードを変更することができます。ソースコードに埋め込まれたデータだけでなく、