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)

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]);
 "using System;".Run();
 "using System.Linq;".Run();
 "using TestPerson;".Run();
 var whereexpression = (Func<Person,bool>)"new Func<Person,bool>( (p) => p.Age < 60);".Compile();
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

[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 = [Mono.CSharp.Evaluator]::Evaluate("from x in new [] {100,200} select x;")

Get every new post delivered to your Inbox.

%d bloggers like this: