-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: Alternate to try(): 1. Call func/closure from assignment and 2. break/continue/return more than one level. #32473
Comments
try()
: 1. Call func/closure from assignment and 2. break
/continue
/return
more than one level.
For those who are voting thumbs down or reacting with confused, can you at least give me the courtesy of providing some explanation for your reactions? Right now it's not clear what about the proposal you disliked or did not find clear. |
When someone writes For func B(i int) (int, int) {
if i > 3 {
break^2
}
return i, i
}
func F() {
var a, b int
for i := 0; i < 10; i++ {
a, b = B(i)
}
// What are the values of a and b here?
} |
Let me expand slightly: I'm sure we can decide on answers for the questions I am asking. But for a really good language proposal the answers to these questions should be in some sense obvious. If they are not obvious--and I don't think they are--then this proposal makes the language more confusing and harder to learn. That is a significant cost, and it requires a significant benefit. |
Hi @ianlancetaylor — thanks for commenting. Honestly, I am caught between really wanting to make a difference and fearing that any efforts I put into this will be for naught. I had already invested over 8 hours into the comments I left on That said, you make some great points and I hope you won't mind me massaging the proposal to address those questions. I'll do that and then follow up with another reply. |
@ianlancetaylor - So in my haste to complete this proposal I forgot to include the return parameters; I have updated to include them now. To explain in more depth, think of the placeholder syntax of " To illustrate, each the first two
Note that I am explaining a potential feature that is orthogonal to error handling but can instead be used for error handling. Of course we could use a different syntax to specify the levels to return (not that I am proposing this syntax, I just wanted to show something different):
Now there is one issue I did not address and that is what happens when your Which bring it to this point. This capability could easily be limited to returning from closures and that would simplify this latter issue. But if you did that then we could not create a named func that could be used as an error handler across multiple functions, which is one of the most powerful things that I think my proposal offers; the ability to create reusable error handlers across methods, across structs and even across packages. |
Panicking if the result parameters do not match is an interesting approach, but I have to say that at first glance I do not understand how to implement that. |
In that case you've got me. I wish I had the skill to code at that level but at this point that level is Greek to me. I guess if it cannot be done — sadly — that makes at least the more general part of my proposal moot albeit you could still support closures since you can see both scopes when compiling. |
Features in Go should be orthogonal. It would be less than ideal to add But if we permit any function call to invoke This is an interesting idea but I'm having a hard time seeing how it could really work. |
@ianlancetaylor Thanks for the follow up. But It has been over a month since I proposed this, and a lot of water has flown under the bridge. I have since seen several other approaches proposed by others that I would as easily get behind as this — if we could even identify a way to achieve this. The one solution I definitely find problematic though is the current iteration of But no need to rehash why as I previously wrote in depth my issues on the other ticket. I for one really hope that we identify a better, more general solution and don't move forward with what it on the table. #fwiw. |
We do our best to evaluate proposals as they are presented. As far as I can see it's the only fair and reasonable approach. If you do not think this specific proposal should be adopted, it's fine to withdraw it. Thanks. |
@ianlancetaylor Sorry, I think my words caused you to misinterpret my meaning. For clarity:
|
The main problem with a multi-level return is that it makes functions less explicit. If I call I someone like the idea allowing functions on the left side of |
Supporting Without that feature, the rest of this proposal does not seem to do what the proposal is intended to solve. There also doesn't seem to be great deal of enthusiasm for this approach. -- writing for @golang/proposal-review |
@ianlancetaylor Thanks for taking the time to thoroughly consider it. As I said above, It was just one of the many approaches I have since found that might be a good solution. However, I would like to ask that the team seriously consider
The benefits here is that the "clean up" code is at the end where code logically flows, and is using a simple This all works today, but if return becomes the "standard" way to do error handling, clients won't like this approach and I'll reasonably need to move to the newly idioms. But I am hoping that newer idioms can embrace a simply flow like the above, maybe with some small changes to streamline it. One simple change I would love is for Go to support one of these two syntax as an alternate to an empty block so that i don't have to redeclare the package
Or:
There are obviously other potentials for improvement — as many have debated for weeks — but this one is a super simple next ask. This is nothing more than do-nothing sugar but it could come to be know to signal intent to use a block for error handling with P.S. This comment should be attributed to @mikeschinkel. I was commenting using a GitHub account a client is requiring me to use vs. my regular account. |
For what it's worth, you can write for once := true; once; once = false { |
True... but that is rather verbose, no? :-) |
I am going to make this brief with the potential of fleshing it out later because I have seen few proposals accepted here so I only like to invest a lot of time in fleshing it out if there is some chance it will actually be considered.
Overview
Add two non-error specific language features to enable much streamlined support for error handling that addresses the use-cases that
try()
would address, but that are more flexible and can handle a far greater number of use-cases.This can be achieved without builtins that require the understanding of "magic" behavior.
This proposal explicitly does not address the expression aspect of
try()
; it assumesfunc
calls that canerror
will each be called on their own lines, which I think is more in the nature of Go than using nestable expressions.For some additional details please see my comment with concerns about the
try()
proposal.Additions Required
break
,continue
orreturn
more than one level.Example
The following example illustrates both; here
e1
ande2
are closures — but could have as easily be declaredfunc
s — and the syntaxitems, e1(err) := GetItems()
means to calle1()
with the 2nd return value afterGetItems()
returns:Above we named the returned error
err
but we could have instead used_
as initems, e1(_) := GetItems()
, assuming that is not considered wrong given_
usually throws away values.As for #2 a we are assume the
return
can jump up the call stack by the number of levels indicated by "^n
."return^1
would be synonymous toreturn
, and in this examplereturn^2
would bypassProcessItems()
and return to its caller.Note also in the example we assume
break^2
will exits the current closure and then break out of thefor{...}
loop inside ofProcessItems()
. Similarly,continue^2
should be allowed to work similarly.Please consider the
^n
syntax is just one hypothetical we could choose so hopefully anyone responding won't bikeshed the syntax but instead discuss the general purpose concept of giving a developer a way to specifying how far up the call stack tobreak
,continue
orreturn
.Special-case builtins on assignment calls
Using the simple example from
try()
that takes this:And simplies into this:
Let us instead allow any of the following three (3) special case builtins to do the same, except that the later two (2) use
break
andcontinue
, respectively, instead of only supportingreturn
astry()
does:Example #2
Now let's revision the
try()
proposal'sCopyFile()
example but using this proposal's system instead. Unliketry()
, all coupling is explicit and easier to reason about when reading the code:Summary
Rather than create a special case
try()
I propose that Go instead add two (2) new general case language features vs. a feature useful for only a constrained set of use-cases. Further, I think these additions would be more in-line with the existing nature of Go but would address the same use-cases thattry()
was targeting. And finally, these features could potentially combined to address other needs that might otherwise force the Go team to add more "magic" builtins in the future.The text was updated successfully, but these errors were encountered: