Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I wasn't aiming for that. My point is more: I know Go already, it's good enough for my purposes, so I'm using that as my hammer. I could just as well have been Java or C# I learned eight years ago and used that for everything. :)


I just began using Go literally 2 days ago, but I could already see building most of my projects in it from here on out. It has the type system I'd need from Java or C#, while being almost as simple and readable as Python. I love the module system so far and enjoy not having to decide on my own formatter.

Go is perfectly boring and simple, and seems to get out of my way. At least, that's how it feels as a newcomer. I'm sure it will change over time, but I'm having a blast at the moment.


> It has the type system I'd need from Java or C#

Its type system is much more primitive than either one of those.


I've been using it for work projects for a year or two now and I still feel the same way as you.


It actually gets even better! :D Enjoy the journey!


What about the absence of exception handling?

Plus OO has its own advantages, even if you don't use it all that much, its one of the best ways to fit problems into neat design patterns.

Go seems to be missing those features.


In modern Java applications, interfaces are favored much more heavily than OO designs relying on inheritance.

And Go has very nice support for interfaces. To the extent you don't even need to declare support for an interface. Go just figures it out if your type supports all the methods in the interface.

If you mean classical Smalltalk style OO, no Go doesn't support that, but neither do Java or C# or C++.


Interfaces and functions do pretty much everything inheritance does. It's just cut in a different direction. If you go in demanding that Go support inheritance you'll be in for a bad time; if you go in demanding that it have some good solution to those problems that you may not be used to, you'll find it generally has them.


Go has exceptions and exception handling in the form of panics and recovers, but go devs are discouraged from using them.

Go also supports most of the typical attributes of oo. It has polymorphism and encapsulation it’s just missing inheritance and uses composition instead. Most Java and C# code basis have stayed away from inheritance (for a long time) so there isn’t that big a difference.


What you see as missing, others (including myself) see as delightfully constrained and solved in a different way.


This is my first time working with a language that exclusively uses errors as values, and I haven't had time to develop any strong feelings about it. So far it feels nice because it makes error handling crystal clear, but I could also see it becoming cumbersome over time.


It’s the exact same broken system as has been known from C, it’s literally checking `errno` all the time.


I mean, you're not wrong, It's just strings (usually) instead of ints.

It's pretty bad, but it turns out that exceptions and inverting my entire program to pass into a Result's flatmap chain are even worse.

When they come up with another strategy, I'll try that instead, but until then I'll keep using the least bad option I've found.


> It's pretty bad, but it turns out that exceptions and inverting my entire program to pass into a Result's flatmap chain are even worse

Based on what? Exceptions do the sensible thing at all times: auto-bubbling up (no random swallowing), contain info about its origin, and a handler can be specified as tightly or widely as necessary.

It’s objectively superior to grepping for an error message, or straight up not doing anything which go is especially prone to do, as after a time all the if errs become just visual noise.


> Based on what?

My experience using all three.

> no random swallowing

We have not been in the same codebases, apparently. The number of times I've come across (I'm paraphrasing):

    try {
        // some stuff that can fail
        // bonus points if there's a comment explaining why it can't error in practice
    } catch (Exception e) {}
Is hilarious. Especially when it happens in library code.

As verbose as `if err != nil { return nil, err }` is, the fact that it gets banged out so much means people default to it, and I find myself less likely to get into a weird partially initialized state in go than I have been in other languages.

> It’s objectively superior to grepping for an error message

Then use `errors.Is`?


It can get verbose, but I'm willing to live with it for all the other benefits of the language.


I mean to this end, Go is more closer to Perl(C/Unix family) than to Python(Pascal? family).

But by now most programers are so very used to making the language do a lot of error handling kind of chores that having to do them manually kind of feels doing work that shouldn't be done(Like doing what the language should have been doing).

Of course you could bolt OO onto Go. In a way similar to how Perl provides kind of bare bones means assemble a OO system. But that is not the point, having syntax to this baked into the language just makes it easier and standardised to learn and use well.

Perhaps Go is Perl done right? Than a replace for Python.

But one has to see for how long it can maintain its minimalism. On the longer run code turns to be as complicated as the problem you are trying to solve. Removing the features doesn't make the code simple, it simply make it explicit(a.k.a Verbose)


? It doesn't have exceptions, so it doesn't need exception handling. It has an error system / standard that isn't based on exceptions.

I only know exceptions from Java myself, and in practice, what it calls exceptions are often... well, not exceptions at all. Files missing, SQL queries returning no errors, division by zero are not exceptional situations, but normal day to day events. And an exception generates a stack trace, which is an expensive operation.

I mean one way to avoiding that is defensive programming - check if a file exists, do a count on the SQL query first, do a pre-check or assertion before dividing - but that adds more and more code that you need to write, test and maintain.

OO has merit for what you describe, but Go's alternative works just as well (imo) for that purpose; you have struct types containing data, you can add methods to those types to encapsulate behaviour. Go doesn't have OO inheritance, but inheritance has been out of fashion for years now so it's not missed.

