Live data from Hacker News

Everyday hassles in Go

crufter.com

291–297 of 297 posts

Re: Everyday hassles in Go

#291
post #76

Well, I want Go to have refcounting instead of current GC, so my programs could guaranty latency. Single-threaded runtime, without all the locks, slow channels, races and so on, because there is no point in so much overhead and complexity for the majority of programs. More consistency couldn't hurt, so I wouldn't have to assign anonymous function to a variable just to return it. Fast regular expressions compiled by t…

The majority of the programs do not really need to guarantee latency. That being said, it is well known that Golang's present GC performs poorly. It presently fails to free memory in certain cases, and has pretty high overhead. There is work done on improving the GC to be fully concurrent, but that is still probably still 2-3 major versions away.

The concurrent GC is planned for version 1.5 and is only 6 months away. There is also work being done on a compacting GC, but I don't know when that is supposed to land.

Actually, the Go team is making very good progress on all the prerequisites to real-time garbage collection. Who knows if they will manage to get all the way there, but I know there's been some discussion about it on the mailing list.

If you look at how fast the GC has improved over the years, it's kind of ridiculous that anyone bothered to criticize it at all, as if it was not really the temporary solution the devs said it was, and was in fact going to stay shitty forever.

Re: Everyday hassles in Go

#292

Earlier quoted context omitted.

This looks more like a bug. The second err is a valid redeclaration, and so should be checked for usage on it's own. Though the redeclaration through multiple assignment is itself a bit of a wart that the programmer hast to be wary of, so it may not be a big deal. In any case, the go compiler is very helpful in most cases, and better tooling can improve things further.

FYI the second use is just assignment, that's why it's not caught by the unused variable rule.

Ah right. It only shadows if it's a new scope.

Re: Everyday hassles in Go

#293
post #143

Earlier quoted context omitted.

First of all, you're making the enterprise java argument. Which is valid, but drives me to suicide. Furthermore ... Go ... succinct ... elegant ... using reflection as an alternative to generics ... In my experience Go is neither succing (if err { ... } one-statement if err { ... } one-statement if err { ... } one-statement). It is extremely inelegant because due to the confused sequence of statements it isn't possib…

Go's philosophy is to consider errors and failures are part of solving problems, not something "exceptional" that should make you fail and refer to a higher authority. Error-checking and error-reporting is not something that is distracting the normal flow of your function : it is part of the normal flow of your function.

First except of course for the corner cases that Go thinks should not be accounted for. These include serious system failures (e.g. gc fails for some reason), memory allocation failures, and of course anything that calls panic. Other errors are effectively impossible to be handled (e.g. system is thrashing and Go's gc runs - you'll never see your program again). So this can't be solved.

So please don't say Go doesn't have exception handling. It has code that detects exceptional conditions and attempts to handle them by unrolling the stack. Of course that's entirely different from "exceptions", right ?

Plus it once again points out the schizophrenic nature of Go. Go uses error codes. Except when it doesn't. Go doesn't have generics. Except when it does. Go doesn't allow polymorphism. Except in ~5 cases. No language on the planet allows for return type polymorphism (meaning of the function changes depending on what you assign it's result to) ... except of course Go.

This was one of the main, and valid, objections people had to languages like modula-2, oberon and the like in the past. And maybe I'm getting old, but my money's on that the pendulum will swing back again.

Furthermore I disagree with your assessment. Go and C insist on the same thing : in-line errors. In C that lead to errors being ignored in the vast majority of cases by "average" programmers. In Go ... well, here's the top-5 of Go projects. Go and take a look for yourself :

https://github.com/trending?l=go (note: changes every day. Now check if errors are ignored today or not. Today's answer 4 of the top 5 projects ignore almost all errors)

But I don't see how your comment addresses the complete unnatural way of thinking that C and Go promote. Handing errors in-line is not natural. This was one of the big complaints when we moved from C to Java/Python, a move supported by a lot of programmers.

So let's be honest here. Go's philosophy in practice is to make users ignore errors.

Re: Everyday hassles in Go

#294
post #293

Earlier quoted context omitted.

Go's philosophy is to consider errors and failures are part of solving problems, not something "exceptional" that should make you fail and refer to a higher authority. Error-checking and error-reporting is not something that is distracting the normal flow of your function : it is part of the normal flow of your function.

First except of course for the corner cases that Go thinks should not be accounted for. These include serious system failures (e.g. gc fails for some reason), memory allocation failures, and of course anything that calls panic. Other errors are effectively impossible to be handled (e.g. system is thrashing and Go's gc runs - you'll never see your program again). So this can't be solved. So please don't say Go doesn't…

About your first point : yes, go has exceptions, the so-called panics, but they are here for truly exceptional situations, those you can't recover for, mainly bugs from the programmer (nil dereference, out-of-bound access, bad dynamic cast, etc.) or, in theory, when the system gets in an unstable state (no memory left, hardware failure, etc.). But they really are the exception (sic), that's why I didn't mention them. Let's be honest : almost nobody ever deals with these errors anyway, and that's not the kind of things people think about when they talk about dealing with errors via an exception mechanism.

I really think (and it looks like we strongly disagree on this point) it's one of Go's virtues to really distinguish between what's part of the problem you're trying to solve and what can be considered as defaults from the computer (as a whole, i.e. both software and hardware). You shouldn't have to deal with these very different problems the same way.

