Wednesday, August 04, 2010

Powershell: Returning ScriptBlocks and Closures

Powershell lets you return scriptblocks (aka anonymous functions) from functions, for example:
function generateAdder ($n)
{
    {
        param ($x)
        $n+$x
    }
}
 
PS C:\> $add4 = generateAdder 4
PS C:\> & $add4 7
7
If you've used languages with closures you'd have expected to get back a function that adds 4 to a passed in value. You'd expect that because $n=4 was in lexical scope when we created the scriptblock to be returned. Recall powershell is dynamically scoped so we don't need to bind ($n) to a lexcial location, instead we can pick up $n from our current environment:
PS C:\> $n = "Hello"
PS C:\> & $add4 7
Hello7
What if you want to instantiate a closure with powershell instead? Luckily someone thought of that and you can do:
function generateAdder2 ($n)
{
    {
        param ($x)
        $n+$x
    }.GetNewClosure()
}
PS C:\> $add4 = generateAdder2 4
PS C:\> & $add4 7
11

Leave a comment if you use these features, I’m curious what you’d use them for.

No comments: