v0.15 Release Note

Last updated:
Created: 2006-08-04








by Fumisky Wells
言語処理系、という深奥に魅せられた Wells が、これまで使ってきた言語、 主に C++ と Perl を元に、俺言語を作る一人プロジェクト Alan。

その ver0.15 をこの度リリースします。

概要

  1. 全てを式に
    1. セミコロンの廃止
    2. 単文例外処理オペレータ
    3. 変数定義のコロン
    4. return文(式)の文法変更
    5. 背景
      1. これまで文と式を区別していた理由
      2. 今回の変更理由
  2. ドット演算子(.)が任意の式で使える
  3. 配列変数の定義式を変更
  4. Filesys パッケージ
  5. str.gsub()
  6. stderr
  7. ENV
  8. get
  9. matched()
  10. wikimini
  11. バグ修正
    1. rescue後にスタックポインタが戻ってないバグを 直しました。
    2. 破棄子付き変数の初期化時にスタックポインタを 調整し忘れていたバグを直しました。
  12. v0.16
  13. v0.17

詳細

  1. 全てを式に
    私が言語を完全にゼロから設計していたら、だぶん Algol68 の流儀を 一歩押し進めて、あらゆる文と宣言を、値を持つ式にしただろう。

    Bjarne Stroustrup, C++の設計と進化, 邦訳版 p.124
    という一言にインスパイアされ、全てを式にする、という大きな変更を行いました。 Ruby のパクリでもあることは言うまでもありません(^^;)。 これに伴い、以下の変更が2次的に発生しています:
    1. セミコロンを廃止しました。
      if a then b else c end を式とすると、旧Alanの文法では
      d = if a then b else c end;
      if a then b else c end;
      は ok ですが
      if a then b else c end
      は、連続する式なのか、1つの式の途中なのか区別つかない、ということで YACC で reduce/reduce 衝突となった、という次第。

      セミコロン無し文法を yacc で記述するのは私にとっては冒険 でしたが、まつもとさんのお勧めもあり(-> langsmith)、チャレンジ した次第。後述の変更も施し reduce/reduce はなくなりましたが、 12 shift/reduce というのが現状です。 ま、ここらで妥協しています(^^;)。

    2. 単文の例外処理のためのオペレータ '||' を導入しました。
      セミコロン廃止と関連する話で、 全て式にする -> セミコロン廃止 -> 例外処理に '||' オペレータ必要、という連鎖反応が発生したわけです。
    3. 変数定義(=宣言)の文法にコロンが必要になり、
      型 : 変数
      (例) int : i
      となりました。Pascal風に「変数 : 型」例えば「i : int」とするのが 正当かも知れません。C言語の作者 Dennis Ritchie も Plan9 で変数宣言を Pascal風に変えたそうですし。 ご意見ありましたらお願い致しますm(__)m。

      これも上と同様、 全て式にする -> セミコロン廃止 -> 変数定義文で reduce/reduce 発生、という連鎖反応で決めました。 型と変数の順序は変更可能なわけですが・・・。

    4. 文法の関係上、"return 式" という C/C++ 的な関数からの戻りが 表現できなくなりました。なので、return は式無しの単なる return となります。
      小飼弾さんの指摘が説得力があったので (2006年春。Perl, Haskell あたりの関数の文法論議?) Alan でも return が無くても関数の最後の式を 関数の戻値とする仕様にしました。

    背景

    Alan で式と文を区別していた理由
    1. C で if文の条件式中に知らず知らず代入式を書いてしまう 落とし穴を避けるため。 代入を文とすれば、文法レベルでこの落とし穴は避けることができる。
    2. 全てを式にすると、その結果値を使わないケースが続出します (手続き的に使用するなら、ですが)。 そうすると、メモリが使われないまま捨てられることになり効率が悪くなる のではないか、という懸念。
    今度、全てを式にしようと考えた理由
    1. Stroustrup の D&E にインスパイアされた。
    2. で、その目で先の問題を見ると回避策があることに気付いた。つまり、
      1. Cでは条件式の結果値は整数型で 0 かそうでないかを true/false としていたため int a; if( a = 3 ) がコンパイラを通ってしまうが、 Alan ではbool型かどうかチェックするのでだいたい 90% はカバーできる。 bool型の代入式はここからは漏れてしまうが、最近の C/C++ や Ruby を 見習って WARN を出せば良い。
      2. 意味解析フェーズで最適化すればいい。 つまり、結果値を使用してない式に関してはなるべく無駄を省くようにする。
    3. Ruby のように end にメソッドが書ける。 if a > 3 then b else c end.method という記述に、最初一瞬 '?' でしたが、すぐに「おお!」と 目を開かされたわけです。要は Ruby からのパクリですねm(__)m。
    4. 3項演算子 a?b:c が不要になる:
      d = if a > 10 then b else c end
      
      って、a?b:c より if a then b else c end の方が冗長でいやだ、 という考えもあるとは思います。 けれども、3項演算子ってそれほど使用頻度が高いとは思えません。 たまに使えるところで簡潔に表現できてうれしいことはうれしいのですが。 それよりも、言語仕様をシンプルにすることの方に重点を置いた、という ところです。
      「もっともシンプルな Lisp が既にあるじゃん」という反論も あるかもしれません。もっともです(^^;)。 文法に多少メリハリをつけたい、というところだとご理解下さい。 メリハリがありすぎると C++ のようになってしまいますが(^^;)。 ま、最終的には、俺の趣味、ということで。
    5. 自明ですが、処理途中の作業変数が不要になる。もちろん、文的にも 使用できる。つまり、式が文を包含しているなら、全て式とする方が文と式の 混在よりは良い、という結論です。

  2. ドット演算子(.)が任意の式で使える
    ようになりました (これまでは識別子にのみ使用できていました)。 なので、次のような記述が可能になります:
    put( ("Hello" + "World").upper )
    
    やっと普通の言語のレベルに追い付きました(この点において)。

  3. 配列変数の定義式を変更
    しました。
    1次元配列 2次元配列
    array[int,10] a; array[int,10,20] b;
    array[int]: a = 10 array2[int]:b = (10,20)

  4. Filesys パッケージ
    を追加しました。ディレクトリ操作、 ファイル名操作あたりをサポートします。 まだほんの端緒ですが。

  5. str.gsub()
    str型に gsub() メンバ関数を追加しました。 残念ながら、Perl の s///ge、Ruby の gsub(//){...} に相当することは まだできません。Perl の何気ないオプション 'e' が closure とは知りませんでした。 closure ...どうしましょうかねぇTBD遠い目。

  6. stderr
    標準エラー出力 stderr を追加しました。stderr.put(...) で 標準エラー出力に任意の変数を put できます。

  7. ENV
    環境変数を map のように扱う変数 ENV を導入しました。 Perl, Ruby からのパクリですね。

  8. str: get(int:len)
    標準入力からデータを得る関数 です。 今までデータを取得する方法は stdin イタレータから のみでしたが、指定長のデータを得る方法として導入しました。

  9. substr: matched(int:i)
    直前のパターンマッチ式 ( s in /pattern/ )から マッチした部分文字列を得るフリー関数です。 (これまでは、rex 型のメンバー関数 rex.matched() のみだったので 正規表現リテラルから部分文字列をとってこれませんでした。)

  10. wikimini
    結城浩さんのwikiminiAlan版 を作ってみました。 (というよりは、wikimini の作成を通じて幾つか機能を Alan に追加していった、 というところです。Filesys, stderr は Alan版 wikimini 作成過程の副産物です。

    が、おかげで Alan v0.15 に2つの大きな問題点があることが分かりました:

    1. str型の最大長 254byte の制約のため、1ページも 254byte以内という ことになってしまったこと。
    2. Perl の s///eg, Ruby の gsub(//){...} に相当する機能が記述できないこと。 Perl の s/// 演算子の何気ないオプション e が closure であることを 今回初めて知りました。この実装は Alan 仮想マシンの根幹に関わる部分 なので、今回は実装を見送らざるを得ませんでした(泣)。
    これらはおいおい考えることとします。

  11. v0.16
    そろそろオブジェクト指向(ユーザクラス定義)・・・ と行きたいところですが、その前に、総称プログラミング を実装してみたいと考えています。 が、その前に、幾つか細かい部分の修正をして基礎を固めておこうかと 考えています。v0.16 はそういったマイナーチェンジを行います。

  12. v0.17
    ・・・で、総称プログラミング。C++ STL を参考に、 Alan に取り入れてみたいと考えています。

    STL によって イテレータとの組合わせで任意の型の線形検索が find() 関数一本で記述できる。 ・・・このことに大きな衝撃と興味を抱いたことでした。 C++ STL は強力ですが、文法や使い方がやや複雑です。 何とか Alan で記述できないだろうか、と考えているところです。

    さて、どうなることやら・・・、乞うご期待。