仕様との差異
- 末尾呼び出しは WebAssembly とインタプリタでは真に末尾になり、JVM ではループに変換できる場合だけです。
WebAssembly にコンパイルした場合(
-o prog.wasm、--component)とインタプリタで実行した場合 (rontolisp prog.scm、REPL)、末尾位置のすべての呼び出しは一定のスタックで実行されます。 JVM でそうなるのは、名前付きlet、do、末尾位置での自己呼び出し、および末尾位置での 手続きどうしの相互呼び出し(even?/odd?、状態機械、評価器のeval/apply)のうち、 ファイルのトップレベル手続きどうし、一つの本体の内部定義どうし、一つのletrecのlambda束縛どうしのものです。手続き値(引数、変数、apply)を通した末尾呼び出しは、そこでは スタックを消費します。引数経由で自分を呼ぶ手続きは、JVM にコンパイルした場合、その 16 MiB の スタック上で深さ約 16,000 でオーバーフローします(-Drontolisp.stackで上げられます)。 call/ccは脱出専用です。 継続は、そのcall/ccの実行中に 1 回だけ呼べます。 再突入はないため、ジェネレータやコルーチンは作れず、dynamic-windのbeforeは ちょうど 1 回だけ実行されます。call-with-valuesは、両引数がlambda式として書かれているとき直接束縛になります。 それ以外の形はリストを経由します。- 例外は巻き戻しの後で捕捉されます。
guardは本体を抜けた後で節を実行するため、 どの節も選ばれなければguardからオブジェクトを再び発生させます。外側のハンドラは本体のraise-continuableを再開できません。with-exception-handlerのハンドラはraise、raise-continuable、errorの場所で実行されますが、組み込み手続きのエラーではthunkを抜けた後で実行されます。WebAssembly では範囲外の文字列添字は検査されません(終端を 超えたstring-refは文字を返します)。捕捉されないerrorは メッセージと irritant を、捕捉されないraiseはそのオブジェクトを表示してプログラムを 終了します。 - パラメータオブジェクトを引数付きで呼ぶとエラーです。Gauche は値を設定します。
evalの 中のparameterizeは名前を挙げて拒否されます。 - どの節も受け付けない個数の引数で
case-lambdaを呼ぶと、エラーオブジェクトが raise されます。evalの中のcase-lambdaは名前を挙げて拒否されます。 - ポートはテキストかバイナリのどちらか一方で、両方ではありません: 文字列ポートの
binary-port?は#fです(Gauche のポートは両方です)。標準のポートはテキストポート なので、read-u8、write-u8などのバイナリ手続きにはバイトベクタポートかバイナリの ファイルポートの引数が必要です。char-ready?とu8-ready?は常に#tを返します。 with-input-from-fileとwith-output-to-fileは、脱出や raise されたオブジェクトを 含め、thunk をどう抜けてもファイルを閉じます(Gauche は開いたままにします)。出力用に 開けないファイルは、R7RS のとおりfile-error?が#tを返すエラーを raise します。- レコードは Common Lisp の
#S(...)構文で表示されます。equal?はレコードを同一性で 比較します。本体の中のdefine-record-typeは書かれた場所ごとに 1 つの型を作り、本体 を実行するたびに新しい型を作ることはしません(Gauche は後者です)。 writeは'xを(quote x)と、未規定値を#!unspecificと表示します。未規定値は 1 つのオブジェクトで、条件としては真です。exitは囲んでいるdynamic-windのafterを実行してから、そのステータスでプロ セスを終了します; その場で終了するのはemergency-exitのみです。- 複素数はありません:
(sqrt -4)、(log -1)、(asin 2)は手続き名を挙げたエラーで プログラムを終了します。 - エラーメッセージには Common Lisp の名前(
CAR)が出ます。 utf8->stringは、正しい UTF-8 の列を始めないバイトをエラーにせず、そのバイト値を コードとする文字に復号します。- ファイルとしてのライブラリは、プログラムを開始したファイルと同じ場所だけから探され、
検索パスはありません。ファイルに書いた
define-libraryはそのファイルからしか見えず、 並べてloadしたファイルは.sldファイルとしてしかそのライブラリを見つけられません。 エクスポートしたマクロのテンプレートが使う名前のうち、ライブラリが定義もインポートもしない ものは、マクロを使う場所での意味になります。ライブラリが定義したレコード型は、名前の前に ライブラリ名を付けて表示されます。1 つの名前を 2 つのライブラリからインポートしても 拒否されず、後のimportが優先されます。 cond-expandはプログラムを読む時点で、すべてのバックエンドに共通の機能に対して判定されます。(features)はオペレーティングシステムやプロセッサを含みません。どの節も成り立たずelseも ないcond-expandはエラーです。evalの中では、(library ...)は標準ライブラリに対してだけ 成り立ちます。
未対応
その他のライブラリ。それらの import は、ファイルを読む時点で名前を挙げて拒否されます。