One concern I've heard from several people is that they are surprised that anything emitted (generally accidentally because they didn't set or pipe to $null) within the function shows up in the pipeline. Although is can be a powerful construct, it can also cause confusion to developers familiar with other language semantics for return
. PowerShell classes does support return
to explicit return objects, but we should consider perhaps adding a property to the CmdletBinding
attribute so that objects not returned
are swallowed and only emitted if explicitly returned
.
I think that will prevent a lot of bugs
One proposal I had was to add something like:
using strict return
At the top of the script. We could also enable lexical scoping in a similar manner.
Makes sense but only if a function with this new attribute does not prevent Windows PowerShell from being able to parse/use such a function.
Being able to enforce the return type and prevent PowerShell from casting the type of returned object would be great as well
I like the idea of adding an option to make this possible. But, I also fear this will result in some really bad code for PowerShell. It will encourage users to ball things up and return them all at once instead of releasing them to the pipeline as created. That is the issue I see more commonly coupled with users who mistakenly think that return
is the only place objects are emitted.
One design consideration would be to include the ability to return multiple objects explicitly to without the flow control aspect of return
. for the sake of demonstration I will use emit
as a keyword for this:
function Get-Stuff {
[CmdletBinding(ExplicitReturn)]
param ()
process {
# Not emitted
Get-ChildItem c:\
# emitted without flow control
emit 1
emit 2
# emitted and flow control sent
return 3
# Not executed
Get-Date
}
}
Get-Stuff
Result:
1
2
3
Breaking change.
@iSazonov How would this be a breaking change? So far everything discussed here is additive. instead of emit
we could change return
to accept a switch return -Continue $value
or something.
Dot-sourcing can be break.
@iSazonov I'm not sure I follow how that would break dot sourcing. Can you elaborate?
using strict return
. .\function.ps1
Seems function.ps1
may not work as expected.
Maybe. The original proposal from @SteveL-MSFT was to add a property to CmdletBinding
.
using
is this context should be lexical - applying only to the file it appears in. If using
affected something dot sourced, that should be considered a bug.
And even if it doesn't, one could say it's not a breaking change - you had to opt-in with new syntax.
Can I ask a dumb question? It seems like the design goal of PowerShell was "output stuff to the pipeline and then stop processing". So why does return $someValue
even exist as valid syntax? It makes it look an AWFUL lot like you are just returning $someValue
. Wouldn't it make more sense to say, if you want to just output anything emitted to the pipeline, say return
. If you want to swallow that and just output a certain value, say return $someValue
? Right now it seems like some weird hybrid where it outputs everything that was emitted previously AND $someValue
. I'd be interested to know the thinking that went into that decision.
return
allows you to return early from a function/scriptblock. It's a way to alter the normal flow of control like break
and continue
do inside a loop.
As a "convenience", return
also allows a value to be output. Essentially return $someValue
is the equivalent of:
$someValue
return
Quite. It's a convenience that saves no bytes at all, and looks misleading.
Most helpful comment
One proposal I had was to add something like:
At the top of the script. We could also enable lexical scoping in a similar manner.