1. 導入¶
1.1. 基本的な疑問¶
どうしてこんなにたくさんプログラミング言語があるのか?
さらに Go, Swift, Rust など新しい言語が作られている。
これらの言語はお互いに違っているが、どう違うのか?
1.2. プログラミング言語を定義する方法¶
新しい言語をデザインする時、曖昧さがなく、簡潔で、理解しやすい形で定義することはきわめて重要である。
Scheme には数学的に厳密な 定義 があるが、残念ながら理解するのが難しい。
BASIC や C は、最初は厳密な定義がなかったので、微妙に異なるいくつかの処理系ができてしまった。PHPも最近まできちんとした定義がなかった(cf. Announcing a specification for PHP )。
言語を定義するには、次の二つのことを決める必要がある。
構文(syntax) --- どのように書くか、ということ
意味(semantics) --- 実行すると何が起きるか、ということ
1.3. 構文的な違い¶
1.3.1. 文字¶
1.3.2. 文法¶
Esoteric progarmming language というものがある。
1.4. 意味的な違い¶
プログラミング言語におけるパラダイムとは、哲学的に言えば「計算とは、何か」ということ。
- 命令型(手続き型)
計算とは、状態を変化させることである。
- 関数型
計算とは、式を簡約することである。
- 論理型
計算とは、命題を証明することである。
1.5. 実行方式の違い¶
プログラム実行の代表的な二つの方式:
- コンパイラ
プログラムを実行する前にすべて機械語に翻訳してから実行する。
- インタプリタ
インタプリタがソースコードに書かれた命令を1ステップずつ実行していく。
理論的には言語と実行方式は独立だが、多くの場合はコンパイラ型言語かインタプリタ型言語に分かれる。
さらに、複合的な実行方式もある:
- バイトコード
バイトコードは、機械語に似ているがハードウェアとは独立に定義されたもので、インタプリタ(バーチャルマシンまたはVMと呼ばれることが多い)によって効率良く実行できる。コンパイラがソースコードをバイトコードに翻訳し、その後VMによって実行される。
- トランスパイラ
ある言語のソースコードを、他の高級言語のソースコードに翻訳する。例えば、TypeScriptはJavaScriptに翻訳されてから、JavaScriptのインタプリタによって実行される。
- JIT (Just-In-Timeコンパイラ)
インタプリタに付加される機能で、プログラムを実行中にその一部を機械語に翻訳する。
1.6. 良いプログラミング言語¶
「読みやすさ」と「書きやすさ」は一般に両立しない。
「効率が良い」とは?
実行速度が速い
コンパイルが速い
プログラムを書くのが速い
信頼性を高くするには?
静的型付けや例外処理の強制 → 嫌いな人もいる
エコシステム
言語の学習が大変だとあまり使われない
言語処理系の開発が大変だとあまり使われない
ライブラリが揃っていないとあまり使われない
1.7. プログラミング言語の理論を勉強する理由¶
発想の幅が広がる --- 言語は概念を表現する道具に過ぎないのだが、使う言語によって発想が制約されるのも事実。「ハンマーしか持っていなければ、すべての問題は釘に見える」ということわざがある。
新しい言語を容易に学べるようになる --- 技術の進歩についていくには常に勉強しなければならない。
ソフトウェア技術の重要な基礎である --- 基礎をおろそかにしては高度な研究はできない。