はじめてのLINQ
LINQ Previewをダウンロードして実験君。ただ、日本語版VS2005β2には対応していないようなので、コマンドラインからちまちまコンパイルすることに。
using System; using System.Query; class Program { public static void Main () { var src = new int [] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; var dst = from n in src where n % 2 == 0 orderby n descending select n; foreach (var n in dst) Console.WriteLine (n); } } /* 結果 8 6 4 2 */
さっくり動きますね。なんだか凄そうに見えますが、コイツをC#2.0のコードで書くと、
using System; using System.Query; class Program { public static void Main () { int src = new int { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; OrderedSequence<int> os = Sequence.OrderByDescending<int, int>( Sequence.Where<int>(src, delegate (int n) { return n % 2 == 0; }), delegate (int n) { return n; }); foreach (int n in os) Console.WriteLine (n); } }
意外と単純。イメージ的にはUnixのパイプに近いかな。
$ from n in src | where | orderby | select > dst
↑こんなのを想像してみてください。
そーいや、queryの並びがSQLと異なって(selectが最後に来ている)いますが、これについてヘジたんがビデオでコメントしていたけど、VB9のLINQってSQLの並びなんですよね。この辺は統一取れてないのかしら?(^^;
Lambda expressions
C#3.0のLambdaがシンプルで良い感じなので、Nemerleでも真似出来ないかと色々試すも、私の知識じゃ歯が立たず。あんまマクロ分かってないんですよね。(^^;
で、格闘の跡。
using Nemerle.Compiler; // 引数1つ macro @fx (parm : parameter, body) syntax ("fx", parm, "->", body) { match (parm) { | <[ parameter: $(iname : name) : $ty ]> => <[ fun ($ (iname : name) : $ty) { $body } ]> | _ => Message.FatalError ("excepted a single parameter") } } // 引数2つ macro @fy (parm1 : parameter, parm2 : parameter, body) syntax ("fy", parm1, parm2, "->", body) { match (parm1) { | <[ parameter: $(iname1 : name) : $ty1 ]> => match (parm2) { | <[ parameter: $(iname2 : name) : $ty2]> => <[ fun ($ (iname1 : name) : $ty1, $ (iname2 : name) : $ty2) { $body } ]> | _ => Message.FatalError ("excepted two parameters"); } | _ => Message.FatalError ("excepted two parameters") } }
使い方は、こんな感じ。
def f1 = fx x -> x * 2; def f2 = fy x y -> x + y * 2; def f3 = fy a b -> a * 2 + b; Nemerle.IO.printf("%d\n", f1 (10)); Nemerle.IO.printf("%d\n", f2 (10, 20)); Nemerle.IO.printf("%d\n", f3 (10, 20)); /* 結果 20 50 40 */