v0.25 Release Note

Last updated:
Created: 2008-01-07








by Fumisky Wells
pipe を導入しました。 仕様はこちらを参照下さい。

背景

ここでは独り言を書きます。

Alan の pipe は、Unix の shell のパイプへのオマージュから生まれました。

発端

発端は:
Unix のパイプは興味深いバイト列操作(の U/I)だ。
なら、Alan の列(=イタレータ)にもパイプがあってもいいじゃないか。
...というものでした。

例は: ...をご覧下さい。

比較

Unix shell, Alan, Ruby, Xtal の間の似た機能を比較することで、それぞれの 相違が分かるかと思います。以下の表にまとめましたのでご覧下さい:
\言語
比較項目\
Shell Alan Ruby Xtal
構文 A | B A | B A.grep(pattern),
A.select{|x| ...} などのメソッドチェイン
A.select{|x| ...} などのメソッドチェイン
プロセス数 2 1 1 1
関係するAPI write()/read() get() grep(), select() など select() など
渡されるデータ型 バイト列 任意 任意 任意
渡し方 プロセス間のデータコピー 参照渡し 配列のコピー イタレータ渡し(≒参照渡し)
push or pull(*) push & pull pull push pull
(*) push or pull とはデータが流れる駆動力を表現したものです。 パイプの前段が後段に押す(push)形で渡される・ 後段が前段から引っ張る(pull)形で渡される、 という形で分類しました。 で、Shell のパイプは、2つのプロセス間で write() で push し、 read() で pull する両者の協調で動作する、という意味で push/pull、 Alan は最後段の get() で駆動されるので pull、Ruby は前段の grep() や select() 等のメソッドで生成された配列が次段に渡される、という意味で push、Xtal は イタレータ(≒ポインタ)が次段に渡されおそらく最後段で pull されるので pull としました(Xtalの私の理解はあやしいです)。

構文は shell のパイプのパクリ(=オマージュ^^;)ですが、 機能的には、Xtal言語 の select メソッドが Alanパイプに一番近いと言えます。

まず、Alanパイプの利点をあげておきます:

  1. データのコピーが発生しないため、高速かつメモリスペースが小さい。
  2. 使う側から見れば A | B という構文で分かりやすい。

Ruby/Xtal では grep() や select() のように、メソッドレベルでパイプと同等の 機能を提供しています。つまり、汎用の機能を言語仕様に変更を加えること無く 追加できている、という点で優れています。 これに対し、Alan ではわざわざパイプ構文を追加しました。理由は、 Rubyブロックの実装にはclosureか複数スタックが必要であり、 Alanメモリモデル = C/C++ メモリモデルではもはや不可能。 つまり、Alanメモリモデルでの外部イタレータ(≒C/C++的外部イタレータ) のぎこちなさを、パイプ構文で隠すアプローチをとった ためです。

ここから Alanパイプの欠点も分かります^^;。つまり、

  1. 実装がぎこちない。
  2. 汎用的でない。
...ことになります。

でも

まあ、

いいじゃないですか、

俺言語だもの(みつを(違))。

内部変更点

  1. iterator の仕様を python風に変えました: 理由: 繰り返しデータが多くなると後者の方が get() ごとのデータの やりとりが少なく効率的なため。 が、実際のところ、100万レコードで 5% の速度差。 数レコードでは前の方法の方が速かった、というオチとなりました。
  2. C++での関数呼出し vm_call(), Gen::gen_call() を変えました: より直感的になったかと。
  3. 従来、file型自身が iterator でしたが、str iterator, byte iterator など複数の iterator に対応するため、分離しました。 alan構文自身は変わりません。
  4. 参照型の導入。これに伴い、O_REF を廃止。
  5. err.EOI を専門に処理する VC_ERRNO_EOI vm opコード。
  6. 型から直接 V_adrs を生成する V_adrs::V_adrs(Type*)の導入。
  7. 暗黙の型変換に対応するための A_convert, Obj::proxy(), Semant::convert_filter(), Semant::convert_iter() の導入。
  8. 型列の走査を抽象構文木であろうと Type object であろうと 統一的に行う TypeSS を使うように徹底。