本節は、コンピュータ科学の技術的側面についてほとんど、あるいはまったく知識を持たない読者のために用意されたものである。本書の評論や講演を理解するために本節を読まなければならないということはないが、プログラミングやコンピュータ科学についてまわる専門用語をよく知らない読者にとっては役に立つかもしれない。
コンピュータプログラマは、ソフトウェア、すなわちコンピュータプログラムを書く。プログラムは、特定の仕事をこなすために何をすべきかをコンピュータに指示するコマンドで書かれたレシピのようなものである。おそらく、読者はさまざまなプログラムをご存知だろう。Webブラウザ、ワープロ、電子メールクライアントなどといったものがそれである。
通常、プログラムはまず、ソースコードという形を取る。この比較的高い水準のコマンドは、CとかJavaといったプログラミング言語で書かれる。ソースコードが書かれると、コンパイラと呼ばれるツールを使って、これをアセンブリ言語というそれよりも低い水準の言語に翻訳する。次に、アセンブラと呼ばれる別のツールを使って、アセンブリ言語のコードをマシン語という最終段階(最低水準)のコンピュータがネーティブに(母語として)理解する言語に変換する。
たとえば、Cを学ぶ人が最初に書くプログラムで、(コンパイル、実行すると、)画面に「Hello World!」と出力する*1「Hello World!」 プログラムについて考えてみよう。
int main() {
printf("Hello World!");
return 0;
}
Java 言語では、同じプログラムを次のように書く。
public class hello {
public static void main(String args[]) {
System.out.println("Hello World!");
}
}
しかし、マシン語では、次のようになる(これは全体のごく一部である)。
1100011110111010100101001001001010101110
0110101010011000001111001011010101111101
0100111111111110010110110000000010100100
0100100001100101011011000110110001101111
0010000001010111011011110111001001101100
0110010000100001010000100110111101101111
上記のマシン語の形式は、バイナリ (2進)というもっとも基本的な表現である。コンピュータのすべてのデータは、0または1の値の連続から構成されているが、人間がそのようなデータを理解するのは非常に難しい。バイナリに簡単な変更を加えるためには、特定のコンピュータがマシン語をどのように解釈するかについての詳細な知識を持っていなければならない。上記の例のような小さなプログラムであれば、そのようなことも可能かもしれないが、およそ面白い意味を持つようなプログラムでは、わずかな変更を加えるだけでもとてつもない労力が必要になる。
たとえば、C言語で書かれた先ほどの「Hello World!」プログラムに変更を加え、英語で「Hello World!」と出力する代わりにフランス語を使う場合について考えてみよう。この変更は簡単であり、新しいプログラムは、次のようになる。
int main() {
printf("Bonjour, monde!");
return 0;
}
Java 言語で書かれたプログラムの直し方も同じようなものだと簡単に類推できるだろう。しかし、バイナリ表現を書き換えようとすると、多くのプログラマでさえ、どこから手を付けたらよいのかわからなくなってしまう。私たちが「ソースコード」というとき、それはコンピュータしか理解できないマシン語のことではない。CとかJava といったより高い水準の言語のことを指している。人気の高いプログラミング言語としては、そのほかにC++、Perl、Pythonなどが挙げられる。理解しやすいものとしにくいもの、プログラムがきやすいものとそれほどでもないものはあるが、プログラムがコンパイル、アセンブリされたあとの複雑なマシン語と比べれば、どれもはるかに操作しやすい。
理解すべきもう1つの重要概念は、オペレーティングシステム(OS)とは何かということである。オペレーティングシステムとは、入力と出力、メモリの割り当て、タスクのスケジューリングを処理するソフトウェアである。一般に、GUI(グラフィカルユーザーインターフェイス)などのよく使われるプログラム、便利なプログラムは、オペレーティングシステムの一部とみなされている。GNU/Linuxオペレーティングシステムには、GNUソフトウェアと非GNUソフトウェアの両方が含まれており、Linux と呼ばれるカーネルが含まれている。カーネルは、入出力やタスクのスケジューリングなど、アプリケーションが必要とする低水準の仕事を処理する。GNUソフトウェアは、GCC(さまざまな言語に対応している汎用コンパイラ)、GNU Emacs (非常に大量の機能を持つ拡張性の高いテキストエディタ)、GNOME (GNU デスクトップ)、GNU libc(カーネル以外のすべてのプログラムがカーネルと通信するために使わなければならないライブラリ)、Bash(コマンドラインを読む GNU コマンドインタープリタ)などのオペレーティングシステムのカーネル以外の多くの部分から構成されている。これらのプログラムの多くは、GNU プロジェクトの初期の段階でリチャード・ストールマンの主導で開発されたもので、現代のあらゆる GNU/Linux オペレーティングシステムに付属している。
重要なのは、たとえ自分では与えられたプログラムのソースコードを書き換えたり、これらのツールを直接使いこなしたりすることができなくても、それができる人を見つけるのは比較的簡単だということである。そのため、プログラムのソースコードを持っていれば、通常、それを変更、訂正、カスタマイズしたり、プログラムについて学習したりする力を手にすることができる。これは、ソースコードが与えられなければ掴めない力である。ソースコードは、ソフトウェアをフリーにするために必要なものの一つである。他の要件は、本書を読み進めるうちに、フリーの哲学、発想法とともに明らかになってくるだろう。楽しみにしていただきたい。
リチャード・E・バックマン
ジョシュア・ゲイ
(define (factorial n)
(if (= n 0)
1
(* n (factorial (- n 1)))))
このプログラムは、与えられた数値の階乗を計算する。たとえば、(factorial 5) を実行すると、5×4×3×2×1 を計算して120と出力する。本文に一切の変更を加えず、この著作権表示を残す限り、この文章全体のいかなる媒体における複製および頒布も許可する。