2009年12月24日木曜日

PLT Scheme のストラクチャ

SchemeはR5RSではストラクチャ(構造体)を持っていません。
僕は正直ピンと来ないんですが、ストラクチャは便利であるらしく、Schemeでは今までも実装依存でストラクチャが提供されてたり、あるいはSRFIで提案されていたり、挙句の果てに、今後どうなるか分からないR6RSでは正式に仕様として加わった模様です。

ここでは、PLT Scheme 依存のストラクチャに付いてちょっと書いておきます。
何故PLT Scheme依存なのか?
端的に言うと理由は以下の三つです。

  1. 比較的、ANSI Common Lispのストラクチャに似てるから。

  2. SRFIR6RSの「レコード型」と言う呼び方が気に喰わない(笑)。

  3. SRFIR6RSのドキュメンテーションが抽象的で良く分からん。


と言った感じですかね。

まあ、2番目の「呼び方が気に喰わない」ってのはクダラナイ理由って言えば理由なんですけどね(笑)。でも今時Pascalじゃねえんだから、とかちょっと思うんですよね。
しかも、「仕様に無い」時点での、独自に「レコード型と呼びましょう」ってのはANSI Common Lispに「不必要に」対抗しているように見えて正直好きじゃないんです。CLもSchemeもLisp語族ですが、この二つの言語間を行き来している人も多いでしょうから、なおさら「ツマラン理由で」呼び名を変えるのはロクな事になりませんって、絶対。
そして、SRFIR6RS辺りのドキュメンテーションが正直良く分からんのですよ。極めて読みづらく、動作が想像しづらいのです。ストラクチャに限らず、一般に、Schemeのドキュメンテーションって不必要に抽象的で分かり辛い、と思います。誰がアレで「実用的なプログラム」を書こうと出来るのか、思えるのか。ホント、敢えて言いますが、Schemeのドキュメントって概してサイテーですよ(笑)。リファレンスとして機能しないケースがあまりにも多いと思います。
結局、1番のPLTのストラクチャが「CLに似てるっぽいのが良い」ってのに還元されるわけです。見た目似てたらCLのドキュメントを調べながら動作確認がしやすいから、ですよね。CLはCLHSなんかあって、しかも例示が比較的多いんで、Schemeに比べると遥に分かりやすいのです。マジでこの辺、SchemeはANSI Common Lispを見習うべきだと思いますよ。

PLT Schemeのストラクチャをポール・グレアムのANSI Common Lisp (スタンダードテキスト)
っぽく見てみましょうか。

PLT Schemeでストラクチャを定義するには、define-structを使う。最も単純な場合には、ストラクチャの名前とフィールドの名前、#:mutable、#:transparentを与えるだけである。

(define-struct point (x y)
#:mutable
#:transparent)

これによって、x、yという2つのフィールドをもったストラクチャpointが定義される。また暗黙に、make-point、point?、point-x、point-yと言う手続きも定義される。
make-pointを呼び出すたびに、新しいpointが返される。

> (define p (make-point 0 0))
> p
#(struct:point 0 0)

pointのフィールドへのアクセサは値を引き出す。set-ストラクチャ名-フィールド名!はフィールドの値を変更する。

> (point-x p)
0
> (set-point-y! p 2)
> p
#(struct:point 0 2)

ストラクチャを定義するとその名前のストラクチャの型も定義される。個々のpointは、pointと言う型に属し、さらにストラクト(struct)という型に属することになる。pointであるかどうか判定するにはpoint?を使う。

> (point? p)
#t

0 件のコメント:

コメントを投稿