++C++; // 未確認飛行 C ブログ

http://ufcpp.net/

Singleton

leave a comment »

こないだ見かけた話題。

singletonといえば?

SingletonList

Roslynのコード中に、こんなメソッドがあるみたいです。

/// <summary>
/// Creates a singleton list of syntax nodes.
/// </summary>
/// <typeparam name=”TNode“>The specific type of the element nodes.</typeparam>
/// <param name=”node“>The single element node.</param>
/// <returns></returns>
public static SyntaxList<TNode> SingletonList<TNode>(TNode node) where TNode : SyntaxNode
{
return new SyntaxList<TNode>(node);
}

場所はここ。

http://roslyn.codeplex.com/SourceControl/latest#Src/Compilers/CSharp/Source/Syntax/SyntaxFactory.cs

Singletonパターン

プログラミングの分野では、singletonっていうと、プログラム稼働中にただ1つしかインスタンスがないもののことを指す場合が多いわけですが。singletonパターン(その、インスタンスの唯一性を保証するためのパターン)が有名なので。

ところが、上記のコードは見ての通り、メソッドを呼び出すたびに新しいインスタンスを作って返していると。それで、「どうしてsingletonじゃないのに名前にsingletonって入ってるの?私のsingletonの理解が間違ってる?」みたいな話が。

集合論のsingleton

まあそりゃ、そのsingletonじゃないから。

上記コードのsingletonは、集合論で使われる数学用語。日本語訳だと単集合になってるみたい。ただ1つの元からなる集合。

数学って、極力少ないルール(公理、証明不可能な最低限の決め事)を使ってより多くの結果を導けることが、理論の「よさ」の1つの指標になります。特に集合論は現代数学の基礎中の基礎なので、ものすごいシンプルなルールしか持っていません。例えば以下のような。

  1. 集合xとyの対 {x, y} を作れる
  2. 含まれる要素が全て等しいとき、2つの集合が等しいと判定する
  3. 自分自身を含む集合は認めない

ここで、1番目のルールから、同じ集合、xとxの対 {x, x} も作れます。ところが、2のルールを見ての通り、集合は含まれている要素の有無だけを見て等価判定するので、要素の重複を区別できません。結果的に、{x, x} と {x} は同じ集合ということになります。

で、x から {x} という集合を作れたわけですが、3のルールから、{x}、つまり、「xだけを含む集合」はxではないということになります。この、xから作った、xを1つだけ含む集合がsingletonになります。

上記コードはどう見てもsingleton(nodeを1つだけ含むSyntaxNodeを作った)なわけです。

+1

少々余談になりますが、この意味(集合論上の)singletonの利用場面を1つ。

集合論では、少ないルールから出発してる手前、ちょっとした操作をするのにも一工夫必要になったりします(動機としては逆で、ルールを減らすために工夫してる)。

例えば、自然数の構築。自然数を作るには「ある数よりも1つ大きい数が作れる」みたいなルールが必要になりますが、集合論的には以下のようにして「+1」を作ります。

  • ある集合xと、そのsingleton {x}の和集合x∪{x}を作る

ちなみにこのためには、先ほどのルールに加えて、以下の2つのルール(公理)も必要。

  1. 要素を持たない集合{} が存在する(空集合)
  2. 2つの集合x, yの両方の元を持つ別の集合 x∪y が作れる(合併集合)

要素を持たない集合(空集合)を0扱いして、以下、

  • 1 = 0∪{0} = {}∪{0} = {0}
  • 2 = 1∪{1} = {0}∪{1} = {0, 1}
  • 3 = 2∪{2} = {0, 1}∪{2} = {0, 1, 2}
  • 4 = 3∪{3} = {0, 1, 2}∪{3} = {0, 1, 2, 3}

みたいな感じで「+1」していきます。

だからといって、singleton?

singletonなことはわかった。でも、その名前どうなの?

「singletonパターンと紛らわしいから」って理由もなくはないんですけども、どちらかというと、汎用性に欠けるから。

なんというか例えば、以下のようなメソッドもあるわけじゃないですか(この例はSystem.Concoleクラスからとってきたもの)。

public static void Write(string format, object arg0);
public static void Write(string format, object arg0, object arg1);
public static void Write(string format, object arg0, object arg1, object arg2);
public static void Write(string format, params object[] arg);

引数が1つだけのもの、2つだけのもの、3つのもの、そして、配列で任意の長さの引数を渡せるもの。これとの類推で行くなら、以下のような名前でもいいわけです。

public static SyntaxList<TNode> List<TNode>(TNode node) where TNode : SyntaxNode
public static SyntaxList<TNode> List<TNode>(TNode node1, TNode node2) where TNode : SyntaxNode
public static SyntaxList<TNode> List<TNode>(TNode node1, TNode node2, TNode node3) where TNode : SyntaxNode
public static SyntaxList<TNode> List<TNode>(IEnumerable<TNode> nodes) where TNode : SyntaxNode

(ちなみに、4 つ目、つまり、IEnumerableを受け取るやつは、実際にListっていうメソッドがSyntaxFactory.cs内にあります。)

1つ目にSingletonListなんて名前を付けてしまったら、2つ、3つとなるたびに、Singleton, Doubleton, Tripleton, … みたいに名前つけるんですかね?みたいなことになってしまいます(もっとも、今回のRoslynのコード上、2つ、3つの場合を使う要件はないんで、別にこれでいいんですけども。名前自体が違う方が、引数を間違える人的ミスは減りますし)。

結果

  • いやいや、どう見てもsingletonだよ
  • singletonなんだけど、singletonって名前はどうなの?

Written by ufcpp

2014年4月13日 @ 01:47

カテゴリー: 未分類

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。