http://d.hatena.ne.jp/propella/20070808/p2 に書いたアイデアの続きです。非正格なスタック言語というのは半分冗談ですが、データフロー記述言語としてのスタック言語を想定すると冗談じゃ無くなってきました。データフロー記述言語というのはどういう意味かと言うと、スタック言語を使って 3 や 4 等の数値計算を行う代わりに実行グラフを計算して行くという物です。過去の文献から上手く行くだろうと予想していたのですが、自分で実装してみると予想以上の出来です。例えばこんな感じです。
3 4 + . -- 普通の計算 > 3 :: 4 + . > 3 4 :: + . > 7 :: . > :: 7 'x' get 'y' get + . -- あとで x と y を計算するグラフ > 'x' :: get 'y' get + . > :x :: 'y' get + . > :x 'y' :: get + . > :x :y :: + . > (+ :x :y ) :: . > :: (+ :x :y )
どこが凄いかと言うと、+ という同じ演算子を使って普通の計算とグラフの構築が出来るのです。我ながらかっこいい!問題は条件文です。Joy では [] を使って遅延評価を表現するのですが、話が急にややこしくなります。そこで 普通の計算での遅延評価をきっぱり諦める事にすると見事に上手く行きました。
true 3 4 opt. -- 普通の計算 > true :: 3 4 opt . > true 3 :: 4 opt . > true 3 4 :: opt . > 3 :: . > :: 3 'cond' get 'x' get 'y' get opt. -- 後で実行 > 'cond' :: get 'x' get 'y' get opt . > :cond :: 'x' get 'y' get opt . > :cond 'x' :: get 'y' get opt . > :cond :x :: 'y' get opt . > :cond :x 'y' :: get opt . > :cond :x :y :: opt . > (opt :cond :x :y ) :: . > :: (opt :cond :x :y )
opt という同じ関数で、普通の条件式も実行グラフも構築できました(ここで、順番を変えただけじゃないかどこが難しいのだ山宮は気が狂ったのかとお感じになられるかも知れませんが、長い背景については長いので省略します) 。どうせ実行グラフの方はシステムが遅延評価するのでこれでよいのです。なぜこれで上手く行くのかと言うと再帰が無いからで、再帰が必要ならやっぱり普通の計算版も必要な時に計算するという Haskell のモデルが必要です。簡単に出来そうならやってみます。