将来を見据えたウェブ・アプリケーションの構築:The Codestのエキスパート・チームによる洞察
The Codestが、最先端技術を駆使してスケーラブルでインタラクティブなウェブアプリケーションを作成し、あらゆるプラットフォームでシームレスなユーザー体験を提供することにどのように秀でているかをご覧ください。The Codestの専門知識がどのようにデジタルトランスフォーメーションとビジネス...
「The Pragmatic Programmer』(まだ読んでいないなら、この記事を読むのをやめて今すぐ読もう!)には、毎年1つずつ新しいプログラミング言語を学ぶべきだと書いてある。
たとえ努力が多すぎるという意見もあるかもしれないが、私たちは皆、それが良いアイデアかもしれないということに同意できるだろう。新しく学ぶ言語を選ぶのは、そう簡単なことではない。実際に使うことがないかもしれないものに時間を割きたくないでしょう?しかし、時には例外を認めて、ただ楽しむために何かを学ぶべきかもしれない。今回紹介するのは、Brainfuck言語だ。数分で学べる言語なので、無駄に時間を投資しすぎるという問題はない。また、Brainfuckを使ってどんな問題を解いても、あなたの脳を刺激することをお約束します(すべてのファックはおまけです ;)。さあ、始めよう!ウィキペディアによると:
ブレインファック は 秘教的プログラミング言語 ウルバン・ミュラーによって1993年に作られた。この言語は8つの単純なコマンドと命令ポインタだけで構成されている。完全にチューリング完全ではあるが、実用を目的としたものではなく、プログラマーへの挑戦と娯楽を目的としたものである。
各セルが0に初期化された、無限に長いリボン(またはテープ) を想像してほしい。入力用と出力用の2つのバイトストリームもある。命令は1つずつ順次実行される。最後の命令を実行した後、マシンは停止する。
コマンド
何をするのか?
>
データ・ポインタを右の次のセルに移動する
<
データ・ポインタを左の次のセルに移動する
+
現在のセルの増分値
–
現在のセルの値をデクリメント
.
現在ポイントされているセルのバイトをASCIIで出力する。 コード
,
標準入力から1バイト読み取り、その値を現在のセルに格納する。
[
もし現在のセルが0なら、マッチする ]セルにジャンプする。
]
一致する [ ] にジャンプする
以外のすべての文字 ><+-.,[]
は無視される。
簡単な例を見てみよう:
,+.
以下のように解釈される:
その結果、入力から1文字が読み込まれ、ASCIIテーブルから次の文字が出力される。
Brainfuckで有用な(?)プログラムを書く前に、インタプリタかコンパイラが必要である。公式のものはないが、問題ない。インターネット上には非公式なものがたくさんある。私がお勧めするのはこの2つである:
「Hello World!"は、新しい言語を学ぶときに最初に書くべきプログラムである。しかし、Brainfuckでこれを書くのは他の言語に比べて少し難しい。まずはもっと簡単なものから...画面に "H "という一文字をプリントアウトするプログラムを書いてみよう(とてもエキサイティングだ :D):
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.
どのように動作するのか?現在のセルの値を72に設定し(72刻み)、"."(HはASCIIコードで72)を使ってそれを画面に表示する。これで "Hello World!"を画面に表示するために何をすべきかはわかったと思うが、その前にちょっとしたリファクタリングをしよう。をすべて書くには、タイピングとカウントが多すぎる。これを短くするには [
そして ]
をループさせる。値を72に設定するには、例えば値を10ずつ7回増やすループを作ればいい。こうすると70になる。2足すと72になる。このようになる:
++++++++++ # cell0を10にセットする。
[cell0 が 0 になるまでループする。
- # cell0 を減らす
> # データポインタを右に移動 (cell1)
+++++++ # cell1 を 7 だけ増やす。
# データ・ポインタを右に移動 (cell1)
++ # 2増加
. # 結果を表示
すべてがどのように動くかを明確にするためにコメントを入れた。コメントなしの同じプログラム:
++++++++++[->+++++++++.
美しいでしょ?
ハロー・ワールド!」プログラムに戻ろう。最初のセルの値を72(H)に設定して印刷し、2番目のセルの値を101(e)に設定して印刷し、3番目のセルの値を108に設定して印刷する、といった具合だ。以下はこのアルゴリズムの実装である:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>
++++++++++++++++++++++++++++++++.>
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>
+++++++++++++++++++++++++++++++++.>
符号をひとつひとつ書くほどクレージーではないので、少しズルをしてRubyでこのプログラムを作成した:
"ハロー・ワールド!".chars.map { |c| c.ord.times.map { "+" }.join + ".>" を入れる。}.join("n")`
そう、"Hello World!"を表示するのに1120バイトしかないのだ!文字ごとに新しいセルを使う代わりに、1つだけ使ってみよう。文字 "e"(101)を印刷するには、セル0(72)の値を再利用すればいい。それを29回(101 - 72)増やすことができる。その結果は次のようになる:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.
+++++++++++++++++++++++++++++.
+++++++.
.
+++.
-------------------------------------------------------------------------------.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++.
++++++++++++++++++++++++.
+++.
------.
--------.
-------------------------------------------------------------------.
またズルした!」:
puts "Hello World!".chars.inject(["", 0]) { |(code, prev), char| [code + "++-"[char.ord - prev 0] * (char.ord - prev).abs + ".n", char.ord].}[0]`)
大きな進歩を遂げた。1120バイトから377バイトになった。しかし、まだ改善の余地がある。いくつかアイデアをあげよう:
+
そして -
ウィキペディアのバージョンは以下の通り:
++++++++[>++++[>++>+++>+++>+<<<+>+>->>+[<]>.>---.+++++++..+++.>>.<-.>+.>++.
わずか106バイトで、最後に改行が表示される!すごい。
さて、もっと難しいものを書く準備ができた。入力から行を読み取り、それを逆順に印刷するプログラムを書いてみよう。最初の問題は、文字を読んで改行文字で止めることだ。覚えておいてほしい。 休憩
, もし
または他の類似した声明。私たちは [
そして ]
.入力からすべての文字を読み取り、連続するセルに入れるプログラムから始めよう:
,[>,]
最初の文字を読むことから始まり、最後の文字まで続く。 ,
オペレーション・リターン 0
.を返す実装では永遠にループします。 O
にとって あとがき
(言語はこの動作を指定していない)。では、どうすれば改行文字で止めることができるのか?ここにトリックがある:
+[++++++++++>,----------]
ループが少なくとも1回は実行されるように、cell0 を 1 に設定して開始する。ループの中で、現在のセルの値を10増加させ、データ・ポインタを次のセルに移動させ、1文字読んでその値を10減少させる。こうすることで、もし改行文字(ASCIIでは10)が読み込まれれば、プログラムは次の繰り返しで停止し、そうでなければ10を加算して値を元に戻す。
このステップの後、セルは次のようになる:
11 c1 c2 c3 0* 0 0
Cn
は入力からn番目の文字であり *
は現在のデータ・ポインタの位置である。さて、データ・ポインタを左に動かし始め、値11に達するまですべてのセルを印刷しなければならない。以下は、このタスクに対する私の考えである:
+[++++++++++>,----------]<-----------[+++++++++++.<-----------]
自分で分析することを勧めるよ。)
難解なプログラミング言語であるBrainfuckを偶然見つけたとき、私は最初、単なるギミックかジョークだと見下した。この奇妙な、そして多くの人が言うように、気の遠くなるような難解な言語は、私には娯楽を目的としたものにしか見えなかった。しかし、時が経つにつれ、Brainfuckに対する私の認識は大きく変わった。
ブレインファック」の謎めいた性質は、あなたを挑発し、次のような視野を広げるよう駆り立てる。 プログラミング言語.この難解な言語は、我々が慣れ親しんでいる高級言語の美しさと必要性を理解させてくれる。プログラミング言語の領域における抽象化、適切な命名規則、整理されたメモリーレイアウトの重要性が浮き彫りになる。これは、たった8つのシンプルなコマンドからなるミニマリスト的なデザインのBrainfuckにはないものだ。
Brainfuckはチューリング完全言語であり、明確で首尾一貫したソースコードを持つことの重要性をさらに強調している。プログラムを書くのが最も難しい難解な言語の1つとして認識されているにもかかわらず、皮肉なことに、BrainfuckコンパイラやBrainfuckインタプリタを作りたい人にとっては、初心者のお気に入りとして輝きを放っている。その理由は、コマンドセットがシンプルであることと、複雑な構文解析を必要としないからだ。
ブレインファック・プログラムの作成は、2つの点でユニークだ。第一に、単一のメモリ・ポインタを使うことに慣れる必要があり、ソースコードについてこれまでとは違った考え方を強いられる。そして2つ目は、「ゼロ・オプション」があることだ。これはメモリセルをゼロにリセットする機能で、他の正式なプログラミング言語ではあまり見られない機能である。
Brainfuckには、見た目以上の学習効果がある。十分な時間と適切な考え方があれば、同じプログラムをさまざまなBrainfuckコードを使って何通りにも書くことができる。この旅の後半は、創意工夫を凝らし、6つのシンボルを利用する新しい創造的な方法を見つけることだ。
Brainfuckのインタープリターは、最小限のものではあるが、コードがどのように実行され、プログラムが何を表示するのか、チューリング完全言語の根本的な仕組みを深く理解させてくれる。結局のところ、Brainfuckは単なる難解なプログラミング言語ではない。まったく新しい次元のものであり、プログラムの見方、理解、書き方に対する別のアプローチなのだ。