思い出したかのように「C# 7思い出話」。

タプルがらみも先週末で一通り書き終わったはずかな。

タプル

これ自体はおおむね当初予定通りですかね。 そんなに裏話的な面白話もなく。 文法的に変化が大きいんで実装は大変そうでしたが。

しいていうと、他の提案を差し置いてタプルの優先度が高かった的な話ですかね。 タプルは、レコード型とか、 C# 7のさらに先で入る予定の機能の基礎に使う可能性があって。 依存順的に先にないと行けないという、割かしシンプルな話。

タプルは、(int x, int y)みたいなメンバー名を持った型から、ValueTupleという完全に名前のないデータ構造を生成する機能なわけで、 型に緩い世界と厳しい世界の橋渡しとして期待されます。ロジックを書く上では厳しい型付けを持っている方が楽ですが、View (WPFやUWPのData Bindingみたいな世界)や、Wire Data (通信層でのデータのシリアライズ・デシリアライズ)とかでは緩い型の方が助かったりします。その間をつなぐ基礎に使えそうって意味で、タプルには期待感があります。

そして、レコード型をタプルをベースに作る、あるいは、レコード型からタプルへの変換を用意すれば、型名がある世界とない世界もつなげます。

レコード型をタプルをベースに作るっていうのは、例えば以下のようなコードを書いたとして(これがレコード型って呼ばれる機能)、

class Point(int X, int Y);

以下のようなコードに展開するという案。

class Point
{
    (int x, int y) Value;
    public int X => Value.x;
    public int Y => Value.y;
}

レコード型からタプルへの変換を用意というのだと、以下のような感じ。

class Point
{
    public (int x, int y) Value => (X, Y);

    public int X { get; }
    public int Y { get; }
}

どちらにしろ、依存関係があるなら、依存されている側の方が先に落ち着いていないといけない。

レコード型は、その前身となる primary constructorっていう機能提案から考えるとC# 6よりも前(一瞬、C# 6に入れる想定で話が進んでた)、2014年半ば頃からあります。それが、「もっと洗練してレコード型にしてから取り入れたい。そのためにはC# 6では無理」となり、「タプルやパターン マッチングと併せて考えたい。そのためにはC# 7よりも後」となり今に至ると。

分解

こちらは逆に、前倒し。 前倒しというか、パターン マッチングがらみの仕様のうち、一部分だけが先行してC# 7に入るわけですが、その一部。

パターン マッチングは結構大きな提案です。All or Nothing、「全部入れるか全部入れない」かとかで入れようとすると、たぶん3年くらい先になります。 こないだ短期リリース サイクル化の話とか書きましたが、後への影響残さないなら、先に少しだけリリースする方が助かります。

元々は、以下のような構文で話が進んでいたんで、それからするとずいぶん、分解専用の構文になりました。多少、そこは、今後、パターン マッチングの全体が入るときに衝突しないのかな?とか思ったりはします(たぶん大丈夫という判断が付いたからC# 7で入ることになったはずですが)。

let パターン = 分解したいもの;