Design Patterns in Dynamic Languages–PowerShell

by Doug Finke on November 9, 2011

in Design Patterns,Dynamic Languages,Groovy,Neal Ford,Peter Norvig,PowerShell,Python,Ruby

I was Googling for the Strategy Pattern and implementations done in dynamic languages and came across Neal Ford’s slides where he implements it in Groovy. Here are Peter Norvig’s slides, Design Patterns in Dynamic Languages, in it he states that 16 of the 23 GoF patterns have qualitatively simpler implementations in dynamic languages. Mr. Norvig is Director of Research at Google.

One of Neal Ford’s slides captures the idea.

image

The Strategy Pattern

Formally speaking, the strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

function ql {$args}            
            
function CalcByMult {            
    param($n,$m)             
            
    $n*$m            
}            
            
function CalcByManyAdds {            
    param($n,$m)            
                
    1..$n | % {$result = 0} { $result += $m } {$result}            
}            
            
            
$sampleData = @(            
    ,(3,4,12)            
    ,(5,-5,-25)            
)            
             
$strategies = ql CalcByMult CalcByManyAdds            
             
foreach($Dataset in $sampleData) {            
    foreach($strategy in $strategies) {            
        $Dataset[2] -eq (& $strategy $Dataset[0] $Dataset[1])            
    }            
}

Why Bother with Extra Structure?

Here I am creating an array of PowerShell script blocks for the strategies, eliminating the ceremony of naming them.

$sampleData = @(            
    ,(3,4,12)            
    ,(5,-5,-25)            
)            
             
$strategies =             
{param($n,$m) $n*$m},            
{            
    param($n,$m)            
    1..$n | % {$result = 0} { $result += $m } {$result}            
}            
             
foreach($Dataset in $sampleData) {            
    foreach($strategy in $strategies) {            
        $Dataset[2] -eq (& $strategy $Dataset[0] $Dataset[1])            
    }            
}

{ 1 trackback }

Using PowerShell v3 to consume StackOverflow JSON API
02.08.12 at 7:40 pm

{ 6 comments… read them below or add one }

Josh Einstein 11.10.11 at 3:33 pm

Very good info. I think the dynamic nature of PowerShell makes it a great candidate for using design patterns to implement “pluggable” functionality. The seamless use of scriptblocks is by far the most elegant of any language I’ve seen that uses them. (For example, just try comparing PowerShell scriptblocks to Objective C blocks and let me know when you’re done throwing up.)

One small critique though. In these kinds of posts it might make sense to avoid shorthand and personal conventions. I consider myself to be pretty knowledgable in PowerShell but I found myself scratching my head over the use of ql only to realize “Oh it has nothing to do with the post at all, it’s just the way he creates arrays…”

Doug Finke 11.10.11 at 5:38 pm

Thanks for the comments Josh. I will add a note about ql. It was suppose to make it into the language in V2. I think it is a Pythonism.

Archen 12.02.11 at 1:42 am

$strategies = ql CalcByMult CalcByManyAdds

I like to know what is the meaning of “ql” operator

Doug Finke 12.02.11 at 1:26 pm

Thanks for the comment Archen.

I define ql earlier in the script:

function ql {$args}

ql is Quick List

so:

ql a b c d | foreach {$_}

is the same as:

"a","b","c","d" | foreach {$_}

By using ql I:

  • Reduce the ceremony of quotes and comments
  • Reduce noise
  • Will Steele 04.02.12 at 11:32 am
    Doug Finke 04.02.12 at 7:21 pm

    That is correct Will! And it came from Perl.

    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>

    You are forbidden!