while they have added some preemption to the scheduler, go is still generally cooperative multitasking. I believe function calls are also schedule points now. If you have a cpu-intensive loop you want to yield from at certain points, stick a runtime.GoSched in there. Having a busy-loop in your code is going to mess things up, and is usually a bug anyway.
I think what GP is getting at that if you call a function with one return value, you can ignore it by not assigning anything to the result of the function.
Go forces you to either assign the return value to a variable and then use that variable, or pretend it doesn't exist at all. I think they were trying to get rid of the middle "assign it to a variable, deal with it later" case, to encourage people to write error-handling code there and then, but I've found that instead it pushes me towards completely ignoring error codes, then because there's no "unused variable 'errorCode'" warning, I forget to go back and robustify the code :(
I probably /should/ get into the habit of writing error-handling code at the same time as writing the main-path code, but for someone who's just started learning the language and just wants to see what works, I find it really frustrating >_<
I agree with sambeau on this one. I have come to like the go way of doing things: it's extremely simple, doesn't take much thought, and after a little while is very easy to read.
I'm sure I don't know most of them (e.g. I have no idea how Prolog does error handling), but I know of:
* the Haskell/ML statically typed approach, error possibility is type-encoded through an Option or Either type; even in cases where it is possible to implicitly ignore return values[0] the compiler will warn or error; the standard library provides high-level operations to pipeline results (build a pipeline of operations which will only transform non-erroneous results, and will let errorneous ones go through)
* the Erlang dynamically typed approach which makes use of tagged pattern matching to make value assertions trivial. It is not shorter than the Go version when fully handling things, but assertion can be used to fault processes during development or when in-process user-visible reporting is irrelevant (fairly common in erlang) yet remain easy to find and replace with more involved handling if needs be
[0] because haskell strives for purity, ignoring return values in non-monadic code makes very little sense and I'm not sure it's possible at all short of unsafe* functions. It is possible in monadic code (e.g. do blocks)
_, err := somethingThatFails(arg)
if err != nil {
return fmt.Errorf("failed with arg=%v, %v", arg, err)
}
Now the use for this is not obvious from this toy example, but having a `printf`-like function that produces error is great to return errors with more context.
The difference from your example is that the info in `err` is not lost when passed up.
... then because there's no "unused variable 'errorCode'" warning, I forget to go back and robustify the code
Well, you can always assign the error code to '_', and then just grep for those later. Or you can take the 10 seconds and just add the code to return the error as sambeau suggests.
OCaml gives you a warning ("this function should return unit") if you don't use the result of each function call, unless that function returns unit (void). You can suppress it with the "ignore" function or with "let _ = some_function() in …"
I would like to implement this feature in Rust as well, as it would have saved me hours of debugging a couple of times.
> OCaml gives you a warning ("this function should return unit") if you don't use the result of each function call, unless that function returns unit (void). You can suppress it with the "ignore" function or with "let _ = some_function() in …"
GHC can also do so optionally (with -fwarn-unused-do-bind) (and I'm unsure there even is a way to ignore return values outside of do blocks)
Linked in that article (http://benchmarksgame.alioth.debian.org/u64q/code-used-time-...) is a comparison of conciseness and performance. Interesintgly the FP languages are put in a right-more / less-concise column than Go, C, C++ (unless I am reading it wrong).
Since the verbosity of error handling in Go is part of the debate here, are not FP languages often more concise? Is "concise-ness" really an issue?
I am so happy they decided to include comparison operators in text/template and html/template [1]. It drove me nuts to have to write comparison functions and call them from within the template. Yes, it kept some logic out of the template but in my opinion it added an unnecessary layer of indirection.
I really want to like Go, but I'm having a hard time believing that they don't have a plan for generics. I've read the FAQs about go+generics, but do we have any better idea of when generics might make an appearance? Not being able to write a generic "map" function in a modern language seems very strange to me.
> I really want to like Go, but I'm having a hard time believing that they don't have a plan for generics. I've read the FAQs about go+generics, but do we have any better idea of when generics might make an appearance?
As a language feature: not likely any sooner than Go 2.0, given everything that's been said on the issue, though I suppose if a way could be found to do generics that doesn't explode compilation time and doesn't involve syntax changes that would break any existing Go 1.x code, it might happen in a later 1.x release. Wouldn't hold my breath.
http://golang.org/doc/faq : "Generics are convenient but they come at a cost in complexity in the type system and run-time. We haven't yet found a design that gives value proportionate to the complexity, although we continue to think about it. Meanwhile, Go's built-in maps and slices, plus the ability to use the empty interface to construct containers (with explicit unboxing) mean in many cases it is possible to write code that does what generics would enable, if less smoothly."
One of Go's goals is a certain level of simplicity. The above point seems to state that generics don't fit that goal, but they are not precluded from a future version.
I take this to mean that since no language has every feature that anyone could possibly want, if generics are a requirement for your work, then Go does not fit the requirements.
"Early in the rollout of Go I was told by someone that he could not imagine working in a language without generic types. As I have reported elsewhere, I found that an odd remark."
This is great: "Finally, an HTTP server will now serve HEAD requests transparently, without the need for special casing in handler code. While serving a HEAD request, writes to a Handler's ResponseWriter are absorbed by the Server and the client receives an empty body as required by the HTTP specification."
39 comments
[ 3.0 ms ] story [ 86.9 ms ] threadDoes this still block forever?
package main
import "time"
func main() { go func(){ for {} }() time.Sleep(time.Millisecond) }
A busy loop is a sufficient way to emulate a heavy computation (e.g. applying effects to image files or compressing data) when it's not optimized out.
http://play.golang.org/p/9J46QRHul1
They presumably would like to force you to use the return value if it is of type error.
On a side note, does any programming languages force you to use the return value of every function call?
I probably /should/ get into the habit of writing error-handling code at the same time as writing the main-path code, but for someone who's just started learning the language and just wants to see what works, I find it really frustrating >_<
My Go programs have far better (more detailed & relevant) error messages than any of my other code.
Yes, we all know how good humans are at work which no computer could ever do such as repetitive output of pointless generic boilerplate.
An exception and line-number (and a call-stack dump) is great for a developer, but a good textual error message is needed for a real user.
The first pattern does not do that. The second one is still mostly pointless generic boilerplate:
is all boilerplate, only two parts are not: the call itself and the error message.> An exception and line-number (and a call-stack dump) is great for a developer, but a good textual error message is needed for a real user.
1. having exceptions doesn't preclude handling them and writing user-readable error messages
2. exceptions are not the only alternative to C-style error handling
* the Haskell/ML statically typed approach, error possibility is type-encoded through an Option or Either type; even in cases where it is possible to implicitly ignore return values[0] the compiler will warn or error; the standard library provides high-level operations to pipeline results (build a pipeline of operations which will only transform non-erroneous results, and will let errorneous ones go through)
* the Erlang dynamically typed approach which makes use of tagged pattern matching to make value assertions trivial. It is not shorter than the Go version when fully handling things, but assertion can be used to fault processes during development or when in-process user-visible reporting is irrelevant (fairly common in erlang) yet remain easy to find and replace with more involved handling if needs be
[0] because haskell strives for purity, ignoring return values in non-monadic code makes very little sense and I'm not sure it's possible at all short of unsafe* functions. It is possible in monadic code (e.g. do blocks)
The difference from your example is that the info in `err` is not lost when passed up.
(I just picked (and cleaned up) the first piece of simple error code that I thought would be easy to use.)
Well, you can always assign the error code to '_', and then just grep for those later. Or you can take the 10 seconds and just add the code to return the error as sambeau suggests.
I would like to implement this feature in Rust as well, as it would have saved me hours of debugging a couple of times.
GHC can also do so optionally (with -fwarn-unused-do-bind) (and I'm unsure there even is a way to ignore return values outside of do blocks)
The blog and comments here have summed this debate up nicely: http://uberpython.wordpress.com/2012/09/23/why-im-not-leavin...
Since the verbosity of error handling in Go is part of the debate here, are not FP languages often more concise? Is "concise-ness" really an issue?
As someone who spent all of yesterday trying to figure out the best workaround for the lack of this functionality, I'm very happy to see this change.
[1]: http://tip.golang.org/doc/go1.2#text_template
edit: there's something "map"-ish here: https://code.google.com/p/go/source/browse/src/pkg/exp/itera...
Why? 4 years on seems a long enough time to come to term with what Go is.
As a language feature: not likely any sooner than Go 2.0, given everything that's been said on the issue, though I suppose if a way could be found to do generics that doesn't explode compilation time and doesn't involve syntax changes that would break any existing Go 1.x code, it might happen in a later 1.x release. Wouldn't hold my breath.
Via a preprocessor? Its already a thing: https://github.com/droundy/gotgo
One of Go's goals is a certain level of simplicity. The above point seems to state that generics don't fit that goal, but they are not precluded from a future version.
I take this to mean that since no language has every feature that anyone could possibly want, if generics are a requirement for your work, then Go does not fit the requirements.
Some potentially relevant material here - http://commandcenter.blogspot.de/2012/06/less-is-exponential... :
"Early in the rollout of Go I was told by someone that he could not imagine working in a language without generic types. As I have reported elsewhere, I found that an odd remark."
Been waiting for this forever...