-
Notifications
You must be signed in to change notification settings - Fork 18k
proposal: Go 2: add on statement #33266
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
Comments
Biggest problem I can see is that I cannot mix this with normal error handling. If I say |
@qrpnxz In most cases, you won't mix the error handling of functions that return an error and functions that return a struct with an package main
import (
"fmt"
"log"
)
type Response struct {
Close bool
Error error
Data string
}
func get(url string) *Response {
// Oversimplified code for the sake of example.
return &Response{
Close: true,
Error: nil,
Data: "",
}
}
func main() {
c := make(chan error)
on err := <-c; err != nil {
log.Fatal(err)
}
resp := get("https://github.com/golang/go/issues/33266")
on resp.Close {
fmt.Println("data received:", resp.Data)
}
// This should have been c <-resp.Error instead.
err <-resp.Error
} |
What does this mean, from the previous comment? on err := <-c; err != nil {
log.Fatal(err)
} You said that |
@ianlancetaylor let me first address what you pointed about nothing ever being writing to err <-resp.Error Should've been: c <-resp.Error Sorry for confusing that. Now, my last comment was an attempt to address the issue brought by @qrpnxz, but you're correct, the current implementation of channels would cause the example to block forever, so I would like to withdraw my proposed solution to use channels with the Back to the initial proposal, the
The Expression evaluates as soon as the func main() {
var a int
on a > 10 {
fmt.Println("a is now 10")
}
a = 10
} The message a is now 10 should be printed. Finally but not less important, the following example shows how the package main
import (
"fmt"
"log"
)
type Response struct {
Close bool
Error error
Data string
}
func get(url string) *Response {
// Oversimplified code for the sake of example.
return &Response{
Close: true,
Error: nil,
Data: "",
}
}
func main() {
var err error
on err != nil {
log.Fatal(err)
}
resp := get("https://github.com/golang/go/issues/33266")
on resp.Close {
fmt.Println("data received:", resp.Data)
}
on resp.Error != nil {
err = resp.Error
}
_, err = os.Stat("path/to/file.go")
} |
PropertyChanged event-handler - i think this makes applications much harder to understand. When will a function end? When the observed object is removed by gc - otherwise this would not work. In your first example the application ends before log.Fatal has written a single rune, if - and here is a performace problem - not the execution of all other blocks is paused (not threads, goroutines or functions). In this case just until log.Fatal has finished nothing alse may be executed, cause this would trigger other event-handlers. But there can be much more event-handlers, even embedded event-handlers (inlined or in called functions) - and all of this would live until gc cleans this up. If i combine your first and second example by moving the line resp := get("https://github.com/golang/go/issues/33266") to the end of your func main() - i feel no good - this should write "data received..."
package main
import (
"fmt"
"log"
)
type Response struct {
Close bool
Error error
Data string
}
func get(url string) *Response {
// Oversimplified code for the sake of example.
return &Response{
Close: false,
Error: nil,
Data: "",
}
}
func getResp() *Response {
resp := get("https://github.com/golang/go/issues/33266")
on resp.Close {
fmt.Println("data received:", resp.Data)
}
on resp.Error != nil {
log.Fatal(resp.Error)
}
}
func main() {
response := getResp()
response.Close = true // does this trigger the on resp.Close ?
response.Close = true // does this also trigger the on resp.Close ?
response.Close = false // this should just reset the condition to ask the following ..
response.Close = true // does this trigger the on resp.Close again ?
} If You say NO, then what if resp would be declared globaly.
Example: on err != nil {
...
}
...
on err {
...
}
on err == nil {
}
....
on err != nil {
...
} If err would be global, this event-handlers could be spread across the hole file or even package in any function and got executed somewhen - , - Nobody writes long functions, but if, multiple on blocks with correlated conditions could apear.
_, err = os.Stat("path/to/file.go")
_, err = os.Open("path/to/file.go") Maybe i am wrong - but either this does not work as expected at all or it hides execution paths, both is not good - just for errors you can use something like this or put the hole error-logging in a separate package - the great benefits are, that errors can be handled directly where they appear and they get also logged: package main
import (
"errors"
"log"
"os"
)
var errChan chan error
func init() {
errChan = make(chan error)
go logErrors(errChan)
}
func main() {
_, err1 := os.Stat("./nomain.go")
errChan <- err1
_, err2 := os.Open("./nomain.go")
errChan <- err2
errChan <- errors.New("no error")
}
func logErrors(errChan <-chan error) {
for {
errFromChan := <-errChan
if errFromChan != nil {
log.Println(errFromChan)
}
}
} This is readable for me and i can see when and what will happen. |
What should happen for func F() int {
var x, y int
on x != 0 {
return y
}
fmt.Sscan("1 2", &x, &y)
} When does the |
@ianlancetaylor good point. In this case, the returning value from calling the |
Note that |
@ianlancetaylor you're right. In this case, this proposal shouldn't move forward at all IMO. Feel free to close the issue if you agree. @maj-o thank you for the feedback, I wish I had time yesterday to reply you. |
Thanks, I don't see how to make this work, so closing. |
I propose the addition of an
on
statement. Much like theif
statement, the block of theon
statement executes when the<expression>
is evaluated to true:However, unlike the
if
statement, the block of theon
statement executes whenever the<expression>
evaluates to true:Those two examples are using error handling because it's a controversial topic right now, but having an
on
statement is more than just avoiding boilerplate code – in essence, theon
statement would improve the language expressiveness in my opinion. The example above shows another applicability:Thanks in advance.
The text was updated successfully, but these errors were encountered: