- Feature Articles
- CodeSOD
- Error'd
-
Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
For those that like Java/Javascript/C++ better, it's like this:
Edit Admin
I hate to offend fans of Go, but this language is silly. What kind of weird syntax is that to put a method into a class (struct)? Why does it need to return
nil
, is it Go's version ofvoid
return type? And what's wrong with bubbling exceptions, why write all this "return err" stuff everywhere?Addendum 2025-08-18 07:31: PS. Also, why is the "tuple" assignment on top done using
:=
, and the field (property) assignment at the end done using=
?Addendum 2025-08-18 07:36: PPS. Oh I see, the
error
is the return type, sonil
means success. I guess it only has a(result, error)
orerror
return types for all methods? I recommend to rename this language to Stop - as in, if you think about using it, STOP.Admin
Go's
nil
is, like Ruby'snil
, the equivalent ofNULL
/null
. That's where the panics come from, the application is trying to call methods on a NULL pointer. Unlike C there's no segfault for the entire application.Returning errors is a choice made by the Go language design team, see https://go.dev/doc/faq#exceptions. I hate it myself as well.
Regarding the first addendum: the difference between
:=
and=
is relatively simple.=
may only be allowed if all variables on the left hand side have already been declared.:=
is the opposite, you must use:=
if any of the variables on the left hand side is new. It's another choice by the Go language design team to make it clear that you intend to create a new variable, without having to declare it separately first.Regarding the second addendum: any function or method that can trigger an error should return that error. If the method needs an actual return value the return type is a tuple, otherwise it's just
error
. Consider(result, error)
as the Go equivalent of returning either something of typeresult
or throwing an exception, anderror
as the Go equivalent of avoid
method that can throw an exception. If a function or method can't trigger any errors then theerror
part can be omitted. If there's also no return value the entire return type can be omitted.Admin
There's only one thing to stop, and it's the language diatribe, please.
Admin
:=
declares a new variable with inferred type. This is actually a good thing to avoid accidentally creating variables with a typo like Python.var
/let
is a lot better of courseEdit Admin
Yep, Go doesn't do exception handling except via explicit
error
returns orpanic
(which is generally discouraged). It's one of the most controversial parts of the language. Many people are incredibly annoyed by how wordy it makes the code, others will fight to the death to defend it. E.g. https://verygoodsoftwarenotvirus.blog/posts/errors-in-go/There are some really nice parts about Go (the concurrency story is excellent) but it's definitely an acquired taste.
Edit Admin
"But I haven't changed anything!" Yeah, right.
Edit Admin
I find their arguments very weak and mostly a result of subjective preferences while ignoring objective facts.
The main reason why exceptions got introduced after functional languages fell out of favor over OOP languages was simply efficiency. You see, if you use errors as results it means you have to at least constantly check result and then you have to potentially make new fake results so you can get back up the call stack. That's the C way of doing error handling and while it's cheap to implement on a language level (as in language compiler and runtime basically don't have to worry about it), it has the downside of either devs "forgetting" to implement error handling for pretty much every function result or they ad a a ton of boilerplate error handling/delegating code in a very messy way. So yeah, I'm with you there, it's a awful way to deal with errors.
Side note: When you try to open a file and it doesn't exist, it's an exception. Every language has methods to allow checking for existing files before, so this was by far the stupidest design argument I have heard in a long time since checked exceptions.
Edit Admin
Not to defend Go - I agree that its error handling is stupid - but trying to open a non existent file is not that exceptional and checking it exists before you open it is a pointless waste of time since it could disappear between the check and the open. It's much better just to try to open it and deal with the error or exception if the open fails.
On a side note, if your language uses exceptions there has got to be a way for the compiler to flag that you need to handle exceptions from the functions you are calling, otherwise each and every one that you didn't write or that calls a function you didn't write is effectively a non deterministic goto statement. Functions should declare the exceptions they throw (or at least that they throw some sort of exception) and handling of exceptions (including passing them up the stack) should be enforced in callers by the compiler. You may say "what about null references and division by zero etc?" but these are programming errors rather than exceptional conditions like missing files: they should cause termination of the program and maybe the programmer's contract.
Edit Admin
Good luck getting that recommendation past the C++ committees. (No, I don't know why they didn't include proper exception specifications at compile time. It's a constant source of bewonderment.)
Edit Admin
Easier said than done. Most business code calls some other code to get its real work done - write to a file, make a database call, whatever. That means all of the framework libraries are at the bottom of the pile and it either introduces a lot of fragility, or encourages workarounds (e.g. "throws RuntimeException"). Java gave checked exceptions a shot, but based on that experience few, if any, languages have seen it as a pattern worth following.
Edit Admin
Checking if a file exist is a very inexpensive table lookup on any OS, often even cached in memory. It's completely pointless when you know the file should be there in normal operations but if you don't, it's a perfect way to make sure.
Opening a file on the other hand is a highly complex operation in a concurrent resource limited environment. So there can a lot happen and for that reason OS front load a lot of operations (specifically when it comes to resource allocations) before they actually start with the actual creation of the file handle. It makes in normal situations sense to ensure those resources are available before you actually try to lock the IO resource. So everything that can go wrong here and there's a ton in a modern OS (heck, even simple DOS had over a dozen of possible error states), is exceptional because it's not part of the expected outcome.
Edit Admin
What you describe are the failed concept of checked exceptions, it makes in practice no sense because you end up with hundreds of different exceptions even for simple algorithms or you end up with a ton of overhead by repackaging exceptions over and over again. Not to mention a lot of sloppy devs just repackage exceptions in a single generic exception, making handling them up the stack in a meaningful way impossible.
The point of exception is to not have gotos at all during normal execution. All modern OS have system level exception handling and different version for different version of each OS. You basically define a system level scope and there will be no goto as long as no exception happens which is literally the benefit over checking error codes where you have constantly gotos (guess what an if-statement actually is). So basically the bad scenario which screws with the CPUs prediction engine becomes the exceptional state (hence the name). So if you hate gotos, you must LOVE exceptions :-)