7つの言語、7つの世界を読んでます。(型付け typingについて)

7つの言語 7つの世界

7つの言語 7つの世界

まだ途中ですが、PrologErlang、Ioなどの言語で結構知らなかった概念が出てきていて面白いです。
もちろん読み終わったらここで紹介します。

変数のtypeを判別する際の型付け(typing)というところがわかりにくかったので、調べてしまいました。
今回はその調べた内容をまとめてみます。

分かりにくかったのは、強い型付け/弱い型付けと動的型付け/静的型付けの違いです。

強い型付けと弱い型付けについて

7つの言語、7つの世界では、以下のように書かれています。

強い型付けとは、2つの型に互換性があるかどうかを検出し、互換性がなければ、エラーを投げるか、型の強制変換を行う
という意味だ。表面的には、JavaRubyはどちらも強く型付けされている。
一方、アセンブリ言語やCのコンパイラは、弱く型付けされている。これらのコンパイラは特定のメモリ位置にあるデータが
整数なのか、文字列なのかあるいは単なるデータなのかを必ずしも意識する必要はない。

つまり、下記のような式が与えられた時

var a = 123;
var b = "456";
var c = a + b;


コンパイルエラーになってしまうのが強く型付けされた言語です。
弱く型付けされた言語は上のコードがコンパイルエラーになりません。
弱く型付けされた言語の場合は暗黙的に変換してコンパイルを通してしまいます。

強い型付けがされているとコンパイル時にバグを見つけることが容易になりますが、明示的に型変換をする必要があるので、
プログラミング時の負担が大きくなります。弱い型付けの場合はこの逆で、プログラミング時は楽ですが、コンパイルでバグを
見つけるのが難しくなります。

これの良いところ取りをしているのが最近の言語の主流です。
例えばJavaRubyは強く型付けされた言語のはずですが、
推論による型変換を行なって上記のコードをエラーにしない言語仕様になっています。

動的型付けと静的型付けについて

7つの言語、7つの世界では、下記のように書かれています。

静的に型付けされた言語では、型の構造体に基づいてポリモーフィズムが行われる。
つまり、遺伝子的な青写真によってアヒルかどうかを判定するのが静的型付け。
鳴き声や歩き方によってアヒルかどうかを判定するのが動的型付けだ。

コードをコンパイルしたときに全ての型が決まっているのが静的型付けで、
決まらないのが動的型付けかと思っていましたが、この条件だけでは無いようです。

上の話を読むと、

■静的型付け

interface Bird {
  String speak();
}

class Duck implements Bird {
  String speak() {
     return "gaga";
  }
}

class Main {
  static void execute(Bird bird) {
     bird.speak();
  }

  static void main(String[] arg) {
     Bird bird = new Duck();
     execute(bird);
     // => "gaga"
  }
}

上は静的型付けの例です。Birdをimplementしている時点で
birdの型と振る舞いが決まっている点に注目してください。

■動的型付け

class Duck {
  String speak() {
     return "gaga";
  }
}

class Goose {
  String speak() {
     return "ga-ga-";
  }
}


class Main {
  static void execute(bird) {
     bird.speak();
  }
  static void main(String[] arg) {
     Duck duck = new Duck();
     execute(duck);
     // => gaga
     Goose goose = new Goose();
     execute(goose);
     // => ga-ga-
  }
}

と上記のように型にかかわらず、振る舞いだけで実行時に型が決まって実行できるのが
動的型付けです。

これも同様にコンパイル時のエラー検出やプログラマの生産性などの議論があるようです。

参考文献:
静的型付と動的型付 - Devneko.net
動的型付け - Wikipedia
静的型付け - Wikipedia