For Gauche 0.9.5


Previous: , Up: 主要な概念   [Contents][Index]

2.7 コンパイル

Gaucheは、Schemeフォームをひとつづつ読み込んでは評価するという意味では インタプリタです。しかし内部では、Gaucheはひとつひとつのフォームを中間形式に コンパイルして仮想マシンで実行しています。

組み込みの構文とマクロはコンパイル時に認識されて展開されます。 よく使われる組み込み関数は、コンパイル時にグローバルな束縛が置き換わっていない場合に、 インライン展開されます。

プログラマは通常、コンパイラの動作を気にする必要はほとんどありませんが、 いくつかの点に注意する必要があります。

loadは実行時に評価される

loadはGaucheでは一般の関数なので、実行時に評価されます。 ロードされるファイル中でマクロを定義している場合、そのマクロは そのloadの呼び出しを含むトップレベルフォームが評価された後で 有効になります。例えば、foo.scmがマクロfooを定義しているとして、 次のような用法を考えてみてください。

;; in “foo.scm”
(define-syntax foo
  (syntax-rules () ((_ arg) (quote arg))))

;; in your program
(begin (load "foo") (foo (1 2 3)))
  ⇒ error, bad procedure: ‘1’

(load "foo")
(foo (1 2 3)) ⇒ '(1 2 3)

beginloadfooの呼び出しを囲んだ場合、 コンパイラはまずbegin全体をコンパイルします。その時点でマクロ fooは定義されていませんから、これは評価時にエラーになります。 一方、後者ではloadが評価されてからfooがコンパイルされるので、 問題は起きません。

このような混乱を避けるために、別のプログラムファイルを読み込む必要がある時は requireuseを使うことを勧めます。これらは構文であり、 コンパイラに認識されます。

require はコンパイル時に評価される

上記の裏返しですが、requireuseはコンパイル時に 解釈されます。したがって、ifなどの条件文のボディにこれらのフォームを 置いておいても、指定されたファイルは条件にかかわらず読み込まれてしまいます。 どうしてももし条件によって読み込むかどうかを変えたい場合は、loadを使うか、 条件判断自体をマクロで行うようにしてください。 (例えば、cond-expandフォーム等を使って。(機能条件式参照))


Previous: , Up: 主要な概念   [Contents][Index]