8 ms·
That's why I love Go so much. You want to write a very clever library using elegant abstraction and generics to have a cool innovative interface to solve your
by RandomThoughts3 2y ago
That's why I love Go so much.
You want to write a very clever library using elegant abstraction and generics to have a cool innovative interface to solve your problem? Tough luck, you can't. So instead, you will just have to write a bog standard implementation with for-loops and good old functions which you will have to copy and tweak as needed where you really need something more complicated. It will work perfectly fine and end up being very readable for you and for the other persons reading your code.
Go is basically anti-Haskell. It forces you to be less clever and that's great.
- GaryNumanVevo 2y agoTake a look at a JSON parser or ORM written in Go. It's god awful the things they have to do to work around Go's type system. The average developer won't see these things, they're typically just writing glue code between Go's great stdlib (which also contains wild things if you take a look) and other 3rd party dependencies.
- lpapez 2y ago> The average developer won't see these things, they're typically just writing glue code between Go's great stdlib (which also contains wild things if you take a look) and other 3rd party dependencies. This is what most of us are doing every day, and exactly what Go excels at.
- kamov 2y agoSum types allow for more robust modeling of the API boundary in libraries, so in fact having a better type system is desirable even when "just gluing libraries", because it can make incorrect program states physically unrepresentable.
- mplewis 2y agoSum types are great – but Go manages to be unreasonably effective even in their absence.
- GaryNumanVevo 2y ago> unreasonably effective I'm really tired of this PR speak when it comes to programming languages. Why / how is it unreasonably effective? More effective than what?
- kerkeslager 2y agoIf you want to progress your career you'll need to take on hard problems at some point. Go isn't particularly unique in excelling at easy problems.
- RandomThoughts3 2y agoGo doesn't excel at easy problems. Go is fine at pretty much everything. Do you think Kubernetes is an easy problem? The thing is just that Go is very opiniated in its feature set. That's you see people here writing about complex projects using "wild" or even "god awful" things, and lament the inability to properly map API boundaries in the language. The truth is obviously that all of these is not particularly wild. It's just things that the commenter considers inelegant but is perfectly able to follow which is Go strength and why it's so code. Want it or not, you will have to write code that someone else can follow. Don't get me wrong, I'm not going to pretend that Go is in anyway perfect or has the correct feature in as much as that exists. I probably enjoyed writing Ocaml more. But in practice, for a large scale project where collaboration is important, using Go is an awesome experience.
- GaryNumanVevo 2y agoGo is "opinionated" because it's designed to be simple rather than complete. - Why are lower cased symbols not exported? Because it would be too complicated to add private / public keywords. - Why isn't there exception handling? It's too complicated. It's simpler to just have everyone manually handle exception flow. - Why isn't there an optional type? It's too complicated. Just use a nil pointer and or default values. - Why aren't there sets or other rich datatypes in the stdlib? It's too complicated. Now go and write it yourself or download a microlibrary. - Why are there no nil pointer protections? It's too complicated. It's very easy to buy into the Golang PR and say "well it's just opinionated" as opposed to calling it "simplistic" or "incomplete". It's an okay language, I've written a lot of complicated stuff in it over the last 6 or so years, including a distributed KV database. Eventually you WILL hit the limits of "opinionated" design.
- kerkeslager 2y ago> Do you think Kubernetes is an easy problem? Kubernetes is an easy problem made hard by doing a bunch of things that don't need to be done. I've used small bash scripts to deploy software for most of my freelance career, and the few times I've been forced to use a containerization tool, it has been far more difficult, for no discernible benefit. > The thing is just that Go is very opiniated in its feature set. That's you see people here writing about complex projects using "wild" or even "god awful" things, and lament the inability to properly map API boundaries in the language. The problem isn't that Go is opinionated--I often wish Python was more opinionated. The problem is that Go started off with the wrong opinion on generics, and took two iterations (first casts, then `go generate`) to arrive at generics, resulting in a system that isn't opinionated on this issue, because all three ways work for reverse compatibility. And this is a) a very important issue to be opinionated on, and b) extremely forseeable given the languages that came before. > The truth is obviously that all of these is not particularly wild. It's just things that the commenter considers inelegant but is perfectly able to follow which is Go strength and why it's so code. Want it or not, you will have to write code that someone else can follow. The lack of abstractions means it's easy to follow on the line by line level, but that falls apart as context grows. Lines in more powerful languages are harder to follow because they do more. If you want to do the same amount of work in Go, you have to write more lines of code. You're going to be implementing the same abstractions ultimately, but because you're writing it custom you're going to do it a little differently every time. As a result, any few lines of code in Go is easy to understand, but the big picture is much harder to understand, because you're caught up in minutia which is slightly different every time instead of using a standard abstraction. EDIT: There's no way the first person who downvoted this had time to read it.
- pjmlp 2y agoAnd yet they had to reach out to Haskell folks to fix their generics story.
- therealdrag0 2y agoFor loops? Dang that’s some clever syntax you have there. Personally I prefer a big standard while loop. /s
- Aeolun 2y ago> It will work perfectly fine and end up being very readable for you and for the other persons reading your code. And make all future work both 3 times simpler, and take 3 times as long. I suppose there’s situations in which this is great, but I’m partial to requiring more. I’ll admit that hasn’t worked out very well for me unless I’m working my myself though.
- theshrike79 2y agoI'll take verbose and simple code over terse trickery every day. People who disagree have never had to wake up at 3 in the morning to fix a critical production issue in someone else's code. And that someone else really loved "elegant and terse" code. It's not fun to grok your brain around weird language trickery when you're half-awake and in a hurry to fix stuff before the customers wake up.
- kamov 2y agoI personally think that writing so called "terse, clever" (misnomer) code, is not an issue with the language, rather the user. Do we really want to have worse tools, just because some people are writing bad code? Clearly it's an issue with the software engineering process rather than language itself. A good language should allow a skilled user to write code as clear as day, while properly modelling the problem domain and making incorrect states logically unrepresentable. We have a tool for that, type system and a compiler.
- RandomThoughts3 2y ago> Do we really want to have worse tools, just because some people are writing bad code? People tend to write bad code. It's a fact of life. Tools forcing people who write bad code to write better code can't be worse tools by definition. They are better tools.
- kamov 2y agoThe fundamental issue is that humans contrary to machines will never know for sure whether whatever they do write is in fact correct code. One can think they are writing good and readable code, but that doesn't mean anything if the code is incorrect. And if you write lots of boilerplate that means more possible bugs. That's also why no one sane writes assembly (or increasingly these days C) unless they have to. We generally prefer more complex languages which put a constraint on the amount of possible bugs.
- kerkeslager 2y ago"Simple" is a cop-out word. Things can be simple along a lot of vectors. The vector you've chosen seems to be "does less for you" which taken ad absurdum would have you using assembly. Go does have elegant abstractions, and they aren't the simplest along this vector, nor would anyone want them to be. Coroutines, for example, are actually quite conceptually complicated in some ways. I prefer "understandable"--it appears this is what you're trying to get when you say "simple", but I think you're drastically overselling the understandability of go code. Sure, you understand any given line easily (what you described as "readable"), but you're not usually trying to understand one line of code. Since go's sparse feature set provides few effective tools for chunking[1] your mental model of the program, complex functionality ends up being in too large of chunks to be understood easily. This problem gets worse as programs grow in size. Another poster mentioned that they start running into problems and wishing they had explicit types with Python programs over 10K LOC, which approximately matches my experience. But comparing to go, you've got to realize that 10K LOC of Python does a whole lot more than 10K LOC of Go; you'd have to write a lot more Go to achieve the same functionality because of all the boilerplate. That's not necessarily a downside because that boilerplate is giving you benefits, and I don't think entering your code into the computer is the limiting factor in development speed. But it does mean that a fair comparison of equally-complex programs is going to be a lot more lines of Go than Python, i.e. a fair comparison of might be 10K LOC of Python vs 50K LOC of Go. I say "might be" because I don't know what the numbers would be exactly. How many people have written or worked on projects in Go of that complexity? How many people have written or worked on programs of equivalent complexity in other languages to compare? I'm seeing people discuss how easy it is to start a project in Go, but nobody is talking about how easy it is to maintain 50K LOC of Go. I've worked on projects of >200K LOC in Python, and the possibly-equivalent >500K LOC in C#. I think the C# was easier to work with, but that's largely because the 200K lines of Python made heavy use of monkey patching, and I've worked in smaller C# codebases that made heavy use of dependency injection to similar detriment. I'm honestly not sure which feels more maintainable to me, given a certain level of discipline to not use certain misfeatures. I haven't written as much Go, and I wouldn't, because the features of C# which make it viable for projects of this complexity simply aren't present, and unlike Python, Go doesn't provide good alternatives. I suspect the reason we don't have many people talking about this is that not many projects have grown to this complexity, and when they do these problems will become apparent. The real weak point is Go's type system--it's genuinely terrible, because the features that came standard in other modern statically-typed languages decades before Go was invented were bolted onto Go after the fact. Gophers initially claimed they didn't need generics for a few years. As a result you've got conflicting systems developed before `go generate` (using casts), after `go generate` but before generics (using go generate), and after generics (using generics). It's telling that you seemingly reject generics ("clever library using elegant abstraction and generics") even though go has them now. Attacking Haskell is sort of a straw man--so far I haven't seen anyone in this thread propose Haskell as a go alternative. I think we agree Haskell is far too dogmatic about its abstractions when it's impractical to be used as a general-purpose language (because I don't think it's intended as a general-purpose language). [1] https://en.wikipedia.org/wiki/Chunking_(psychology) https://en.wikipedia.org/wiki/Chunking_(psychology)
- eweise 2y agoYou can write abstractions in Go and it has generics. Its just that the abstraction aren't as good so you end up with harder to read code.
- omeid2 2y agoYou're holding the phone wrong. Kubernetes does the same. So does Docker, and just about every Go project. You don't understand Go.
- eweise 2y agoI've been coding full time in it on a large team for four years now. If Go is this difficult to comprehend, then maybe its not the simple language it claims to be.
- omeid2 2y agoThat is the joke. Go conflates simple with primitive, so you end-up building things like Computer Science has just emerged and it is the 50s with some syntax sugar, an decent concurrency to be fair.
- tome 2y ago> Go is basically anti-Haskell. It forces you to be less clever and that's great. This is a bit of tangent, but I think it's worth pointing out the value in Haskell (at least as far as I see it) is not that it allows you to write "clever" code, but that it allows you to define precise interfaces. I suspect some people like Haskell because they can be "clever", and I suspect to be able to define precise interfaces you have to allow some degree of cleverness (because you need things like higher order functions and higher kinded types), but cleverness is not, in itself, the value of Haskell.