A Quest for 非同期入力

きっかけは、どう書く?.orgのこんなお題から。
どう書く?org
起動すると、標準出力に1秒毎に'a'の1文字を出力し続けるプログラムで、 以下の条件を満たすもの

    * 'q'キーが押されるとプログラムは終了する
    * 出力中に'p'キーが押されると一時停止する
    * 一時停止中に'p'キーが押されると出力を再開する

先人が苦労なさっていた。

で、自分でいろいろさがしたが、たしかに見つからない。

Erlangでテトリスを、というexampleがあるわけだから、キー入力が取れないわけが無い。これは、gsというグラフィックライブラリが使われていた。いかにも大げさである。

question-erlangのMLで「プログラミングErlang」の著者のJoeが質問してたorz..
Erlang Central | Page not found
まぁ、彼自身書き方がわからんというのではなくて、最近じゃどういうのがメジャーなの?というような質問だったが。
回答では、slというライブラリが紹介されていた。これはErlang標準のものではなくて、Jungerl - a dense and chaotic Jungle of Erlang codeで配布しているものだった。どうやらTcl/Tkを取り込んでいるようだ(入出力に使っているかは不明)(追記:←嘘でした。Tcl使ってるのはgsで、slはリンクインドライバらしいですドライバのCのソース呼び出し側のsl.erlに、erl_ddll:load_driver(code:priv_dir(sl), "sl_drv") という記述があります。)
コードはこんなふうになるらしい。

{ok, TTY} = sl:open("/dev/tty", [{echo, false}, {mode, raw}])

これで、端末デバイスファイル"/dev/tty"を読み書きできるようだ。
自分が使っている端末デバイスを特定できれば、実用にはなりそうだが、今ひとつだな。

なんで標準のライブラリが無いのか?

Erlang本家のFAQに記載があった
要するに、Erlangにおいては、並列実行性とかリアルタイム性はキモなわけで、コードを読んで、どこでブロックするかとかいうことが明らかじゃないとデバッグが困難になる。デバイスの読み書きはブロックするのが当たり前だから、そういうところはライブラリに押し込んでしまうか、外部のプログラムに追い出してポートで接続することにして、Erlangのコードでは明示的に書けないようにしておきたい、らしい。
また、デバイスの仕様はOSによってもさまざまであるから、標準添付のライブラリに入ることもないかなーと。それはそれで見識、だあね。
MLでも議論にはなってたみたい。
Erlang Programming LanguageErlang Programming Language

自分なりのアイデア

エンドユーザにはtelnetを起動してもらって、サーバとして動かすのはどうかな?