最近 Nemerle がマイブームです
私自身は最近知ったのですが、実は以前からある言語っぽいですね。
C#によく似た構文を数多く持ち、関数型言語によく見られる機能(パターンマッチングとかタプルとか)を言語レベルで実装しているのが特徴です。
型を静的にチェックできる強力なマクロもあって、かなり自由度の高いコードが書けるようです。
foreach
文なんかもマクロで書かれているそうです。
あと#pragma indent
ディレクティブを宣言することでPythonやF#, CoffeeScript, Haml, SASSなどで馴染みのある「インデントが意味を持つ」書き方ができます。
自分はまだそこまで使いこなせてないですが、書いていてすごく楽しいです。
知名度もそれほどなくコミュニティもあまり活発ではないようですが、C#もF#も好きって人には向いているんではないでしょうか。
例えば、以下は拙い知識で書いたフィボナッチ数列を求めるコードです。 gist.github.com
これはC#で書くと大体こんなような感じです。
using static System.Console; using System.Numerics; static class Program { static void Main() { Action<int> fib = null; fib = n => { WriteLine("{0,8} : {1}", n, Fibonacci(n)); if (n % 10 == 0) ReadLine(); fib(n + 1); }; fib(1); } private static BigInteger Fibonacci(int n) { var a = BigInteger.Zero; var b = BigInteger.One; foreach (int i in Enumerable.Range(0, 31).Reverse()) { BigInteger c = a; a = a * (b * 2 - a); b = c * c + b * b; if ((((uint)n >> i) & 1) != 0) { c = a; a = b; b = c + b; } } return a; } }
これだけだと正直何がいいのか伝わらない自覚はあります。
Nemerleらしい箇所はタプルでの多重代入とdef
を使った型推論くらい…。
match (expr)
はdef
の直下やforeach
の直下で省略できるため、
// A(文字コード: 65)からz(同: 122)までの大文字で、かつ偶数番目に出現する文字のみを出力 foreach (c in $['A' .. 'z'] with index) { | x when char.IsUpper(x) && index % 2 == 1 => Write(c) | _ => () } WriteLine(); // 冗長に書くとこう foreach (c in $['A' .. 'z'] with index) { match (c) { | x when char.IsUpper(x) && index % 2 == 1 => Write(c) | _ => () } }
こんな感じでforeach
からのパターンマッチとかやるとちょっとはメリットが見えてくるかもしれません。
分かりやすさのためにあえてc
とx
と変数名を変えましたが、Nemerleはスコープが異なる場合は変数名のオーバーライドが可能なので、
// 上のコードで、4行目をこう書いても意味は同じ | c when char.IsUpper(c) && index % 2 == 1 => Write(c)
です。
こんなコードも書けます。
Main() : void { def n = 10; def somefunc(n) { $[n ** 3, n in [1 .. n]] } def listToString(list) { "[" + string.Join(", ", list) + "]" } def list = somefunc(n); WriteLine(listToString(list)); }
n
が何を指しているのか、コンテキストが分かりづらいのでほどほどにするのがよさげですね。
個人的には自由度が上がったC#の延長、みたいな感じに捉えています。
地味にC# 7.0から対応の2進数リテラル(0b1011
みたいなの)もとっくのとうに実装済みだったり、便利です。