読者です 読者をやめる 読者になる 読者になる

The LINQ Project (1)

.NET

今更ながらのネタですが,先日 PDC 2005 で C# 3.0, Visual Basic 9.0 と共に発表された The LINQ Project .NET Language Integrated Query についてのお話です.
LINQ は次世代の .NET 言語に SQL 的なクエリ機構を統合させるという野心的なプロジェクトですが,言語拡張とライブラリ整備の両側面を持つことが「一言で」言えるような簡潔な説明を難しくしているかもしれません.Don Box が書いた上のリンク先の記事はさすがに綺麗にまとまっていますが,未来の「C# 3.0 入門書」や「Visual Basic 9 入門書」を書く人は本当に大変なんじゃないかと思います.
まあ鬼が笑うような話は置いておいて,以下この Linq を自分なりに整理してみました.いかがでしょ?

  1. 標準ライブラリに Standard Query Operators と呼ばれる SQL 風の静的メソッド群を導入する(id:NyaRuRu:20050921#p2).これらのメソッド群は,主に IEnumerable 型のデータソースとデリゲートによる述語を取り,結果を IEnumerable を返す.このあたりで既に TheServerSide.NET の記事*1に出てくる Pipeline Pattern の理解は前提.ライブラリとしての Linq はある意味 Standard Pipeline Library と言える.
  2. Extension Methods で Standard Query Operators を IEnumerable 型のインスタンスメソッドのように記述できるようにする*2C# では using System.Query; とすることでこの記法が可能となる.
  3. これで IEnumerable source; に対しこれらのメソッドを chain させて呼び出すことができるようになった*3
  4. さらに C# 3.0 / Visual Basic 9 では,いくつかのキーワードを導入し,上記メソッド呼び出し chain の省略表記や,複数のソースへのアクセスを簡単に記述できる.

さて,やねうらおさんのところの C# 3.0 紹介記事のコメントより.

# yaneurao 『IEnumerableを実装したユーザー型に対してクエリをかけたりするとインターフェース経由になるから超遅いんじゃないかというのが気になるところでして..
そのへんのコードの最適化がキワキワのところまでされているならば別にいいんですけれど..。(そのリンク先はまだ詳しくは読んでませんので、おかしいこと言ってたらゴメンナサイ)』

個人的な予想では,System.Query 以下の汎用 Standard Query Operators は多くの C++ STL Algorithm のようにな代物にとどまるのではないかと思います.単にアルゴリズムが教科書通り実装されているだけと(追記: C:\Program Files\LINQ Preview\Docs\Sequence.cs に実装がソースコードの形で公開されています).ただし .NET の inlining はまだまだ甘いところがあるので,今のところ速度面ではそこまで期待していません.
なお,ここで言語拡張が絡むのは(2),(3), (4)の部分です.(1)については C++ の stream 抽象のようでもありますし,アルゴリズムライブラリを一通り提供することで Pipeline パターンに一定の標準を持ち込むという意味もあるでしょう*4.今でも作ろうと思えば作れます.

*1:菊池さんが紹介されていた 奴ですね

*2:例えば IEnumerable source; source.Where(Func predicate); は IEnumerable Where(source, predicate); と解釈される

*3:source.Where(s => s.X*s.X+s.Y.s.Y < 1.0).Select(s => new {s.ID, s.Name}).Take(5);など.使い心地としては C++ がストリーム演算子 >> で実現していた Hack に近い気がする.

*4:オレオレ野良 iterator があちこちで沸いてくるのを防いでくれそうなのはありがたいのですが,肝心の C# 2.0 で今すぐは使えないのはどうにかならんのかと