Go Hate Thread

...

char* token = strtok(someString)
if (token == NULL) {
//Error handling
}

Oh look, your beloved C does the exact same kind of error handling.

So what is in result in Go if there is an error?

at least it doesn't claim to be a clean and modern language, we all know C is ancient and has problems

Usually, the zero value for the return type. Normally, you don't touch the result if there is an error.

>Go is as shit as C but even slower because of GC
That's the point, m8.

// when will they learn?
if ((result = func()) != 0)
printf("something happened");

>Usually, the zero value for the return type. Normally, you don't touch the result if there is an error.
So it's undefined?

Whoever thinks this approach is better than exceptions is absolutely retarded.

Foo something = somefuction();
if (check_magic_global_error_variable_i_hope_you_are_not_multithreading()) {
status = 5;
goto ERROR;
}

Luckily errno is threadsafe.

Foo result = some_func().orElseThrow(RuntimeException::new);

Step aside boys
try
{
//something to try
}
catch(Exception e)
{
//something went wrong
}

>exceptions
>return codes
What is this, 1990s?
fn error_safe() -> Result {
let result = some_func()?;
let another_result = some_other_func()?.some_method()?;
Ok(result + another_result)
}

an error code or message, i do it all the time in lua, pretty sure it's common practice in all languages that support multiple return values.

No, it's not undefined. It's very well defined by the code that returned it. I was just pointing out that the convention is to return the zero value for the type. If the result type is a pointer (or pointer-like, i.e. slice, map, func, chan), it's nil. If it's an integer, it's 0. If it's a string, it's "", etc. etc.

Although I'd admit that is pretty sexy, exceptions are not as bad as Sup Forums wants them to be desu senpai. It makes writing code more natural, because you write code for the path that assumes successful termination, rather than interleaving error checks with normal path. This is why I find exceptions appealing, errors are treated as literal exceptions, rather than a natural part of your code. It also allows compilers to optimise for the successful termination path.

>No, it's not undefined. It's very well defined by the code that returned it.
See, that's the problem. Unless the function signature somehow indicates what the result is in an error condition, you have to rely on conventions. This is why error handling in C is crap, and I really don't understand why Go would adopt this as a modern language.

You operate under the assumption that you are not meant to touch the result if the function returned a non-nil error, so you really don't care what it is. If you can do something with the result even if there is an error, the function should document this (though these cases are extremely rare, and are usually handled differently: perhaps using a sticky error or in the style of bufio.Scanner).

>You operate under the assumption that you are not meant to touch the result if the function returned a non-nil error, so you really don't care what it is.
I get that, and I'll admit that it is slightly improved over C-style intermixing of values and error codes.

But still, I just prefer semantics where error handling is completely separated from the normal code path.

> because you write code for the path that assumes successful termination
You do the same in Rust with try! macro and ? operator, but you don't run the risk of forgetting to catch a particular exception you've added somewhere down the path. It requires some boilerplate to set up proper Errors hierarchy, but error_chain! simplifies that somewhat.

Cool, I'll have to look into Rust some day. It looks pretty nice.

That doesn't look all too bad, it's just another way of handling errors.
Go has other concerns but your picture is certainly none of them

Fair enough. Personally, I don't mind the error handling too much because the language compensates in other areas, such as the exceptional standard library and the concurrency primitives. Go might not be able to express happy paths (+ exceptions) very nicely, but it can express concurrent behavior in ways that are elegant and easy to understand / reason about. I can live with that.

Can you give some examples regarding concurrency primitives and how you can express concurrent behaviour in Go?

I don't know any Go and I'm too lazy to look it up.