2014-09-23
理想の言語とは何かを考える

[ PR ]
前回まで、過去を知ることでどう変わってきたかを見てきました。
今回は、未来を想像して見たいと思います。プログラミングをしている皆さんなら、きっと使っている言語の進化を実感していることでしょう。
そんな言語の進化は、今もどこかで誰かが、何らかのインスピレーションを受けて行っています。
そこで、今回は理想の言語とは何かを考えてみたいと思います。
(今回は私が理想とする条件なので、人によって変わってくると思います)
理想の言語の条件
挙動
- コンパイルが速い
- 動作が速い
- 起動が速い
- メモリ使用率が小さい
この2つは基本的な言語の性質ですね。全てを満たすことは難しいですが、改善する努力が必要でしょう。
例えば、Javaは動作は速いですが起動は遅く、起動を高速化する努力が一層必要です。
言語仕様
- 標準的な構文を用いている (ECMAScript 4〜6 を参考に)
- 学習コストが低い
- 変数定義が型宣言で始まらない (var foo:Foo = ...)
- 関数名が短い (Objective-Cは最悪)
- セミコロンが不要 (Pythonなど)
- 必ずしもクラス定義が必要でない (スクリプト言語として使いやすい)
- eval が存在することが望ましい (メタプログラミングの可能性)
- 低レイヤーへのアクセスが言語と独立している (JNIなど)
- 基本構文が少なく、ほとんどが高階関数で定義されている (Scalaなど)
- 静的型付け言語であれば、型推論ができる。(OCamlなど)
- 関数は全て第一級関数である (Scalaなど)
- 値は全てオブジェクトである (Rubyなど)
- シンボル(キーワード)が存在する (Rubyなど)
- デフォルトのモデレータはPublic (Scalaなど)
- 無名関数のシンタックスシュガーがある (
(x) -> x*x
) - ほとんどの構文が式であり、値を返す (Rubyなど)
- 最後の式を返り値とする (Rubyなど)
- インラインドキュメントが書ける (JavaDocなど)
- アノテーションが書ける (Javaなど)
- コンストラクタは
def initialize(...)
とする (Rubyなど) - シンタックスシュガーを複数用意する (Rubyなど)
- 暗黙の宣言による副作用は極力避ける (Scalaは最悪)
- 演算子のオーバーロードを制限付きで許容する (Rubyなど)
これらの性質は、可読性に優れ、スケーラブルであることが既に示されています。
また、高階関数を活用することで、より完結で学習コストの低い言語仕様が策定できます。
仮想マシン (VM)
- VMを再発明しない
- VMの起動が速い
- VMのメモリ使用が少ない
- GCのオーバーヘッドが小さい
- VMに限らないが、末尾再帰最適化をサポートする
VMは難しいところですが、JVMやNekoVM、LLVMのように、VMとして独立したものを利用することが、開発コストを下げ、VMの性能を向上させることに繋がると思います。
ライブラリ
- importができ、別名を付けることができる (Scalaなど)
- 部分importができる (Scalaなど)
- 標準ライブラリが充実している (Pythonなど)
- gemのようなバージョン管理システムがある (Rubyなど)
使用例(Examples)
Hello World
println "hello world"
条件付きで、括弧の省略を認める。
Fib
def fib(n: Int): Int {
if(n < 2){
n
}else{
fib(n-2) + fib(n-1)
}
}
if式は値を返し、最後の式が返り値となる。
クラス
class Say<T> {
var form: String
def initialize(format: String){
this.form = format
}
// 演算子のオーバーロード
def [](val: T){
println String.format(form, val);
}
}
var say = new Say<String>("hello, %s"); // 型推論
say["world"]; // hello, world
Map
def double(list: List<Int>): List<Int> {
list.map(n -> n*2) // 型推論
}
p double([1,2,3]) // [2,4,6]
Filter
def odds(list: List<Int>): List<Int> {
list.filter(n -> n.odd?) // 型推論
}
p odds([1,2,3,4,5]) // [1,3,5]
Inject
def sum(list: List<Int>): Int {
list.inject(:+)
}
p sum([1,2,3,4,5]) // 15
Fold Left
def join(list: List<String>): String {
list.foldL(_ + _) // シンタックスシュガー
}
p join(["hello", " ", "world"]) // (("hello" + " ") + "world") => "hello world"
Fold Right
def subRev(list: List<Int>): Int {
list.foldR(_ - _) // シンタックスシュガー
}
p subRev([1,2,3]) // (1 - (2 - 3)) => 2
マップ(辞書)
var ages = ["Tom": 16, "Mary": 21, "Bosh", 34] // 型推論
p ages.keys.filter(key -> ages[key] < 20) // ["Tom"]
マクロ
macro def nil!(expr: Expr){
"#{expr} = nil"
}
var a = "foo"
nil!(a) // コンパイル時に実行
まとめ
今回は理想の言語を自由に考えてみました。
同じことを自分でやってみると、案外楽しいと思いますよ。
ふつうのコンパイラをつくろう 言語処理系をつくりながら学ぶコンパイルと実行環境の仕組み
posted with amazlet at 14.09.23
青木 峰郎
ソフトバンククリエイティブ
売り上げランキング: 246,711
ソフトバンククリエイティブ
売り上げランキング: 246,711