前回はLucidの処理系であるpLucidについて紹介した。
今回はLucidについて触れていきたい。
Lucidとは?
Lucidというのは、前回も触れたとおり、データフロープログラミング言語の1つ。
自分がこの言語に触れて一番変わってるなぁと思ったのは、変数が数列のように履歴を持つというところ。
なので、プログラミングが、漸化式を書くような感じになってたりする。
まぁ、これは実際の例を見てみないと分かりづらいと思うので、後で。
Hello, world!
とりあえず、新しいプログラミング言語に触れるなら、まずこれでしょ、ということで、Hello, world!から。
LucidでHello, world!を書くと、次のようになる:
`Hello, world!'
ちょっと注意が必要な点としては、最初のはクォートはバッククォートで、最後のはシングルクォートだということ。
これをpLucidで実行するには、まず適当なファイルに保存して(ここではhello
というファイルとする)、以下のようにコンパイル:
$ lucomp hello
ただし、これはlucompから呼び出されるpass1、pass2、pass3、pass4、pass5が、PATHの通った適当な場所に置かれているのが前提。
もしこれらがPATHの通った場所に置かれていない場合、以下のようにして、パイプで処理をする:
(ここではpass1〜pass5がカレントにあると仮定)
$ ./pass1 hello | ./pass2 | ./pass3 | ./pass4 | ./pass5 hello
すると、hello.i
という中間のバイナリファイルが生成される。
中間のバイナリファイルが生成されたら、次のように実行:
$ luval hello.i
さて、実行したらどうなるのかというと、こうなる:
$ luval hello.i Evaluation begins ......... output( 0) : `Hello, world!' output( 1) : `Hello, world!' output( 2) : `Hello, world!' output( 3) : `Hello, world!' output( 4) : `Hello, world!' ...(省略)... output(995) : `Hello, world!' output(996) : `Hello, world!' output(997) : `Hello, world!' output(998) : `Hello, world!' output(999) : `Hello, world!' $
なんじゃこりゃ!?、ってなるよねw
ただ、これがつまり、変数が数列のように履歴を持つということを意味している。
Lucidでは、一番外側にある式が評価され、その値が出力となる。
このHello, world!では、`Hello, world!'
という文字列が式になっていて、その値が評価される。
だったら、`Hello, world!'
が一回表示されて終わりなのでは?となりそうだけど、そうはならない。
というのも、これは、Lucid的には次のような意味になるから:
そう、outputという変数は、単一の変数ではなくて、数列のように、0番目の値、1番目の値、2番目の値、・・・と、複数の値を含んでいるようになってる。
なので、pLucidはその値を順番に出力していった、と。
(実装的に上限が1000で固定になってるので、999番目の値で出力は止まってる)
うん、変な言語w
Hello, world!(真)
じゃあ、一回だけHello, world!を出力して終わりにしたかったら、どうするか。
数学的に考えれば、次のように場合分けすればいいことになる:
なお、eod
は、データの終わりということ。
これをLucidで書くと、次のようになる:
`Hello, world!' fby eod
さっきと同じようにコンパイルして実行すると、以下のような出力になる:
$ ./luval hello.i Evaluation begins ......... output( 0) : `Hello, world!' Statistical Information about the evaluation # of memory buckets created = 0 # of space/time/place tags created = 3
このとおり、1回だけ出力され、終了する。
(それ以外の出力もなんかいろいろ出てるけど・・・)
ここでポイントとなっているのは、fby
という演算子。
これは"followed by"の略で、1回目は左項が評価され、2回目以降は右項が評価されるようになっている。
なので、output(0)
は左項が評価されて`Hello, world!'
になり、output(1)
以降は右項が評価されてeod
となるので、データの終了ということでそこで出力が停止する、と。
ちなみに、fby
は右結合なので、次のように書くと、2つ出力して終わる感じになる:
`Hello, world!' fby `Good bye!' fby eod
実行例は、以下:
$ ./luval hello.i Evaluation begins ......... output( 0) : `Hello, world!' output( 1) : `Good bye!' Statistical Information about the evaluation # of memory buckets created = 0 # of space/time/place tags created = 4
理屈としては分からなくもないけど、なんとも分かりにくい(^^;
アイディアは面白いと思うんだけど、もうちょっと分かりやすい記法はなかったものか・・・
なお、今自分がいじっているGitHubのリポジトリは、luvalを実行するとセグメンテーションフォールトが発生するので、ここでの実行例は、おそらくGCCでオリジナルのコードをそのままビルドして作られたバイナリを使ってる。
自分のいじってる方も、そのうちちゃんと動くようにしたい。
今日はここまで!