Reserving keywords

Reserving keywords

  • Comments 35

A couple months ago we asked our MVPs how they felt about reserving keywords in V2.  We received some excellent but mixed feedback, so we’d like to open the discussion up a bit wider.

There are keywords we hope to use in a future version of PowerShell, but won’t be implemented in V2.  “class”, “using”, and “new” are excellent candidates for additions to PowerShell, but we haven’t decided on the exact list yet.

Because V1 did not reserve these keywords, reserving them now would be a breaking change.  For example, some people like to add an alias like:

New-Alias -Name new -Value New-Object

If we reserved “new”, scripts using this alias would be broken.  Similarly, in Bruce Payette’s book “Windows PowerShell In Action”, he describes a way to implement a keyword like “class”, though he uses “CustomClass” instead of “class”

The biggest benefit of reserving in V2 is that we’ll break fewer scripts.

The cons to reserving in V2 include:

  • Breaking scripts needlessly.  We’ve tried to make V2 as backwards compatible as possible.  The breaking changes that we do have implement real functionality (for example, try/catch are new keywords, breaking scripts that used try or catch as a function.)
  • Some keywords can be implemented in script, at least well enough to look like a real keyword.

Here’s an example of how you might implement the C# using statement in a V2 PowerShell script:

function using             
{             
    param($obj, [scriptblock]$sb)             
            
    try {             
        & $sb             
    } finally {             
        if ($obj -is [IDisposable]) {             
            $obj.Dispose()             
        }             
    }             
}            

And here is how you can use that function – it looks very similar to how a using keyword might look:

using ($stream = new-object System.IO.StreamReader $PSHOME\types.ps1xml) {             
    foreach ($_ in 1..5) { $stream.ReadLine() }             
}

Feel free to give us your feedback in the comments – are you using any common language keywords as a function name in your scripts?  If you do, how bothersome would it be if you had to change your scripts?

- Jason Shirk [MSFT]