As for your comment about the practice being to ignore errors in Go, I have to believe your words I guess (maybe I should have a look at these horrors you're talking about). This is clearly not the way I work but that's a serious fault from developers if they do. And, of course, that will lead to very serious bugs since an ignored error code is much more damageful than an uncaught exception. Sure, empty try-catch blocks are found in java too, but they tend to disappear.

Re: Everyday hassles in Go

#295
post #245

Earlier quoted context omitted.

I've been trying to get my mind around this kind of stuff for maybe a year. And I have to say that monads don't look like the solution to any of the problems that I actually face or have ever faced, in a thirty-year career. So, no, it's not just that the words are unfamiliar. It's that the problems that they're trying to solve are so abstract that they're completely disconnected from the work that I actually do. And…

Did you ever work with a list? Did you ever do things like foo = [bar(x) for x in quux] Or did you ever flatten a nested list? Congratulations, you've been using one of the most widespread monads. Monads are not artificial constructs. Monads, like functions, or loops, or conditional statements, emerge naturally when you try to describe a computation, even a simple one. This is like speaking prose without knowing that…

    foo = [bar(x) for x in quux]
This is effectively a map, so it's strange to call it "using monads". "Using functors" would be more accurate.

You can get "monad" out of list comprehensions though, when you have multiple "for" clauses.

    foo = [y for x in quux for y in bar(x)]
seems equivalent to foo = quux >>= bar

Re: Everyday hassles in Go

#296
post #293

Earlier quoted context omitted.

First except of course for the corner cases that Go thinks should not be accounted for. These include serious system failures (e.g. gc fails for some reason), memory allocation failures, and of course anything that calls panic. Other errors are effectively impossible to be handled (e.g. system is thrashing and Go's gc runs - you'll never see your program again). So this can't be solved. So please don't say Go doesn't…

About your first point : yes, go has exceptions, the so-called panics, but they are here for truly exceptional situations, those you can't recover for, mainly bugs from the programmer (nil dereference, out-of-bound access, bad dynamic cast, etc.) or, in theory, when the system gets in an unstable state (no memory left, hardware failure, etc.). But they really are the exception (sic), that's why I didn't mention them.…

> About your first point : yes, go has exceptions, the so-called panics, but they are here for truly exceptional situations, those you can't recover for,

1) I recover from such errors in Java all the time. It's easy : execute finally's ("defers"), execute retry policy (go, incidentally, makes generic retry policies very fucking hard due to lack of generics. It is impossible to write a method "TryThreeTimes(method, timeout, params)" in Go.

2) It is extremely disappointing that after all the effort that Go forces on you for error handling there are still a dozen classes of errors (of the kind you find often) that can kill your program, even with error handling perfectly up to the Golang author's standards.

3) These errors happen often enough that it's not reasonable to kill the program if they happen, so you absolutely need to recover in daemons and the like. So any reasonably large Go program has to consider exception handling, recovery, and alternate method returns.

4) You also have the C++ problem : libraries should never, ever raise an exception ("panic"). But of course, they do (ok granted, the Go standard library is reasonably good about this, but the same cannot be said for github stuff)

5) Nobody actually does the error handling. You never see anything other than "return err" or "exit program with log message" in error branches anyway)

> I really think (and it looks like we strongly disagree on this point) it's one of Go's virtues to really distinguish between what's part of the problem you're trying to solve

Yeah we disagree here. I feel Go's error handling standard prevents me from focusing on the problem independently of what might go wrong, and this limits my abstract thinking. What makes this even more frustrating is that this is exactly the same problem C had.

> This is clearly not the way I work but that's a serious fault from developers if they do.

With the guarantee of quality developers, I'd develop nearly anything in C++. There is no problem in C++ if you have a really good team and there's just no beating the C++ language in too many departments (portability, abstraction, compiler quality, tooling, power, control of complexity in huge programs ...).

But the great failing of C++ is simple : it doesn't support junior programmers, or otherwise somewhat incompetent teams very well at all.

The question here is : does Go ? I don't know, but to me it's not looking good. I would argue that the damage that can be done by slightly incompetent programmers in Go far exceeds the damage that can be done in most other languages (ok, granted, maybe it's better than C++, but definitely worse than Java).

Re: Everyday hassles in Go

#297
post #296

Earlier quoted context omitted.

About your first point : yes, go has exceptions, the so-called panics, but they are here for truly exceptional situations, those you can't recover for, mainly bugs from the programmer (nil dereference, out-of-bound access, bad dynamic cast, etc.) or, in theory, when the system gets in an unstable state (no memory left, hardware failure, etc.). But they really are the exception (sic), that's why I didn't mention them.…

> About your first point : yes, go has exceptions, the so-called panics, but they are here for truly exceptional situations, those you can't recover for, 1) I recover from such errors in Java all the time. It's easy : execute finally's ("defers"), execute retry policy (go, incidentally, makes generic retry policies very fucking hard due to lack of generics. It is impossible to write a method "TryThreeTimes(method, ti…

Ha, it's really a matter of taste, because what I like about error codes is how easy and readable it is to write "I want to try three times then fail" blocks.

    for i := 0; i 
Writing this kind of behavior with try-catches is rather annoying, the try-catches being leaking all over the code.

About C++, well, I almost agree ; this is my favorite programming language (in the sense it would be the one I'd use if I had to pick only one), but I think it is not the right tool for a lot of tasks (including the ones Go is targeting : servers and sysadmin tools). Java might be better for servers than Go, but for sysadmin tools it clearly sucks (because of startup time, mainly).

Post reply on HN