Powershell: Implement -then -else for Ternary operator

Created on 22 Sep 2019  ·  8Comments  ·  Source: PowerShell/PowerShell

Considering the ternary operator was added using the syntax most friendly to c# developers and not general PowerShell users - i.e all your admin users,

I propose that the ternary operator should be further extended to also allow -then -else syntax

My reason for asking is simple - there are still many in the PowerShell community that want & prefer the verboseness of the language over other languages and find that the verboseness provides a much easier readability experience.

PowerShell is known for allowing users to pick syntax options that they are comfortable and giving -then -else syntax would help bring the ternary operator to those users, that don't come from the classical developer type roles.

Issue-Enhancement

Most helpful comment

If you want a bit more verboseness what is wrong with just using the existing if statement if ($x) {$y} else {$z}? I honestly don't see much advantage of adding -then / -else operators. It saves two chars:

$x -then $y -else $z
if ($x) {$y} else {$z}

And only one char if your code style is:

$x -then $y -else $z
if($x) {$y} else {$z}

All 8 comments

Referencing this comment from @lzybkr https://github.com/PowerShell/PowerShell/issues/3239#issuecomment-365072448

The syntax that I believe is most PowerShelly would be $x -then $y -else $z & is the syntax that I am requesting also be implemented to aid in possible adoption of this operator

It's worth mentioning as it kinda feels like it's been forgotten that PowerShell's primary target userbase was always Windows Administrators and NOT C# Developers, whether Windows based or not.

I don't think that it's too much of an ask to implement this before v7 goes GA to appease both camps of users

It was already discussed here but the reaction was quite negative from a few people: https://twitter.com/Steve_MSFT/status/1152013489965109252

Twitter
@CoryKnox @CBergmeister We’re unlikely to do both. Would probably cause confusion”

If you want a bit more verboseness what is wrong with just using the existing if statement if ($x) {$y} else {$z}? I honestly don't see much advantage of adding -then / -else operators. It saves two chars:

$x -then $y -else $z
if ($x) {$y} else {$z}

And only one char if your code style is:

$x -then $y -else $z
if($x) {$y} else {$z}

Character count isn't everything. Typing parentheses and braces is slightly awkward, and honestly it's harder to read if/then/else on one line. Of course the ternary operator can be hard to read too, which is why my proposed syntax doesn't seem universally hated.

That's true, as well. My only concern for using -then/-else syntax for a ternary operator is that it creates an exception in the language rules.

All other operators with -operator syntax are purely binary operators. While they may have multiple arguments on their LHS or RHS, they _only_ have a LHS and RHS argument. None of them have a third argument.

From a newbie's perspective, $a -then $b -else $c looks pretty similar to $a -eq $b -as $c (or any other consecutive sequence of operators; they're not super common, but also not unheard of). This creates a pitfall in terms of the expectation of what an -operator does and how it should work. The ternary syntax is a completely different mode of operation than all existing operators using this syntax.

The expectation we currently have for an -operator is:

$LHS -operator $RHS # creates some definite result that can be further operated on

Extending this to the proposed syntax creates a false assumption:

$a -then $b and $a -else $b are also valid syntaxes, and $a -then $b -else $c is just an extended variant of these.

I'm not saying this is a hard-line "we should under no circumstances do this", but I would think that given the proposal is to create, effectively, a "clearer" version of the ternary syntax, we should probably avoid creating a behaviour that is easily misunderstood based on currently reasonable assumptions about how the language patterns behave.


_That said_, there's a fairly easy solution here: implement -then and -else as separate operators, which can then be combined to create this ternary syntax.

For example:

# if $a is truthy, returns $b, otherwise returns $null
$a -then $b 

# if $a is not null, returns $a, otherwise returns $b
$a -else $b 

# if a is truthy, returns $b; otherwise the first operation is evaluated, 
# leaving us with: $null -else $c, which then returns $c
$a -then $b -else $c 

This has a bonus effect: $a -else $b then becomes an analogue to C#'s a ?? b syntax, and you can utilise -then as another null-coalescing operator: $a -then $a.Property or $a -and $a.Property -then $a.Property.SubProperty

I'm not especially fond of -then/-else as being implemented in precisely the same way as the current ternary operator. I don't like introducing exceptions to established and presently well-defined language rules if we can help it.

TL;DR: I'm in favor of it as long as $a -then $b and $a -else $c don't create parse errors, essentially.

Someone in the PowerShell Discord brought up one potential issue with my above idea:

$true -then $null -else $someValue

If implemented as separate operators... this could be a potential pitfall if it is not handled carefully by the parser. Ternary syntaxes should return $null in that kind of case ($true ? $null : $value will return $null) but if the operators are completely independent it's possible that -else could be mistakenly triggered.

I still think that's the best way to proceed, but we'd need to add a special case somewhere in the logic to also skip an immediately following -else if the -then condition passes, even if the positive result of the -then is in fact $null.

Mind you, I'm not sure that's a _likely_ occurrence, since $a -then $null will _always_ result in null; it's rather a pointless operation. However, it's conceivable that in any given $a -then $b statement, $b could potentially be $null by accident, if not on purpose.

(also, edited the above to clarify the proposed behaviour of -else as I made an error there)

I'm just reading this issue for the first time now.

TL;DR: I'm in favor of it as long as $a -then $b and $a -else $c don't create parse errors, essentially.

Yeah, that's how && and || work in JavaScript. I think that's the most logical way for them to operate. Essentially the same as -and and -or, but returning the value rather than the boolean coercion of that value.

I don't see any particular composition of that as a pitfall, just a regular result of left-associative operator parsing.

I think the value of these operators is in being able to pass out a meaningful result in a truthy situation, but stop an error in a falsey situation:

return $item -then $item.Transform()
Was this page helpful?
0 / 5 - 0 ratings