Issues with Windows PowerShell syntax

Issues with Windows PowerShell syntax

  • Comments 21

REI recently posted some comments/requests about Windows PowerShell syntax at:

http://blogs.msdn.com/powershell/archive/2006/04/25/583273.aspx#675133

Let's go through a few of the points.

...the syntax was just way too cryptic and unintuitive. Often it's even dangerous. Like this:

#PowerShell's syntax causes dangerous problems generating incorrect results and no error for seemingly innocent expressions:
function Pow($var, $exp) { [Math]::Pow($var, $exp) }
Pow(2, 8) + 3 #invalid (you'd expect it to work)
Pow 2 8 + 3 #valid, BUT INCORRECT RESULT (256)
(Pow 2 8) + 3 #vald (259)
...........
#PowerShell requires you to know whether a function is a cmdlet/script or a .NET method. Even though this method does the exact same thing as the method above, the syntax differs:
[Math]::Pow 2 8 + 3 #invalid
[Math]::Pow(2, 8) + 3 #valid


There are really 2 issues here: parsing modes and function calling syntax.  In order to make Windows PowerShell serve 2 masters: Rich Scripting Engine & Interactive Shell, we made a number of design decisions that you need to be aware of.  We realize that whenever we have one of these, it is going to require our users to invest their time and energy to learn so we treat these issues with incredible respect.  We travail over each of them, demanding to understand whether it is truly necessary or whether we just haven't thought about the problem hard enough.  I'm really proud of the teams dedication to work through these issues and there are a bunch of them that we were able to design away after enough creative thought and hard work.  In the end, we are trying to perform a slightly unnatural act so a couple remain.

With all that as a preamble, let me be quick to note that this issue exists because we are providing a uniform surface to an incredibly wide range of functions.  In the typical shell experience, the user has dozens of these issues as the shell does a limited set of functions and then you have to rely upon separate and sundry utilities and commands to accomplish a task.

The first of those is Parsing Modes:

PSMDTAG:PARSER: The parser has both a COMMAND and an EXPRESSION parsing mode. 

EXPRESSION Mode:
PS> 8 + 3
11

COMMAND Mode:
PS> Write-Output 8 + 3
8
+
3

Parentheses allow you to use expressions in a statement that looks like it would be evaluated in COMMAND Mode:

PS> Write-Output (8 + 3)
11