Leave a Comment
  • Please add 1 and 1 and type the answer here:
  • Post
  • I'm in favor of the reserving keyword idea. The words tend to be general enough and usually my function names are more descriptive. If a keyword reservation ever broke some of my scripts, good 'ole search and replace works fine or I'd simply write a script to mass update the effected words.

  • With a dev hat on, I am all for reserving keywords.

    My aliases or functions are named, created and behave as in C#.

    But concerning IT professionals, I am not sure how they would react.

  • Think about the stuff you didn't reserve in v1 and regret now. Just do it. V3 will have v1+v2 users in the contentious list. v2 will just have v1 - and how many v1'ers are writing functions like "using," "new" or "class?" Not half as many as will be in v2 if you don't.

    "{0:c}" -f 0.02

    - Oisin

  • Rather than reserve the keywords, could you just define them as functions or aliases that could be overridden by the user, like help and mkdir in V1? This would prevent breaking changes in existing scripts but allow new functionality to be introduced. It would also be helpful if the functionality were available by a non-keyword name (PowerShell_Using?) to support extension of built-in capabilities.

    As an example, I have defined my own 'using' function [1] that serves both as an IDisposable wrapper and as an assembly loader. If the language were to claim the using keyword, every assembly-referencing script I have (many, as a SharePoint dev) would break. I would much prefer to just redefine my function as an extension of however you implement it in the future.

    Cheers ~

    Keith

    [1] http://solutionizing.net/2008/09/21/multi-purpose-powershell-using-function/

  • I haven't checked lately - would the using function in the post work for explicit implementations of IDisposable?  This was a problem in V1, not sure if it's still one in V2 or not.

    If it does work, then I'm ok with the function.  If it (still) doesn't, then please add a using keyword so I can have this functionality even with explicit implementations.

    Of course, then the other question becomes - if this "using" function is going to be so common (and it's likely to become so), how are you expecting the powershell ecosystem to deal with this?  Everyone defines their own copy of it, potentially with conflicting behavior (they all *should* do the same thing, which means they won't).  It seems useless to avoid one keyword and cause this kind of hassle to the community/ecosystem at large.

    I get it's a slippery slope, though.  But c'mon, if Anders feels using, even though it's just syntax sugar, is worth a keyword in C# (and one ver later, VB.NET), can't we have a little MSFT consistency and do the same in posh?  please? :)

  • My mom used to call that borrowing trouble from tomorrow.

    It seems like a bad idea to introduce breaking changes (in a release that might otherwise not break existing scripts), "just in case" you might break them in the future.

    If you don't end up implementing them, you'll have broken things for no reason!

    But even if you do implement them later, that future release will probably break even more things -- reserving those keywords doesn't in any way guarantee that you WON'T break all those same scripts next time anyway.

  • Pros and cons to each side.  Any reason we can't have both?  Maybe something akin to a $*preference variable:

    > $reservedKeywordPreference = Stop;

    > new-alias -name new -value new-object

    KEYWORD FAIL: 'new' is a reserved word

    > $reservedKeywordPreference = Continue;

    > new-alias -name new -value new-object

    WARN: use of reserved word 'new'

    >$reservedKeywordPreference = SilentlyContinue;

    >new-alias -name new -value new-object

    ...

    I would want it to default to Stop, but if I needed to I could easily change it in my profile or at the stop of a broken script.

  • Go for the reserve, but don't make it a breaking change. Write-Warning it or something if there are conflicts. Since they're reserved but not being used, it shouldn't affect v2 functionality, but it informs users that this behavior is likely to change. I'm thinking of how the <Obsolete> attribute in the framework can result in both warnings as well as errors at compilation time.

  • I think you should get the keywords defined as soon as possible. Every (computer) language needs its tokens and keywords. If you will need known ones in the future, implement them now to avoid implementing them in an inevitably more complex future. That will save us from a harder retrofit later.

  • Only generate an error for use of a reserved keyword when Set-Strictmode 2 in effect.  

  • I came here to offer David's exact suggestion.  The analogy to [ObsoleteAttribute] is perfect.

    Reserve the keywords now at the language level.  That is to say, nobody can "turn off" the reservation (as Keith's aliases could be, or beefarino's metavariable explicitly provides for) short of writing their own interpreter.  But don't feel compelled to completely halt people in their tracks.  Just make it painful :)

  • If these keywords are likely to be used in V3, V4 or what ever there is going to be a breaking change at some time. So your choice is to annoy a smaller number of people earlier, or a large number of people later.

    The small number of people you annoy now will be more annoyed because the change isn't absolutely necessary yet. But given the exponential rate at which PS uptake is growing there will be many more people upset when the change comes. And now that you've blogged it they can see you thought about steps to stop them falling into a hole.

    So the right thing to do is to reserve the keywords you think will be used at the earliest possible stage.

  • Hi Jason,

    got somehow similar question. Consider example where I am manipulating with Citrix - and I would like to have function to create new object.

    Logically it should be New-Object, however that is already taken by powershell itself ;)

    Instead I am using functions with function "scope" - above example means that function name will be Citrix:New-Object.

    See my blog post here: http://martinzugec.blogspot.com/2009/03/smart-function-names-in-powershell.html

    Can you see any problem regarding PowerShell plans with this approach??

    Thanks,

    Martin

  • I say introduce the keywords now and save a lot of headache down the road. Break some scripts now or a lot later on? I say "some now".

    Andy

  • I say do it.  As an "IT professional", I haven't found the need (yet) to implement custom functions in my scripts that would use potential reserved words.  Most of my scripts utilize WMI to gather data and format cmdlets to, well, format the output.

    If anything, you could implement the same functionality that SQL Server has, where enclosing the reserved word in brackets will allow me to use it in a custom function instead of a reserved word.  Thoughts?

Page 1 of 3 (35 items) 123