Pythonはほとんど使ったことがないのですけど、「いいなぁ」と思う点はインスタンス生成にnewが不要なこと。クラス名を関数呼び出し形式で使えばいいだけ、x = Person('Tonkichi')
。いいなぁ。
リテラルがなかったら不便
newがイヤなのは、まず単純に「書くのがめんどくさい」という理由があります。別な理由もあります、僕はリテラルが大好きなんだけど、newはリテラルにとって邪魔モノなんです。ここで、リテラルってのは、値やオブジェクトを直接に表現する記法です。たいていの言語で、153
は整数リテラルだし、"Hello"
は文字列リテラルです。
String s = "Hello";
のようなリテラルが使えないと大変ですぜ。次のようにしなきゃならないでしょう。
いや、これも文字リテラル
// これはJava風
char[] s0 = {'H', 'e', 'l', 'l', 'o'};
String s = new String(s0);
'H'
なんかを使っているので、文字オブジェクトを必ず生成するとしたら、こんな感じ:待てよ、
Character H = new Character(72);
Character e = new Character(101);
Character l = new Character(108);
Character o = new Character(111);
Character[] s0 = {H, e, l, l, o};
String s = new String(s0);
72
とか101
も整数リテラルだから、これも使えないとしたら … どうにもなりませんがね。もっとリテラルを
人間と人間のコミュニケーションでは、記号のオーバーロード(文脈による解釈)を盛大に使うので、リテラルはかなり強力な表現力を持ちます。例えば、2次元ベクトル(数値タプルとしてのベクトルね)の話をしている文脈なら、次の式の意味は明らかでしょう。
x = (3, 2)
y = x + (-1, 5)
プログラミング言語ではこれほど気楽には書けない -- そこがイヤッ。
とはいえ、括弧やカンマなどの記号を完全にユーザー定義可能とするのは現実的とは思えないので、そこまでは言いません。コンストラクタにnewがいらなくて、演算子(この場合は+
)オーバーロードが可能なら、次のように書けます。
// 今度はJavaScript風
var x = Vector2D(3, 2);
var y = x + Vector2D(-1, 5);
実際はコンストラクタ呼び出しだけど、リテラルっぽいでしょ。オブジェクトがイミュータブルなら、リテラルの出現はコンストラクタ呼び出しとしてもかまいません(何らかの方法でインターンできれば効率化できる)。
まだナガーイ
Vector2D(3, 2)
はnew Vector2D(3, 2)
よりいいけど、長いですね。クラス名を短くするのは抵抗があるのでダメ。となると、クラス名とコンストラクタ名の一致を破るしかありません。明示的に「この関数がコンストラクタだ」と指定できれば、「クラス名=コンストラクタ名」である必要はありません。
// JavaScript2.0風
class Vector2D {
var x:Number;
var y:Number;
constructor v2(x:Number, y:Number) {
this.x = x;
this.y = y;
}
// ...
}
すると、こう書ける:
var x = v2(3, 2);
var y = x + v2(-1, 5);
とりあえずの策としては:
function v2(x, y) {
return new Vector2D(x, y);
}