例外はポータブルにdisplayできない

そろそろyuniライブラリを各種処理系で自動テストできる環境を作ろうとしている。個々のテストはevalに渡してその例外を記録していくことになるが、例外オブジェクトはwriteで書き出せないため何らかの可読形式に変換する必要がある。
R7RSには、error-object-messageとerror-object-irritantsの各手続きがあるので、これらを通せばそれなりに可読にもできる。しかし、これらでは情報が落ちてしまうという地味な問題がある。たぶん、R6RS用のcondition printerと、各R7RS実装用のcondition printerをそれぞれ用意しないといけない。
とりあえず、単純なdisplayを各種処理系で試してみた。evalに存在しないライブラリを渡して、上がってきたconditionオブジェクトをdisplayした。
こうして見てみると、

  • Record/Conditionであることしかわからない処理系(Guile/Larceny)
  • 単にダンプするだけなので読めない処理系(nmosh/Racket/Vicare)
  • それなりに読める処理系(Sagittarius/chibi-scheme/Gauche)

に大別される。
ライブラリが見付からないエラー一つとっても、その構造にはあまり互換性が無い(R6RS標準のエラーとして規定されていない)。例えば、nmoshでの例外はirritantsにライブラリ名を含むが、Vicareはそうなっていない。なので、この辺は処理系毎に実装して互換性レイヤを準備する必要がありそうだ。

R6RS/R7RS Hybrid

  • nmosh
#<type:condition(#<#<type:record-type-descriptor&assertion #<type:record-type-descriptor&violation
 #<type:record-type-descriptor&serious #1=#<type:record-type-descriptor&condition #f &conidion-uid
 #f #f () > &serious-uid #f #f () > &violation-uid #f #f () > &assertion-uid #f #f () >> #<#<type:
record-type-descriptor&who #1# &who-uid #f #f ((#f . who)) >lookup-library > #<#<type:record-type-
descriptor&message #1# &message-uid #f #f ((#f . message)) >"Library not found" > #<#<type:record-
type-descriptor&irritants #1# &irritants-uid #f #f ((#f . irritants)) >((NEVERLAND)) >) >
#<condition
 #<&error>
 #<&message import no such library ((NEVERLAND))>
>
  • Larceny
#<record &compound-condition>

R6RS

  • Racket
#(struct:exn:fail "environment: cannot find suitable library installed (exception: collection-path
: collection not found\n  collection: \"NEVERLAND\"\n  in collection directories:\n   C:\\repos\\y
uni\\lib-runtime/racket\n   C:\\repos\\yuni\\lib-stub/racket\n   C:\\Users\\test\\AppData\\Roaming
\\Racket\\6.1\\collects\n   C:\\Program Files\\Racket\\collects\n   ... [152 additional linked and
 package directories]): {NEVERLAND}" #<continuation-mark-set>)
  • Guile
#<r6rs:record:&compound-condition>
  • Vicare
#[r6rs-record: compound-condition components=(#[r6rs-record: &error] #[r6rs-record: &who who=expand
er] #[r6rs-record: &message message="cannot locate library"] #[r6rs-record: &library-resolution lib
rary=(NEVERLAND) files=("/usr/local/lib/vicare-scheme/NEVERLAND.fasl" "lib-r6rs/NEVERLAND.vicare.sl
s" "lib-r6rs/NEVERLAND.sls" "lib-stub/vicare/NEVERLAND.vicare.sls" "lib-stub/vicare/NEVERLAND.sls" 
"lib-stub/r6rs-common/NEVERLAND.vicare.sls" "lib-stub/r6rs-common/NEVERLAND.sls" "lib-compat/NEVERL
AND.vicare.sls" "lib-compat/NEVERLAND.sls" "lib/NEVERLAND.vicare.sls" "lib/NEVERLAND.sls")])]

R7RS

{Exception #18 user "couldn't find import" ((NEVERLAND)) #f #f}
#<compound-condition #<error "cannot find "NEVERLAND" in ("l"> #<<compile-error-mixin> 0x18b9e60>>