Gauche:Translation:Devlog:キーワードとシンボルの統合
(原文: Keyword-symbol integration)
キーワードとシンボルの統合
嗚呼、もう五月か。 信じられない。 最後の追い込みは長いマラソンだということがわかりました。
GitHub のレポジトリ https://github.com/shirok/Gauche を見ているならそれが積極的に開発されていることは知っているでしょうが、ほとんどの変更はマイナーな修正です。 0.9.4 リリースのために私が最後に記載した項目をクリアし、一大項目「キーワード」を残して実現しました。
Gauche は他の型と分離したキーワード型を持っています。 STk からそれを継承したと思います。 Common Lisp について話すと :keyword を持つことは RnRS 仕様と競合することを忘れがちほど自然です。 RnRSでは、それらはシンボルでなければなりません。
実際、 srfi-42 を採用したときに : で始まるシンボルが使用されていて問題になりました。 アレックス・シンは問題を回避するために、マクロ展開時に巧妙なトリックを採用しました。
今、もっと多くのR7RSライブラリが出てくると、この設計が大きな障害となると予期しています。
キーワードを持っているいくつかの実装はシンボルとは異なる構文を採用することでこの競合を回避しています。 例えば #:keword といったようなものです。 実際、私の当初の計画はキーワードの構文をカスタマイズ可能にすることでした。 :keyword, #:keyword あるいは keyword: (DSSSL スタイル、誰か覚えていますか?) などです。 それがキーワードの名前スロットにコロンを持っていない理由です。 しかし、これらの構文の混合は混乱しただけで、私は :keyword をやはり強く好んでいます。 #:keyword は、シンボルと競合しないというメリットがありますが視覚的にあまりにもでしゃばりだし、 CL と Gauche では unintern symbol として使用されています。
技術的にはキーワードをシンボルから分離する必要はありません。 確かに CL でキーワードはキーワードパッケージに属するだけのシンボルです。 我々はちょうどそれと同じように出来ます。
- <keyword> を <symbol>はのサブタイプにすることが出来ます。 : で始まる識別子は <keyword> のインスタンスとして読み込み、それはまたシンボルでもあります。 そう、 keyword? はまだ動作しますが、キーワードは symbol? でも #t を返します。
- gauche.keyword モジュールを持ち、すべての有り得るキーワードの不変の束縛を持っているかのように動作します。 キーワードはそれ自身に束縛されています。 実際には、キーワードが読み込まれる都度にその場でそのような束縛を作ります。
- そのとき gauche モジュールが gauche.keyword を継承できて、 Gauche のキーワードの既存の使用は保持されます。 それらはシンボルですが、それ自身に評価されます。 また、プログラマがキーワードを(ローカルまたはそのモジュールのトップレベルで)再バインドすることができますが、効果はローカルなままです。 そのような行為を行っている人は、何をしているか知っている必要があります。
- r7rs モジュールは gauche.keyword を継承しておらず、したがって : で始まるシンボルは普通のシンボルです。 すべてのポータブルな R7RS コードが実行できる必要があります。
- Gauche の機能を使用するために gauche.core をインポートすることを望むなら、それらのキーワードの束縛はそれになり、 Gauche を使うときのように Gauche の手続きをキーワード引数で呼出すことが可能になります。
これは私には合理的に見えます。 いくつかのひっかかりがありますが、それはマイナーなものでしかなく簡単な迂回路があります。
- もし (import (only (gauche core) foo ...)) といったように Gauche の手続きを R7RS のコードへ import したなら、キーワードは import されません。 (foo ':bar b ...) のように呼ぶ必要があります。 言い換えるとキーワードのクオートが要ります。
- : で始まるシンボルをエクスポートした R7RS ライブラリと gauche.core の両方を R7RS へ import したなら、 いずれか後に現れた方が先行をシャドウします。
しかしながら、この変化は特定の場合の後方互換性を破壊する必要があり、それは少し複雑ですが判明しました。 後ほど説明します。