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.
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
“@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()
Most helpful comment
If you want a bit more verboseness what is wrong with just using the existing
if
statementif ($x) {$y} else {$z}
? I honestly don't see much advantage of adding-then / -else
operators. It saves two chars:And only one char if your code style is: