チュートリアル:Hello,Worldアプリケーション
簡単なHello,Worldプログラムを題材に電波プログラミングを紹介する。
プログラミング言語としてはPerlを使用するが、プログラム例としては単純なものなので、読者諸兄によってそれぞれ好みの言語に移植することは容易であろう。
要件定義
電波プログラミングは電波文と異なる。あくまでプログラミングであるので、要件定義は必要である。
例としてHello,Worldプログラムの要件を定義するならば、以下のようになるだろう。
- 端末上に"Hello,World!"というASCII文字列を表示すること
"Hello,World!"という文字列を表示する、という点について注意したい。つまりこの時点で、以下のようなプログラミングは要件を満たさないことになる。
print "HW!\n"; #私の内的な宇宙においてHello,World!の意味をなす文字列
また、以下のようなプログラムは当然のことながら「計算機的」という意味で本稿の目的とはそぐわない
print "Hello,World!\n"; #完全に計算機的なロジックに依拠している!
電波プログラミングの世界では、要件を超計算機的なロジックにおいて実装することが求められる。超計算機的なロジックは計算機的なロジックと異なり、最適化が不可能であることが多く、また様々な思想信条に左右されるためこれが正解というものがない。それぞれが己の内的世界と向かい合うことによって要件を解釈し、また実装することが必要とされるのである。
「自分の」電波プログラムを行う前に、例えばどのような手法があり得るか?ここで比較的ポピュラーな実装例を2,3紹介してみたい。
乱数派による実装例
電波プログラミングの有力な派閥として乱数派というのがある。彼らのロジックは明快であり、「全ての出力は疑似乱数の周期中に存在する」というものである。
彼らの論理でHello,Worldアプリケーションを実装するならば以下のようになるだろう。
while(1){
my $str="";
for($i=0;$i<12;$i++){
$str .= pack("C*", 33+int(rand()*93)) #乱数からASCII文字を一つとりだす
}
print $str,"\n";
if($str eq "Hello,World!"){
last; #break
}
}
実行してみるとプログラムはrand()関数によって得られた疑似乱数周期の中から"Hello,World!"という文字列を探索し、見つけるとただちに停止する。
残念ながら現在(2008年)においては、世界最高のスーパーコンピューターですら乱数派の要求するスペックとはほど遠い為、おそらくは読者諸兄のPCでこのプログラムが諸君の寿命がつきる前に停止することはないだろう。
しかしながら、「全ての出力は疑似乱数の周期中に存在する」という超計算機的なロジックに基づく限りにおいて、このプログラムが最終的に"Hello,World!"と表示することは自明であるため、電波プログラム的な意味においてこのアプリケーションは完全だと言える。
グーグル派による実装例
グーグル派のロジックは「全ての求められる出力はGoogleで検索することによって得られる」というものである。彼らはまた、グーグル指向最適化言語環境(Google Oriented Optimization Language Environment=GOOGLE)という独自の言語系を使うことでも知られている。GOOGLE言語の仕様では唯一の関数はgoogle(string)である。
彼らのコードは以下のようになるだろう。(実行結果はリンクを押す事で表示される)
見事にHello,World!がいくつも出力されている。(要件定義では文字列は1つとは規定されていないのでこれも解である)
しかしここで読者諸氏は疑問に思われるかもしれない。例えば出力する文字列が"Hello,World!"ではなく以下のように「おめがぽらんげ」というような未知語であった場合は、意図したとおりに出力されないのではないか?と、
その心配はない。何故ならこのwikiが「おめがぽらんげ」と記述していることによって、いつかはGoogle botがクロールを行い、意図どおりに出力されるようになるのだ!
これがグーグル派における「再帰」である。
自分なりの超計算機ロジックを見出す
電波プログラミングにとって重要なことは、自分なりの超計算機ロジックを見出すことである。
やり方は人それぞれであるが、筆者の電波プログラミングを行う手法を紹介しよう。
もしあなたが計算機的プログラマであるなら、コンピューターが何故動いているかなどといった瑣末な知識はむしろ邪魔となるため綺麗さっぱり忘れてしまおう。ここで必要なのは"Hello,World!"と出力するにはどうすればいいか?ただその一点であると言っていていい。
おもむろにエディタを起動し、以下のように書いてみる
Hello,World!
出力はされた。よし。しかし、これは自分が手を動かした結果である。これではプログラミングとは言えない。これを計算機に行わせる事ができればよいのである。一瞬キーボードを叩くロボットの姿が垣間見えれば電波プログラミングの入り口にさしかかったと言っていいだろう。しかしロボットはない。プログラミング言語というのを使ってすれば良いらしい。ここで一気にではなく、少しずつ、ギリギリと絞りながら使い慣れたperlのシンタックスを思い出そう。端末に出力する命令は"print"である。これは間違いない、では"Hello,World!"は?文字列とはそもそも何だ?終端がnullのバイト列であるなどと考えてしまったのなら、それは計算機的プログラミングである。頭を冷やすべきだ。そうではない。文字列は文字列だ。"Hello,World!"は"Hello,World!"なのだ。エディタ上に現れた文字を見直そう、この文字はどうやって現れたのだ?キーボードを打った。そうだ、そうだった。では何故キーボードを打ったのだ?"Hello,World!"と書きたいと思ったからだ。つまり意識は計算機に通じるのである。
となればそれをプログラミングすればよい。意識を変数$mindと置く
print $mind;
実行してみよう。出ない。ここで当たり前だと思ってしまったら失格である。最初からやり直そう。何故でないのか?意識してないからだ、そうか。意識をしよう。意識をしながら実行する。やはり出ない。
気を落ち着かせるためにコーヒーでもいれよう。コーヒーと好みのスナックを口にしながらコンピューターに向かう。ふふふ僕はまるでハッカーみたいだぞ!さあ、$mindに僕の意識を代入するのはどうすればいいのか?とりあえず関数を呼び出してみよう
$mind=readMyMind();
print $mind;
実行する。エラー。readMyMind()がない。そのような関数はperlにはないことに気づく。関数がなければ自分で作ればいいのだ!とりあえず、"Hello,World!"だけを考えていると呼吸が止まってしまうので、全ての意識を連結して返す関数になる。
sub readMyMind{
return join("",@MyMind);
}
あとは意識をperlに転送するために自分の意識をMyMind配列にマップすればよい。
@MyMind=("オリオン座の下でセックス","30代で職歴なしはヤバいよなあ・・",
"宝くじがあたればいいんだ","死にたい","俺何やってるんだろう","Hello,World!");
$mind=readMyMind();
print $mind;
sub readMyMind{
return join("",@MyMind);
}
実行する
オリオン座の下でセックス30代で職歴なしはヤバいよなあ・・宝くじがあたればいいんだ死にたい俺何やってるんだろうHello,World!
でた!やった!
…と、あくまで例であるが、このような形で電波プログラムを行うことができる。
最終更新:2011年01月24日 22:03