TL;DR, exceptions and OO are solutions to problems, Go has its own solutions to those problems, neither of which are difficult to understand.


Throwing prevents the caller's control flow from passing into code that assumes a useful value was returned and ready to be consumed when it wasn't. Handling a success or a failure with exactly the same code shouldn't be a default because it almost never makes sense.

A Java exception can suppress stack trace init if needed, letting an instance be created once and reused very cheaply (though logs will be less useful).


The whole idea of exception handling with try/catch comes from the fact that problems and error handling can all be standardised into one structure of patterns. Once you are here you can be sure the language(compiler) and tooling(IDE/Editor etc) will generate them for you and provide you with means to handle them.

Nothing much has changed in terms of problems and interfaces. So the errors will remain the same.

Now when you use go, you will have to write a lot of code that other wise the language+tooling could do automatically for you. This is just doing work that you shouldn't even be doing the first place and pointless verbosity.

Minimal is not always better. And some parts just feel like they were omitted because the language designer didn't want to do the work for you. Whereas the whole point of a programming language is that it does as much work for you as it possibly can and make it easier for you.

Just saying writing the same/similar code over and over again is waste work.


Of course, Go has try/catch, albeit under the keywords panic/recover. The whole idea of not using it, most of the time, except for the case of exceptions, comes from the fact that problems and error handling have shown to not in any way fit well into a standardized structure. Ruby, for example, came to the same realization even before Go. This is something that was already becoming understood before Go was conceived.

Sometimes it works out. Certainly encoding/json in the Go standard library shows that it's quite acceptable to use where appropriate – the programming tools are there to use, but it turns out that it is rarely appropriate. Which is also why most other languages are also trying their best to move away from the practice as a general rule, if it ever was adopted at all.


Just looking at Go after having experience with Erlang and Crystal, does it still have a narrow-minded view of what features language won't support?

Like I remember there was a whole drama about generics, errors being simple strings and always returned without being able to raise them, is this attitude still there or have things changed?


That attitude is still there because there is no compelling reason to move away from that. A lot of languages have been diseased by bolting on features for no other reason than different languages have them, and it's overcomplicated the languages and fragmented the codebases.

Example, if you ask ten Scala developers to solve a problem, you'll get ten different solutions. That number drops quickly for less feature-rich and more opinionated languages like Go.


I agree with that and Scala example, but also languages diseased by not evolving and not allowing new widely-accepted features. I wonder what would happen with Go if they never changed their mind and kept it without generics?

My point is not about bringing all features other languages have (its just not possible unless its a lisp), but rather creating a new language and not understanding how vital something like generics is for general purpose programming. That is an orange flag for me.


> I wonder what would happen with Go if they never changed their mind and kept it without generics?

Change their mind? What do you mean? Go always maintained it would get them, once the right design was found – which was echoed by Ian Lance Taylor actually working on them even before the first public release. He alone has, what, 8 different failed proposals?

The problem was always, quite explicitly, that nobody within the Go team had the full expertise necessary to create something that wasn't going to be a nightmare later. As you may recall, once they finally got budget approval to hire an outside domain expert, the necessary progress was finally made.

Being an open source project, you'd think the armchair experts on HN would have stepped in and filled in that gap, but I suppose it is always easier to talk big than to act.


> The problem was always, quite explicitly, that nobody within the Go team had the full expertise necessary to create something that wasn't going to be a nightmare later. As you may recall, once they finally got budget approval to hire an outside domain expert, the necessary progress was finally made.

This is a very interesting part and looks like you know about what happened. I wonder how come Go team had many super talented experts (Pike and Thompson for example) with a "power" of Google behind them and generics were an issue at all, while for example Crystal being a very similar language with native code generation, similar concurrency model and no big tech behind it managed to pull it off?

I've read some comments of devs who used both and they say Crystal is just plainly better. This just doesn't make sense to me, the biggest tech company on the planet should create a language that is head above everything else, but ended up being just good.


Nope, it's the same. It's one of the things I value about the language and project.


Well, Go has generics now and you can do quite a few tricks with errors. In the end error handling logic is up to developer.

UPD: thankfully Go does not try to bring in every "feature" possible. Not without consideration at least.


No, that attitude is core to the design of Go and one of the key reasons people pick it for projects.

Generics were eventually added. But not until they thought through very carefully performance and compilation time implications.


And this is a perfectly reasonable approach. Frankly, the cost/benefit ratio of delving into another language is most often not appealing.

As a suggestion, you could have delved more into the "hammer" metaphor, mentioning that a hammer is a flexible tool: nail planks, remove nails, smash things and even as a defensive weapon! You shouldn't misuse it for drilling walls, but that is outside the required scope of your work etc.

But in the end it's a very personal post, and we typically crave here for universality and judge posts up high from a meta-perspective, haha. Often neglecting that we were not actually the intended audience.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: