{"id":9851,"date":"2006-08-02T05:08:00","date_gmt":"2006-08-02T05:08:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2006\/08\/02\/joel-on-software-on-the-power-of-a-good-language\/"},"modified":"2019-02-18T13:21:27","modified_gmt":"2019-02-18T20:21:27","slug":"joel-on-software-on-the-power-of-a-good-language","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/joel-on-software-on-the-power-of-a-good-language\/","title":{"rendered":"Joel-On-Software on the power of a good language"},"content":{"rendered":"<p>Joel Spolsky of Joel-On-Software fame, just posted a blog, &#8220;Can Your Programming Language Do This?&#8221; <a href=\"http:\/\/www.joelonsoftware.com\/items\/2006\/08\/01.html\">http:\/\/www.joelonsoftware.com\/items\/2006\/08\/01.html<\/a><\/p>\n<p>In this article, he drives home the point that when it comes to code: Maintainability, Readability, Abstraction == Good!&nbsp; He then points out how languages can help or hinder this and goes on to articulate the things a language should do to help.&nbsp; We couldn&#8217;t agree more.&nbsp; He could have renamed the article, &#8220;Why Windows PowerShell is a Great Language!&#8221;.&nbsp; <\/p>\n<p>Open up Joel&#8217;s blog entry in a separate window and compare the code. You should notice 2 things immediately <\/p>\n<ol>\n<li>Windows PowerShell code looks amazingly like the code Joel said he wanted.&nbsp; There are a couple of <span>syntactic <\/span>differences but not many.<\/li>\n<li>Windows PowerShell is giving you answers!&nbsp; In other words, I did everything using the interactive console.<\/li>\n<\/ol>\n<p>Joel uses the function ALERT to display info so to make it easier to compare, I created an Alias:<\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">Set-Alias Alert Write-Host<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">Alert &#8220;I&#8217;d Lke some Spaghetti!&#8221;<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">I&#8217;d Lke some Spaghetti!<br \/>PS&gt; <font color=\"#0000ff\"><strong>Alert &#8220;I&#8217;d Lke some Chocolate Moose!&#8221;<\/strong><\/font><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">I&#8217;d Lke some Chocolate Moose!<br \/><\/font><\/span><\/p>\n<p><font face=\"Courier New\" size=\"1\"><\/font>&nbsp;<\/p>\n<p>Noone likes repeated code so he created a function:<\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">function SwedishChef ($food)<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; {<span>&nbsp;&nbsp; <\/span>Alert &#8220;I&#8217;d like some $food !&#8221;<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; }<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; <\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">SwedishChef Spaghetti<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">I&#8217;d like some Spaghetti !<br \/>PS&gt; <strong><font color=\"#0000ff\">SwedishChef &#8220;Chocolate Moose&#8221;<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">I&#8217;d like some Chocolate Moose !<br \/><\/font><\/span><\/p>\n<p>&nbsp;<\/p>\n<p>Joel then makes the point that being able to pass functions as parameters increases the chances that you&#8217;ll be able to find common code:<\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">Function PutInPot($Ingredient) {Alert &#8220;POT: $Ingredient added&#8221;}<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">Function BoomBoom($Ingredient) {Alert &#8220;BOOM: $Ingredient&#8221;}<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">Function Cook ($i1, $i2, $f)<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; {<span>&nbsp; <\/span>Alert &#8220;Get the $i1&#8221;<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>&amp;$f $i1<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>&amp;$f $i2<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; }<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; <\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">Cook Lobster Water PutInPot<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">Get the Lobster<br \/>POT: Lobster added<br \/>POT: Water added<br \/>PS&gt; <font color=\"#0000ff\"><strong>Cook Chicken Coconut BoomBoom<\/strong><\/font><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">Get the Chicken<br \/>BOOM: Chicken<br \/>BOOM: Coconut<br \/><\/font><\/span><\/p>\n<p>&nbsp;<\/p>\n<p>He then points out that the problem with this is that you have to have the functions defined a priori.&nbsp; Wouldn&#8217;t it be more flexible\/powerful if you could write them inline instead of declaring them elsewhere (anonymous functions)?&nbsp; If you could do that, then it reduces the cost\/burden to reuse code:<\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <font color=\"#0000ff\"><strong>Cook Lobster Water {Param($x) Alert &#8220;Pot $x&#8221;}<\/strong><\/font><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">Get the Lobster<br \/>Pot Lobster<br \/>Pot Water<br \/>PS&gt; <strong><font color=\"#0000ff\">Cook Chicken Coconut {Param($x) Alert &#8220;Boom $x&#8221;}<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">Get the Chicken<br \/>Boom Chicken<br \/>Boom Coconut<br \/><\/font><\/span><\/p>\n<p>&nbsp;<\/p>\n<p>Once you have anonyous functions as arguments, you begin to see the world in a different way.&nbsp; First Joel shows you a traditional approach to doubling all the elements of an array:<\/p>\n<p><span><font size=\"1\"><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">$a = 1,2,3<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\">PS&gt; <strong><font color=\"#0000ff\">for ($i = 0; $i -lt $a.length; $i++) {Alert $a[$i]}<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">2<br \/>4<br \/>6<br \/><\/font><\/span><\/p>\n<p>But now let&#8217;s use write a generic function which takes a function and an array as parameter and then applies that function to each element in the array:<\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">function map ($fn, $a)<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; {<span>&nbsp; <\/span>for ($i = 0; $i -lt $a.length; $i++)<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>{<span>&nbsp; <\/span>$a[$i] = &amp;$fn $a[$i]<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>}<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; }<\/font><\/font><\/strong><\/span><\/p>\n<p>That allows you to now do this:<\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">$a = 1,2,3<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">map {param($x) return $x*2} $a<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">map Alert $a<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">2<br \/>4<br \/>6<br \/><\/font><\/span><\/p>\n<p>&nbsp;<\/p>\n<p>Another example of this is the following 2 functions.&nbsp; Both of these add elements to an initial value.&nbsp; In the first case (SUM), the elements are added as integers.&nbsp; In the second case (JOIN), the elements are added as strings.<\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">function sum ($a)<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; {<span>&nbsp; <\/span>$s = 0<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>for ($i = 0; $i -lt $a.length; $i++) <\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>{<span>&nbsp;&nbsp; <\/span>$s += $a[$i]<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>}<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>return $s<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; }<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\"><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">function join ($a)<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; {<span>&nbsp; <\/span>$s = &#8220;&#8221;<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>for ($i = 0; $i -lt $a.length; $i++)<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>{<span>&nbsp; <\/span>$s += $a[$i]<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>}<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>return $s<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; }<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">&gt;&gt; <\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">alert (sum 1,2,3)<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">6<br \/>PS&gt; <strong><font color=\"#0000ff\">alert (join &#8220;a&#8221;,&#8221;b&#8221;,&#8221;c&#8221;)<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">abc<br \/><\/font><\/span><\/p>\n<p>&nbsp;<\/p>\n<p>Look at the details of these functions and you&#8217;ll see that they are almost identical except for the initial value (0 vs &#8220;&#8221;).&nbsp; So now let&#8217;s refactor these functions to use a common function (REDUCE):<\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">function reduce ($fn, $a, $init)<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; {<span>&nbsp; <\/span>$s=$init<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>for ($i = 0; $i -lt $a.length; $i++)<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>{<span>&nbsp; <\/span>$s = &amp;$fn $s $a[$i]<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>}<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>return $s<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; }<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\"><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">function sum ($a)<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; {<span>&nbsp; <\/span>return reduce {param($a,$b) return $a + $b} $a 0<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; }<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; <\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">function join ($a)<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; {<span>&nbsp; <\/span>return reduce {param($a,$b) return $a + $b} $a &#8220;&#8221;<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; }<\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><strong><font color=\"#0000ff\"><font size=\"1\">&gt;&gt; <\/font><\/font><\/strong><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">PS&gt; <strong><font color=\"#0000ff\">alert (sum 1,2,3)<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">6<br \/>PS&gt; <strong><font color=\"#0000ff\">alert (join &#8220;a&#8221;,&#8221;b&#8221;,&#8221;c&#8221;)<\/font><\/strong><\/font><\/span><\/p>\n<p class=\"MsoPlainText\"><span><font size=\"1\">abc<br \/><\/font><\/span><\/p>\n<p>Joel &#8211; thanks for an the <span>eloquent articulation <\/span>of the value of Windows PowerShell!&nbsp; <\/p>\n<p>Jeffrey Snover [MSFT]<br \/>Windows PowerShell\/Aspen Architect<br \/>Visit the Windows PowerShell Team blog at:&nbsp;&nbsp;&nbsp; <a href=\"http:\/\/blogs.msdn.com\/PowerShell\">http:\/\/blogs.msdn.com\/PowerShell<\/a><br \/>Visit the Windows PowerShell ScriptCenter at:&nbsp; <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx\">http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>PSMDTAG:FAQ: Anonymous Functions &#8211; are they supported? ANSWER: YES<\/p>\n<p>PSMDTAG:LANGUAGE: Anonymous Functions<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Joel Spolsky of Joel-On-Software fame, just posted a blog, &#8220;Can Your Programming Language Do This?&#8221; http:\/\/www.joelonsoftware.com\/items\/2006\/08\/01.html In this article, he drives home the point that when it comes to code: Maintainability, Readability, Abstraction == Good!&nbsp; He then points out how languages can help or hinder this and goes on to articulate the things a language [&hellip;]<\/p>\n","protected":false},"author":600,"featured_media":13641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[10,33],"class_list":["post-9851","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell","tag-faq","tag-language"],"acf":[],"blog_post_summary":"<p>Joel Spolsky of Joel-On-Software fame, just posted a blog, &#8220;Can Your Programming Language Do This?&#8221; http:\/\/www.joelonsoftware.com\/items\/2006\/08\/01.html In this article, he drives home the point that when it comes to code: Maintainability, Readability, Abstraction == Good!&nbsp; He then points out how languages can help or hinder this and goes on to articulate the things a language [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/9851","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/users\/600"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/comments?post=9851"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/9851\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media\/13641"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media?parent=9851"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=9851"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=9851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}