4 ms·
It would help a bit if the article included at least roughly equivalent Go code next to the Python code. The Go code is wordier, but maybe it takes less time to
by it 14y ago
It would help a bit if the article included at least roughly equivalent Go code next to the Python code. The Go code is wordier, but maybe it takes less time to write because it doesn't require as many decisions (libraries etc.) as with Python.
package main;
import (
"fmt"
"net"
)
func main() {
hosts := []string { "www.google.com", "www.example.com", "www.python.org" }
c := make(chan string)
for _, h := range(hosts) {
go get_ip(h, c)
}
for i := 0; i < 3; i++ {
fmt.Println(<-c)
}
}
func get_ip(host string, c chan string) {
addrs, err := net.LookupHost(host)
if err != nil {
fmt.Println("Host not found:", host)
c <- host + ": <error>"
return
}
c <- host + ": " + addrs[0]
}
- zemo 14y agoThis is a very good example of the type of thing I'm talking about. Nobody prompted you to do so, but you gracefully handled the case of a DNS failure in your code, because the control path was obvious throughout. Go makes this type of error handling a topic very early on in the literature. I find this type of clarity when structuring concurrent code to be very helpful in minimizing subtle concurrency bugs.
- d0mine 14y agoOn error handling in Go vs. Python: Lack of exceptions means the deeper the call stack the higher the proportion of error handling code relative to a normal (non-exceptional) code path. For example, if you decide to refactor some code from a bigger function into its own smaller function then all error handling code have to be repeated twice (first in the child function then in the parent that calls it). It introduces unnecessary clutter and boiler-plate. Exceptions allows you to limit the error handling to two places: the place where you detect an error and the place where you are ready to handle it and not throughout the whole call stack. Language with a builtin garbage collection can (should) afford a builtin exception support. I like that Go excludes some language features on purpose but in the case of exceptions Python has its merits.
- mseepgood 14y agoGo has panic/recover if you have to propagate an error through multiple layers.
- goblin89 14y agoComing from Python, I was of the same opinion at first. A significant amount of error handling lines is what I noticed first when looking at Go code[0], too. However, I was interested to learn that Google style guide for C++ recommends not using exceptions. I don't know C++ (shame), but at least some of their reasoning is applicable to Python as well: For example, when you start raising an exception in a Python function, you have to check its callers, whether they (or their callers) handle it. And vice-versa—when a Go function has “expected” error in its signature as return value, it's very obvious what you need to handle when you're the caller. “Expected” error as return value also encourages single responsibility principle, I suppose. E.g., for a function that decodes JSON, bad syntax is “expected” error, the rest is a reason to panic(). I'm not sure if I get your example with refactoring, but it may be a case when you use panic() in inner function, recover() in outer, and return an error as usual. That said, I've never actually used Go yet, so it's just theorizing. [0] But then my Python code that (to me) looks more or less “solid” appears to contain a comparable amount of error handling lines, so not sure if it's a good metric.
- zemo 14y agoI was initially of the same opinion, but with time I came to understand that Go's error handling system is like vegetables; unpalatable, but good for you. Go's error handling works very well in practice, and my programs exhibit little to no unexpected behavior.