IronScheme を使ってみた
IronScheme をインストールした後、.NET なプロジェクトに IronScheme.dll と IronScheme.Closures.dll を参照設定に追加すれば一通り使えました。
using System; using IronScheme; using IronScheme.Runtime; static void Main(string[] args) { Console.WriteLine("(+ 1 2)".Eval()); // => 3 Console.ReadKey(); }
あっけなく。
次に Scheme 側の手続きを C# で呼び出してみます。
"(define (add-one-func i) (+ i 1))".Eval(); var addOneFunc = "add-one-func".Eval<Callable>(); Console.WriteLine(addOneFunc.Call(0)); // => 1 Console.WriteLine(addOneFunc.Call(5)); // => 6 Console.WriteLine(addOneFunc.Call(10)); // => 11
あっけなく。
最後に C# 側の関数 (Func) を Scheme で呼び出してみます。
int i = 0; Func<int> incrementFunc = () => i++; "(define increment-func {0})".Eval(incrementFunc.ToSchemeProcedure());
が、no expression in body と怒られてしまいます。
IronScheme の Eval() が悪さをしているっぽいのですが (引数で渡したオブジェクトがいったんシンボルになってる)、Scheme レベル 0 なのであんまり深く追っていません。
"(define increment-func '())".Eval(); "(set! increment-func {0})".Eval(incrementFunc.ToSchemeProcedure()); Console.WriteLine("(increment-func)".Eval()); // => 0 Console.WriteLine("(increment-func)".Eval()); // => 1 Console.WriteLine("(increment-func)".Eval()); // => 2 Console.WriteLine("(increment-func)".Eval()); // => 3
とすると、とりあえず動きました。
他にも、
foreach (var val in "'(1 2 3 4 5)".Eval<Cons>()) { Console.WriteLine(val); }
のように、Cons が IEnumerable だったりして面白いです。
IronScheme 自体の初期化が重いのが難点ですが、常駐系のアプリであれば結構使えそうです。