マクロ拡張について質問していますが、まず関数の処理方法を明確にしたいと思います。
呼び出しと定義が実際にどのように起こるかに注意してください。 2つ目のポイントでは、関数内のコードが後で定義される関数を呼び出すことができるとします。これは厳密には当てはまらない。
C++のような言語では、関数を宣言して定義してから、アプリケーションをコンパイルします。インライン展開、テンプレート、ラムダ、その他の魔法を無視する...関数をコンパイルするときに、その関数が使用する他のすべての関数の宣言が存在する必要があります。リンク時にコンパイルされた定義が存在する必要があります実行を開始します。プログラムの実行が開始されると、すべての機能がすでに完全に準備され、呼び出す準備ができています。
Lispでは、物事が異なっています。今のところコンパイルを無視してください。ちょうど解釈された環境について考えてみましょう。実行した場合:
;; time 1
(defun a() (b))
;; time 2
(defun b() 123)
;; time 3
(a)
時刻1にプログラムに機能がありません。
最初のdefun
は、機能(lambda() (b))
を作成し、それをシンボルa
に関連付けます。この関数には、b
というシンボルへの参照が含まれていますが、b
が呼び出されていない現時点ではです。 a
はa
が呼び出されたときにのみb
を呼び出します。
したがって、時刻2では、プログラムにはシンボルa
に関連付けられた1つの機能がありますが、まだ実行されていません。
第2のdefun
は、機能(lambda() 123)
を作成し、それをシンボルb
に関連付けます。
時刻3では、プログラムには記号a
とb
に関連付けられた2つの機能がありますが、いずれもまだ呼び出されていません。
今、あなたはa
を呼び出します。その実行中には、シンボルb
に関連する機能のために、は、このような機能はすでに時間この時点で存在することを発見し、それを呼び出して見えます。 b
が実行され、戻り123
のは、より多くのコードを追加してみましょう: ;;時間4 関数定義のB()456) ;;時刻5 (a)
時間が経過すると、新しいdefun
が456を返す関数を作成し、シンボルb
に関連付けます。これはb
は、123を返す関数に保持した後、ゴミが収集される(またはごみを取り出すことがないものは何でも実装)の参照を置き換えます。
a
を呼び出す(またはより正確に、シンボルa
の機能属性によって参照ラムダ)は、今、代わりに、我々が最初に書かれていた場合は456
を返す関数の呼び出しになります。我々はa
を呼び出す時間2の後に、それはシンボルb
に関連付けられている機能を見つけることができないので、それが失敗するため
;; time 1
(defun a() (b))
;; time 2
(a)
;; time 3
(defun b() 123)
...これはは、働いていないでしょう。今
からcompile
、eval-when
、最適化およびその他の魔法は、私が上記した内容と異なるファンキーなもののすべての種類を行うが、あなたが最初にそれより高度なものを心配する前に、これらの基本の理解していることを確認することができます。
- 関数は、
defun
が呼び出された時点で作成されます。 (インタプリタはファイル内を先読みしません)
- シンボルの属性の1つは、関数への参照です。 (関数自体に実際に名前はありません)
- 複数のシンボルは同じ関数を参照できます。シンボル
b
は時間a
によって関連機能を有している限りは、と呼ばれているとしての機能b
(口語的に言えば)を呼び出す関数a
の定義((setf (symbol-function 'd) (symbol-function 'b))
)
- 、OKです。 (
defun
ning a
の時点では必要ありません)
- 記号は、異なる時刻に異なる機能を参照することができます。これは、そのシンボルを「呼び出す」関数に影響します。マクロため
のルールが異なる(その展開には時間を「読み」の後に静的です)ですが、原則の多くは(Lispがそれらを見つけるために、「ファイルに先読み」しません)同じまま。 Lispプログラムは、あなたが慣れ親しんでいるかもしれない大部分の(より少ない;-))言語よりはるかに動的で実行時間が長いことを理解してください。理解する何かがのときには、Lispプログラムの実行中にとなり、マクロ展開を支配するルールが意味を持ち始めます。
http://clhs.lisp.se/Body/03_abab.htm –
マクロの詳しい扱いについては、http://www.paulgraham.com/onlisp.htmlを参照してください。 そこから本をダウンロードできます。 –