週刊nmosh - 対応scheme追加の会
なんだか各種Scheme処理系のコーナーケースを突く嫌なコーナーになりつつ有るような。。
とにかくyuniは移植できそうなところには全て移植していく心意気でやっていきます。
picrin
- https://github.com/picrin-scheme/picrin
- R7RS + 各種ライブラリ
- https://github.com/picrin-scheme/benz
- Scheme処理系コア
picrinは処理系コアを外部ライブラリのbenzに追い出し(submodule)、R7RS部分をpicrinリポジトリに残している。picrinはライブラリをファイルからロードする機能が無く、何故か(export ...)を先に書けないので、専用の変換パスとランタイムを用意した。
- ローダー : https://github.com/okuoku/yuni/blob/ee218aee1b6e6b7f21256290463754ca76911a84/lib-runtime/r7rs/yuniloader.scm
- ライブラリブリッジ : https://github.com/okuoku/yuni/blob/ee218aee1b6e6b7f21256290463754ca76911a84/lib-runtime/r7rs/yuni-runtime/picrin.scm
(define-library (yuni-runtime picrin) (import (scheme base)) (begin (define-syntax library (syntax-rules () ((_ libname (export ...) (import ...) body ...) (begin body ...))))) (export library))
R6RSやR7RS規格の例のように、define-library→export→import→bodyの順で書くと、未定義シンボルとしてエラーとなる。どちらかと言うとexportは繋ぎ合わせて最後に処理するのが普通で、R7RSで例として挙げられているライフゲームのサンプルもexportが先に来るスタイルで書かれている。
今のところpicrinはyuniのmatchライブラリをexpandできない。デバッグ中。
Sagittarius
おなじみSagittariusはnmoshと同様R6RS/R7RSのハイブリッドとなっている。SagittariusはGauche風のキーワード構文を備えるので、Gaucheと同じブリッジライブラリを使用する(exportからコロンで始まるシンボルを抜く)。
Sagittarius 0.5.8のsyntax-rulesは、(object ... . last)のようなパターンを処理できない。R7RSはドット対で終るパターンのサポートを要求している。
(import (scheme base) (scheme write)) (define-syntax extract-last (syntax-rules () ((_ (bogus ... . last)) 'last) ((_ bogus) "error"))) (define-syntax test (syntax-rules () ((_ arg) (begin (write (list '(extract-last arg) '= (extract-last arg))) (newline))))) (test (0 . 1)) ;; => 1 (test (1 0)) ;; => nil (test ()) ;; => nil (test 1) ;; => 1
nmoshやRacket、Gaucheはこの手のパターンを問題なく処理できる。(最後の(test 1)の結果がかなり人間にはわかりづらい。。)
Sagittariusは、手続きのarityが既知の場合、arityが合わない呼び出しはエラーにする事が有るようだ。便利。
(define-library (check) (export check) (import (scheme base)) (begin (define (unused a b) #f) (define (check obj) (and obj (unused 1)))))
ここで、checkでのunused呼び出しは絶対に失敗する。Sagittariusはこのようなコードをエラー扱いにする。