このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

newが嫌いな理由 -- リテラル好き好き

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);
}

はははははっ、これでもいいか。でも、演算子オーバーロードがないとなー、x.add(v2(-1, 5))じゃイヤだ。