Bruce Payette, the Language dev-lead, is writing a great book Windows PowerShell in Action (http://manning.com/payette/ ) which goes into this topic in great detail regarding both how it works and why we do this.  Sadly, you'll have to wait this this fall to purchase it.

 

The second issue is function call syntax.  A number of people have been tripped up by this because a number of environments call functions putting the arguments within parentheses.  e.g. FOO(2,8)

PSMDTAG:PHILOSOPHY: Command abstractions are the greatest good.

PSMDTAG:PHILOSOPHY: The world already has lots of great tools for PROGRAMMERS, Windows PowerShell is focused on USERs.

While we provide access to a wide range of functions, our core belief is that commands represent the greatest good.  The essense of a COMMAND is the fact that someone took time to think about the best way to surface a function to a USER (vs a programmer).  The industry already has lots of great ways to surface functions to programmers, our mission is to address the great unmet need of users.

As such, we view functions as just another implementation choice for writing COMMANDS (not methods).  This is why we surface them using COMMAND syntax.  That said, we've brainstormed the idea of allowing either syntax because a number of people have stumbled on this point.   I believe that one of the reasons why this comes up is that we have stopped short on making functions be true equivalents to Commands (something we all dislike but "to ship is to choose").  I'm inclined to address this ASAP and use better documentation to get people over this point.

PSMDTAG:PHILOSOPHY:  No matter what, there will always be some number of key concepts that you have to learn to be productive in a new environment.  You want to keep that number as small as possible but if it is zero, there is a good chance that you've produced something worthwhile.

 

 

REI continues:

#Certain universally recognized aliases for common tasks don't exist:
ls #aliased
dir #aliased
new #not aliased (new-object)

#Calling a default constructor requires its own special syntax:
new-object collections.arraylist(5) #valid
new-object collections.arraylist() #invalid
new-object collections.arraylist #valid

Great point.  Here is what is going on.  We decided against provide an alias for NEW because we decided to make NEW a language keyword in a future version.  Thus in the future, you'll be able to do either:

New-Object Collections.ArrayList 5

or

new Collections.ArrayList(5)

 

REI continues:

Also, the no plurals thing: it doesn't work. The convention in .NET is to signify collections as plurals, and PowerShell's no-plurals policy is a real lump in the pudding. get-member would make a lot more sense if it were called get-members.

The problem is that plurals are an inconsistent syntax in English.  Sure, we can all agree that Get-Members makes more sense than Get-Member but then how is someone from Korea  suppose to guess that it should be Get-ChildREN vs get-ChildS ?  Predictability is critical for a command line environment (there is a theory of operations involved here that I should take time to document but this is a core pillar of Windows PowerShell).  The other reason why we stick with the singular tense is that it is often unknown whether a command provides a value or a set of values.

Get-Process Notepad

Returns a singleton if there is only one notepad running and a set of values if there are more than one notepads running. 

 

Yeah, I know, this isn't the right place to be rambling about this....

Nope - there you are absolutely wrong.   We love people telling us what they don't like.  10,000 thanks for taking the time to articulate the things that you didn't like/found confusing.  These really help us understand where our issues are and it forces us to be crisp about our thinking.  e.g. is this something we are hard-core about and need to do a better job of documenting or is it something we are open to changing and if so, what can we do to improve things.

I encourage other people to chime in with the things that they've found confusing. 

Jeffrey Snover [MSFT]
Windows PowerShell/Aspen Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Leave a Comment
  • Please add 3 and 5 and type the answer here:
  • Post
  • Hi James;

    We are aware of some pretty big usability issues with special characters in the current release.  We've spent a lot of time improving PowerShell in this area since then, which you should see in the next drop.

    Lee
  • Having suffered from the same problems as James, it's good to hear that you're working on it. I just want to say that so far PowerShell is really great and thank you so much for listening to user concerns and responding.
  • > thank you so much for listening to user concerns and responding.

    You guys are the customers.  Talk and we'll listen.  
    We want you to be the happiest campers in the forest.  :-)

    Jeffrey Snover [MSFT]
    Windows PowerShell/Aspen Architect
    Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
    Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx
  • I have a question on how/why you guys chose the syntax for comparision and logical operators.  (I'm quoting the quick reference guide that comes with 1.0.)

    I'd much rather use:

    if a==b {}

    then:

    if a -eq b {}

    And you support ! for not, but not && and || for "and" and "or", respectively?  

    And along the same lines, why did you choose "`" (backquote) to escape characters, rather than the more common "\"?

    I'm a sysadmin, not a programmer, and I don't like having to memorize all these inconsistencies.  (Comparing command shell scripts, vbscript, jscript, etc.)

    Thanks for the great work though, I do appreciate the new features.

  • I ran into this article while looking for a description of PowerShell expression syntax. Where is the expression documentation mentioned (several times) above?

    It would be REALLY nice if it happened to be a complete PowerShell reference (included, for example, a description of begin/process/end statement blocks.

    Thanks

    Mike

  • Hi,

    I have also a problem with powershell :)

    Concerning regular expression, here is my code:    

    $objEntry = [ADSI]''

    foreach ($objOU in $objEntry.psbase.Children)

    {

       if ($objOU.Name -match "^(\w+)$")

       {

           $matches[0]

       }

    }

    I try to get all organizational unit with matching the regular expression.

    In that case, variable $matches is not populated. What's append ? How can i fix the problem ?

    Thx !

Page 2 of 2 (21 items) 12