You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Allow advanced functions to only return objects to the pipeline explicitly #3669
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.
Reacted by James Baker, Maarten, Christoph Bergmeister, Nick James, jantari and iRon7
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:
functionGet-Stuff {
[CmdletBinding(ExplicitReturn)]
param ()
process {
# Not emittedGet-ChildItem c:\
# emitted without flow control
emit 1
emit 2# emitted and flow control sentreturn3# Not executedGet-Date
}
}
Get-Stuff
Ilya (@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.
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:
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:
I feel like PowerShell could just reuse the C# syntax yield return for explicitly passing an object to the pipeline without exiting the function like a bare return would.
I would still love to see this feature: [CmdletBinding(ExplicitReturn)] on functions and then only pass objects on to the pipeline with yield return or return keywords. As Steve Lee (@SteveL-MSFT) said it's been a long standing source of frustration for new and old PowerShell users, could this be looked at again and evaluated for the roadmap for this year or so?
microsoft-github-policy-service commented on Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
microsoft-github-policy-service commented on Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
Activity
powercode commentedon May 1, 2017
I think that will prevent a lot of bugs
lzybkr commentedon May 1, 2017
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.
bergmeister commentedon May 25, 2018
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
markekraus commentedon May 26, 2018
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
returnis 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 useemitas a keyword for this:Result:
iSazonov commentedon May 26, 2018
Breaking change.
markekraus commentedon May 26, 2018
Ilya (@iSazonov) How would this be a breaking change? So far everything discussed here is additive. instead of
emitwe could changereturnto accept a switchreturn -Continue $valueor something.iSazonov commentedon May 26, 2018
Dot-sourcing can be break.
markekraus commentedon May 26, 2018
Ilya (@iSazonov) I'm not sure I follow how that would break dot sourcing. Can you elaborate?
iSazonov commentedon May 26, 2018
Seems
function.ps1may not work as expected.markekraus commentedon May 26, 2018
Maybe. The original proposal from Steve Lee (@SteveL-MSFT) was to add a property to
CmdletBinding.lzybkr commentedon May 29, 2018
usingis this context should be lexical - applying only to the file it appears in. Ifusingaffected 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.
jez9999 commentedon Jul 4, 2018
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 $someValueeven 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, sayreturn. If you want to swallow that and just output a certain value, sayreturn $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.rkeithhill commentedon Jul 4, 2018
returnallows you to return early from a function/scriptblock. It's a way to alter the normal flow of control likebreakandcontinuedo inside a loop.As a "convenience",
returnalso allows a value to be output. Essentiallyreturn $someValueis the equivalent of:jez9999 commentedon Jul 4, 2018
Quite. It's a convenience that saves no bytes at all, and looks misleading.
jantari commentedon Jan 17, 2022
I feel like PowerShell could just reuse the C# syntax
yield returnfor explicitly passing an object to the pipeline without exiting the function like a barereturnwould.I would still love to see this feature:
[CmdletBinding(ExplicitReturn)]on functions and then only pass objects on to the pipeline withyield returnorreturnkeywords. As Steve Lee (@SteveL-MSFT) said it's been a long standing source of frustration for new and old PowerShell users, could this be looked at again and evaluated for the roadmap for this year or so?microsoft-github-policy-service commentedon Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
microsoft-github-policy-service commentedon Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
microsoft-github-policy-service commentedon Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
jantari commentedon Nov 16, 2023
This is still something I'd very much like to see and I also stand by the idea of borrowing
yield returnas a new statement.microsoft-github-policy-service commentedon Nov 24, 2023
This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.