Posts Tagged ‘Mono’
Using C# Compiler as a Service in F#, PoshConsole (Powershell)
I saw this amazing video from Anders Hejlsberg on C# as Compiler service and after which, Miguel de lcaza from the Mono posted about their implementation of C# Compiler service. Thanks Miguel .The best part is ,it works out of the box in Windows on the Microsoft .NET code base. So here I am using Mono’s C# compiler code (Mono.CSharp.dll) within Microsoft .NET Code
This is cool because we could use C# more like python. And what if VS.NET can be customized using C# based scripting ,like Lisp for Emacs.
I figured out from Miguel’s post the only class we should be consuming is Evaluator. And here is a simple extension method for string class to compile and run.
static class Extensions
{
public static object Compile(this string code)
{
return Evaluator.Evaluate(code);
}
public static void Run(this string code)
{
Evaluator.Run(code);
}
}
And here is a code that uses the above extension, which creates a Func dynamically and passes it back to static code.
static void Main()
{
var people = new List<Person>() { { new Person() { Name = "Bush", Age = 63, Sex = 'M' } },
{ new Person() { Name = "Obama", Age = 53, Sex = 'M' } }, { new Person() { Name = "Gordon", Age = 57, Sex = 'F' } } };
Evaluator.Init(new string[0]);
Evaluator.ReferenceAssembly(typeof(Person).Assembly);
"using System;".Run();
"using System.Linq;".Run();
"using TestPerson;".Run();
var whereexpression = (Func<Person,bool>)"new Func<Person,bool>( (p) => p.Age < 60);".Compile();
people.Where(whereexpression).Dump();
}
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public char Sex { get; set; }
}
Here is a code that uses C# within F#
open System
open System.Collections.Generic
open Microsoft.FSharp.Core
open Mono.CSharp
Evaluator.Run("using System;") |> ignore
Evaluator.Run("using System.Linq;") |> ignore
let eval code = Evaluator.Evaluate code
let list = ["FSharp";"CSharp"]
let code = eval "new Func<string,bool>( (s) => s == \"CSharp\") ;" : ?> Func<string,bool>
printfn "Does list contain Foo? %b" (code.Invoke("Foo"))
printfn "Does list contain CSharp? %b" (List.exists (FuncConvertExtensions.ToFSharpFunc (code)) list)
let seqCast : seq<char> = Seq.cast (eval("from x in \"Bar\" select x;") : ?> IEnumerable<char>)
printfn "Sequence result: %b" (Seq.exists(fun x -> x = 'c') seqCast)
I know there is F# powerpack for Linq. One of the reasons we would probably extend this is, if an application is developed in F# (targeted at Devs) and it could possibly allow extensions in C#. Here is an example ,Seesmic has platform for building extension and how would it be If I could write a “ Func<Tweet,bool>( tweet => tweet.Language == “English” && tweet.HasLink == true)” in the search box and if the platform happened to developed in F# (which is not) it would allow the C# devs to extend it .
Another interesting use is using C# compiler service within PoshConsole . In Powershell we could use Add-Type for creating types on the fly but with is I wouldn’t have to create a class and method we could get away with just creating lambdas. Here is an example of the usage
[Reflection.Assembly]::LoadFile("D:\tools\Mono.CSharp.dll")
[Mono.CSharp.Evaluator]::Run("using System;")
[Mono.CSharp.Evaluator]::Run("using System.Linq;")
$func = [Mono.CSharp.Evaluator]::Evaluate("new Func<int,bool>( (s) => s == 10);")
$func.Invoke(100)
$func = [Mono.CSharp.Evaluator]::Evaluate("from x in new [] {100,200} select x;")
$func