週刊nmosh - 対応scheme追加の会

なんだか各種Scheme処理系のコーナーケースを突く嫌なコーナーになりつつ有るような。。
とにかくyuniは移植できそうなところには全て移植していく心意気でやっていきます。

picrin

picrinは処理系コアを外部ライブラリのbenzに追い出し(submodule)、R7RS部分をpicrinリポジトリに残している。picrinはライブラリをファイルからロードする機能が無く、何故か(export ...)を先に書けないので、専用の変換パスとランタイムを用意した。

(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のハイブリッドとなっている。SagittariusGauche風のキーワード構文を備えるので、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はこのようなコードをエラー扱いにする。

Guile

GuileはR6RSだが、拡張子.slsをライブラリ拡張子として認識しないのでライブラリ拡張子を編集してやる必要がある。

(set! %load-extensions '(".guile.sls" ".sls" ".scm"))

コマンドラインオプションの -l に与えることで、ファイルをロードした状態でプログラムを実行できる。
それ以外のポイントは問題なく動作する。

先週やったこと / 今週やること

パーサはビックリするくらい遅い仕上りだったのでリテイク。もうちょっと真面目に文字列 + indexでストリームを扱わないとダメ。。
今週は、yuniFFIのC言語スタブジェネレータを作る。今のところ動的FFIバインディングが使えてyuniが動くのがnmoshとRacketしか無いので、ひとまずこの2つで。