Nemerle

Nemerleで n == 1 && n == 2 && n == 3をtrueにする

なんか流行っているらしい ので、自分の好きなNemerleで解いてみました(Klassicを一時的に改造しようかと思いましたが、さすがに時間の浪費なのでやめました)。

Nemerleは、知っている人は知っていますが、なんでもかんでもマクロで定義できる言語で、標準定義のオペレーターも実は単なるマクロ定義だったりして、そのマクロ定義を、別のマクロ定義で上書き(隠蔽)することができます。

というわけで、まずは == マクロを定義します。

using Nemerle.Compiler;
macro @==(lhs, rhs) {
  <[
    true
  ]>
}

先頭に @ がついたシンボルをマクロとして定義すると、二項演算子のマクロ定義になるようです。

これを、まずはコンパイルします。

$ ncc -r Nemerle.Compiler.dll -t:dll eq_macro.n -o eq_macro.dll

eq_macro.dll が生成されるので、これを使って、以下のコードを書きます。

using System;

class Hello
{
  static Main () : void
  {
    def a = 1;
    Console.WriteLine(a == 1 && a == 2 && a == 3);
  }
}

あとは、生成されたdllをリンクして、コンパイルして実行するだけです。

ncc -r eq_macro.dll Hello.n -o Hello.exe
Hello.n:7:9:7:10: warning: N168: a local value a was never used (defined in 'Main() : void')
Hello.n:7:9:7:10: hint: replace name with `_' or prefix it like `_bar' to avoid the warning
$ ./Hello.exe
True

何もトリッキーなことをせずに書き換えができました。この辺、さすがにマクロに強いNemerleの面目躍如といったところでしょうか。

ちなみに、この警告がなんででるかというと、aを定義したのに使っていないからで、 == マクロはtrue に単純に展開されるので、 a の利用側が消えてしまうからです。だから、実は、 def a = 1 すら書かずとも、このコードは受理されます(はず)。