‘Embedding’ F# in PowerShell

by Doug Finke on July 27, 2007

Jeffery Snover, architect of PowerShell, presented a PowerShell script with embedded C# code to invoke a Win32API.

Here is a first attempt at embedding F# in PowerShell. The key difference is the the F# code is written to disk, compiled and the resulting DLL is then loaded into memory. The embedded C# approach uses the System.CodeDom to compile and generate the executable in memory.

program

The F# code, lines 6 through 13, are in a PowerShell here-string (5 and 14). The program is saved to disk (16), the F# compiler invoked (18), the compiled DLL is loaded (22) finally the get method is invoked (24).

results

Notes

The F# get method is generated as static. Calling static members requires the fully qualified namespace, class name, two colons and the member name. [Strangelights.Fibonacci]::get()

If you want to find the static methods/properties of a class, use the Get-Member cmdlet with the switch -Static on the already loaded DLL.

Get-Member

F# compiles to a .Net assembly, so any .Net language can interoperate with it. Conversely, F# can use assemblies generated by other .Net languages.

{ 1 comment… read it below or add one }

Mr. Spock 12.28.09 at 11:25 am

Very interesting !!
I made some modifications to your code to allow it compile F# into memory.

Hope it helps:

#path to FSharp Compiler Provider assembly DLL
$fsharp_codedom = "$env:ProgramFiles (x86)\FSharp-1.9.7.8\bin\FSharp.Compiler.CodeDom.dll";

#load compiler assembly
$codedom_assy=[System.Reflection.Assembly]::LoadFrom($fsharp_codedom);

#instantiate compiler and parameters
$compiler = new-object -type Microsoft.FSharp.Compiler.CodeDom.FSharpCodeProvider;
$compilerParameters = new-object -type System.CodeDom.Compiler.CompilerParameters;

#force assembly to be compiled in memory
$compilerParameters.GenerateInMemory=$true;

# FSharp Source
$source=@"
#light
module Strangelights.Fibonacci
let fibs =
(1,1) |> Seq.unfold
(fun (n0,n1) ->
Some(n0, (n1, n0 + n1)))

let get n =
Seq.nth n fibs

"@

$result = $compiler.CompileAssemblyFromSource($compilerparameters,$source);
if ($result.Errors.HasErrors){ $source;$result.Errors;break}

#calling FSharp functions from powershell
1..40| ForEach { "{0} {1}" -f $_, [Strangelights.Fibonacci]::get($_) }

Leave a Comment

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>