[HN Gopher] Twelve Years of Go
       ___________________________________________________________________
        
       Twelve Years of Go
        
       Author : mfrw
       Score  : 169 points
       Date   : 2021-11-10 16:15 UTC (6 hours ago)
        
 (HTM) web link (go.dev)
 (TXT) w3m dump (go.dev)
        
       | ianopolous wrote:
       | Things I love about Go:
       | 
       | 1) ridiculously easy built-in cross-compilation
       | 
       | 2) structs (compact memory layout and usage)
       | 
       | 3) easily having millions of cheap threads aka go-routines
       | 
       | 4) modern standard library for things like cryptography
       | 
       | Things I hate about Go:
       | 
       | 1) plugins (very painful to get working and not even cross
       | platform - e.g. Windows)
       | 
       | 2) duck typing make refactoring and understanding new codebases
       | error prone
       | 
       | 3) no ternary operators (the verbosity!)
       | 
       | 4) missing basic collections (like set, various queues etc.)
       | 
       | 5) lack of built-in memory use limits
       | 
       | 6) errors and error handling (just give me a stack trace for
       | pete's sake)
        
       | zabil wrote:
       | Congrats for turning 12! Starting using golang 6 years ago and
       | it's been so easy maintaining our projects and upgrading to the
       | latest versions. Cheers to the team.
        
       | grey-area wrote:
       | Coming from other languages, the most interesting thing about Go
       | for me (in my limited experience of a few other languages) was
       | all those things they left out:
       | 
       | No inheritance - no more digging through the massive world-tree
       | of objects to find the code that actually does things.
       | 
       | No churn - I have not seen a Go update break my code in about 8
       | years of use.
       | 
       | No complexity - I like the culture of simplicity and eschewing
       | dependencies in favour of writing the minimum code required.
       | 
       | No dynamic libraries - deployment is easier and apps more stable
       | 
       | No declared interfaces - they are defined at the point of use,
       | not declared elsewhere
       | 
       | No header files - why C++, why?
       | 
       | No implicit type conversion - of the kind that plagues JS (see
       | WAT), this rarely makes it more verbose.
       | 
       | There are of course a few gnarly corners - nils, errors, panics,
       | struct tags are not very satisfactory IMO at the moment.
       | 
       | There are also lots of great positive things about it - the GC,
       | tooling, fast compiler, stdlib and docs are a great example for
       | other languages IMO.
       | 
       | I'll be really interested to see where they take it next, while
       | hopefully keeping the culture that has made it so pleasant to
       | use. Thanks to everyone working on Go from me, and here's to
       | another 12 years of Go.
        
         | throwaway894345 wrote:
         | I'll add:
         | 
         | * No DSLs for declaring dependencies or otherwise scripting the
         | build system.
         | 
         | * Excellent standard library
         | 
         | * Incredible ecosystem
        
           | grey-area wrote:
           | They do have a few little DSLs, which I dislike: struct tags
           | (optional, I prefer to avoid), magic comments which provide
           | build directives (this seems icky to me, but avoids breaking
           | Go1 promises I guess).
           | 
           | https://dave.cheney.net/2018/01/08/gos-hidden-pragmas
        
             | throwaway894345 wrote:
             | I don't want to be too contrarian, but I'm not aware of any
             | library which uses struct tags to encode anything that
             | anyone might call a DSL. At most, they're used for key-
             | value pairs (e.g., `foo:bar`), which is pretty easy to get
             | one's head around. I don't use build directives and ideally
             | we wouldn't need them, but most (all?) mainstream compiled
             | languages have them. Maybe the complaint is that they don't
             | get their own dedicated syntax, in which case I don't see
             | the issue beyond _" in $MY_PREFERED_LANG, build directives
             | have their own syntax, and that's how I like it!"_.
             | 
             | In all cases, these issues seem positively trivial compared
             | to "you can't parse JSON or send an HTTP request until you
             | learn some DSL or cargo-cult someone else's build file".
        
               | jerf wrote:
               | "I'm not aware of any library which uses struct tags to
               | encode anything that anyone might call a DSL."
               | 
               | There's a couple of struct validation libraries that got
               | IMHO a bit overexcited with what you can jam in a struct
               | tag and then interpret, but they don't seem to have
               | gotten very popular, so it doesn't factor into the
               | language much.
        
               | grey-area wrote:
               | Have a look at some of the bugs related to struct tags
               | (420 open ones) - they can control marshalling and have
               | lots of little directives in them like
               | omitempty,attr,-,set plus they combine too (for
               | xml,json,asn1 etc) and you can stuff your own little
               | language in too if you want, the possibilities are
               | endless! They are a set of limited yet unvalidated
               | translation DSLs stuffed into a string.
               | 
               | https://github.com/golang/go/search?p=4&q=struct+tags&typ
               | e=i...
               | 
               | Personally I think the language would be better without
               | them, but it's too late now.
               | 
               | Re build directives - the complaint is they are comments
               | which _do things_ and change code /compilation, the
               | syntax I don't care about, but I do care that they've
               | abused comments to do this.
               | 
               | I agree, these problems are pretty trivial, I don't lose
               | sleep over them.
        
         | kisstheblade wrote:
         | "No inheritance - no more digging through the massive world-
         | tree of objects to find the code that actually does things."
         | 
         | You still have interface methods? I had problems navigating a
         | new codebase and find the places "actually doing things". Some
         | object was passed in somewhere which mysteriously implemented a
         | one method interface defined on the spot in the other go file.
         | I.e. the implementation had no relation to the interface which
         | was obvious without a lot of searching and finding the right
         | implementation.
         | 
         | Also passing in functions (callbacks?) all over the place is a
         | little messy at least for a newbie. It was hard to find where
         | the functions where called and at what point and how the
         | program flowed.
         | 
         | (this is hard to explain but maybe somebody gets the point...)
         | 
         | edit: somebody else touched on what I also meant: " duck typing
         | make refactoring and understanding new codebases error prone"
         | 
         | Also the modules and dependencies management surely is a joke?
         | Pulling stuff from github willy-nilly? Quite bad in any case
         | when compared to maven where you have a local repository with
         | all the dependencies (so they don't change or disappear from
         | the internet so that you can actually build your software 5
         | years later, exactly in the same way)
        
           | mdaniel wrote:
           | Heh, that's amazing, we posted within 30 seconds of each
           | other with basically the same observation. Great minds, and
           | all that :-)
        
           | grey-area wrote:
           | There are certainly ways to write confusing code in Go too,
           | no inheritance is just one cause of confusion subtracted.
           | 
           | IMO interfaces are best used sparingly and in a minimalist
           | way like io.Reader (but I prefer them to Java interfaces and
           | have not found them confusing nor felt compelled to find all
           | concrete types conforming), callbacks are best avoided if
           | possible, and yes dependency management has only recently
           | improved.
           | 
           | https://pkg.go.dev/io#Reader
        
           | ohCh6zos wrote:
           | I really do think Go has a discovery problem. Function
           | signatures don't tell you hardly anything, does this need
           | something deferred, what types does it implement, etc.
        
         | mdaniel wrote:
         | > No inheritance - no more digging through the massive world-
         | tree of objects to find the code that actually does things.
         | 
         | That's not 100% accurate; as a concrete example, tell me which
         | files (to say nothing of the actual downstream types!) contain
         | the implementations of this interface method:
         | https://github.com/kubecost/cost-model/blob/v1.88.0/pkg/clou...
         | _(err, without using github 's fancy new SourceGraph-lite
         | integration, of course, that'd be cheating)_
         | 
         | I find the sibling "No declared interfaces - they are defined
         | at the point of use, not declared elsewhere" similarly
         | suspicious, but suspect we're having a nomenclature mismatch
        
           | grey-area wrote:
           | > That's not 100% accurate; as a concrete example, contain
           | the implementations of this interface method
           | 
           | But why? I've often wanted to know what a method does in Ruby
           | and have had to resort to .method(:x).source_location because
           | it is so dynamic only the compiler knows once it has finished
           | running it. I've never _had to_ find all the places that
           | conform to an interface in Go (a very different question) or
           | Java, because that 's what an interface is for, so that you
           | don't need to know, and new people can come along and conform
           | too: your interest should be limited to what they can do,
           | which the interface tells you already. Maybe this is a
           | problem in getting to know a large complex codebase I guess?
           | I've never encountered it in the real world.
           | 
           | The second point is linked - interfaces are used the way you
           | describe in a few other languages, Java among them, (find me
           | all the implementors of x), but not in Go, the whole point is
           | you have no idea who the implementors of an interface are,
           | new ones will arrive, and that's ok.
           | 
           | It's certainly possible to write bad, confusing and
           | enterprise Java flavoured code in Go, but the lack of
           | inheritance at least does away with a whole bag of hurts
           | related to overabstraction.
        
       | jstx1 wrote:
       | I've only picked up Go recently and I must say that the beginner
       | experience is superb. Way easier to get started, learn new
       | concepts and put them in use compared to some other languages.
        
         | 0x008 wrote:
         | can you recommend any video lectures?
        
           | squegles wrote:
           | I suggest running through each example at
           | https://gobyexample.com
           | 
           | This personally helped me build a good foundation on Golang.
        
           | JimiofEden wrote:
           | So it's not a video lecture on Go specifically, but I first
           | started learning itbecause I saw how it looked and how fast
           | it ran while watching a Dynamic Programming series that
           | happened to use Go for its implementations.
           | 
           | https://www.youtube.com/watch?v=jTjRGe0wRvI&list=PLVrpF4r7WI.
           | ..
           | 
           | From there, I started reading about it more seriously here:
           | https://golangbot.com/learn-golang-series/
           | 
           | And I've been using it and loving it ever since. There are
           | one or two things that trip me up (slice manipulation can
           | sometimes get me if I'm not paying close attention to my
           | capacity and just pointing around, rather than copying) But
           | for the most part, it's a fairly elegant language, and
           | amazingly fast! For me, it's also been incredibly intuitive
           | start working on asynchronous features.
           | 
           | The new inclusion of Generics is just icing on the cake.
        
       | geodel wrote:
       | Plenty of great initiatives listed here. Integrated Supply chain
       | security tooling is going to be increasingly important. For Java
       | we use third party tools to identify vulnerabilities in
       | libraries.
        
       | behnamoh wrote:
       | You mean, it all started twelve years a-go :)
        
         | crecker wrote:
         | -.-
        
       | Shadonototra wrote:
       | Keeping things simple, fast while maintaining super high
       | iteration time is the way to go for success
       | 
       | A lot to learn from this success story
        
       | nedsma wrote:
       | Go is great! Looking forward to another 12. Hear hear!
        
       | shaan7 wrote:
       | I can attest to the fact that programming in Go taught me a lot
       | of good engineering. I certainly find myself better trained at
       | handling errors, for example.
       | 
       | However, I always feel exhausted when implementing real-world
       | systems with Go given the lack of $things (that everyone feels is
       | a virtue). Over time I realized that a lot of people just aren't
       | as lazy (or scared of breaking things) as I am - they find it
       | easier to copy code dozens of times and then fixing them all in
       | one go using their ninja refactoring skills. Just a different
       | kind of tradeoff, at the end.
       | 
       | So given how laborious it is to make anything more than simple
       | programs (because of the amount of copy-paste-driven-development
       | required), I generally avoid Go unless I'm writing a webservice.
       | 
       | For me Go's virtues are static typing and wide variety of
       | community packages to do things. The whole "oh not having
       | features is a feature" thing is just an opinion for the sake of
       | having an opinion. otoh, I damn excited to have generics support
       | soon finally :)
        
         | jerf wrote:
         | If you are or your coworkers are constantly copying and pasting
         | code, stop, and think a bit more. I do a _lot_ of Go
         | development and almost never copy and paste anything anywhere.
         | (And even in those cases it 's usually justified. I just a few
         | minutes ago copied and pasted a big struct... but it's because
         | the first struct was defining a JSON message, and the second
         | struct was defining a very similar, but not quite identical,
         | JSON message in another file. This doesn't seem like a big deal
         | to me, because it's defining a separate external data format
         | and while they are superficially similar they are _not_ the
         | same and really shouldn 't share code.)
         | 
         | Either you're not using the tools Go has to their full effect,
         | or, possibly, you shouldn't have chosen Go. But I make that
         | last concession not because it probably fits your case, but
         | because it is technically true. (In particular, don't take Go
         | for heavy math code where you need a type system that is ready
         | for lots of mathematics.) But it's probably not applicable.
         | 
         | You should not be copying and pasting all the time.
         | 
         | There are several communities; I happen to hang out on the
         | reddit /r/golang. If you've got something that you'd like to
         | see how to refactor to not be copy and paste, consider posting
         | a question there (ideally with a running version in the
         | playground of whatever you're asking about). It is true that
         | not everything can be improved, but most things can.
        
       | abdulwajid31 wrote:
       | superb
        
       | princevegeta89 wrote:
       | Would you say Go is suitable for web services and apps? I was
       | trying to compare it with a rapid development framework like
       | Rails but felt Go Web Frameworks aren't as mature and ready like
       | Rails. Any insight would be appreciated, thanks!
        
         | machiaweliczny wrote:
         | I suggest going Rails/Next.js/Django and then extracting Go
         | microservices if you ever need it.
        
           | princevegeta89 wrote:
           | This seems to be a really valid point
        
         | pphysch wrote:
         | Definitely suitable. Depends if you want to work within a
         | framework or not.
         | 
         | If you want a framework, use Rails/Django/Node as they are very
         | mature. Huge plugin ecosystems, great for prototyping non-
         | trivial features like authn, because a plugin certainly exists
         | for it.
         | 
         | If you want more control (fewer dependencies), roll everything
         | yourself with Go. The built-in libraries are fantastic, you can
         | spin up a CRUD app without any external libraries. There are
         | also great third-party libraries, but I would stay away from
         | framework-y stuff like GORM.
        
           | princevegeta89 wrote:
           | Thanks. How about a framework which has all these things
           | stitched together already? For example, a good templating
           | engine and an ORM that supports DB migrations out of the box?
           | Do we have one for Go?
        
             | pphysch wrote:
             | GORM (https://gorm.io/index.html) has auto migrations.
             | 
             | But it is still a framework, which means it is making a lot
             | of decisions for you and forcing you to learn its own way
             | of doing things. Ultimately it is a relatively thin layer
             | over builtin Go libraries like `html/template`, `net/http`,
             | `database/sql`; generally speaking, the Go philosophy is to
             | build systems yourself from these components and therefore
             | keep the architecture simple, focused, and maintainable.
             | 
             | Unless you are stuck with Go for a good reason, if you want
             | a framework use one of the industry standard ones mentioned
             | previously.
        
         | petepete wrote:
         | I'd say that's not where its strength lies, but it's certainly
         | possible.
         | 
         | Building an API backend for a single page app though,
         | absolutely.
        
         | handrous wrote:
         | AFAIK _nothing_ has the plug-n-play library availability of
         | Rails, as far as things that are highly relevant to stitching
         | together  "web apps". Not even Django, which may be its closest
         | competitor. That single aspect of it is so good that even
         | though I hate Rails (but I think Ruby's alright--go figure)
         | it's hard to recommend against it for some projects.
        
           | nkozyra wrote:
           | True, but that's comparing a (light) framework to a language
           | itself.
           | 
           | Go is great for web services, it's the first thing I reach
           | for.
        
         | grey-area wrote:
         | Yes.
         | 
         | I've used Rails extensively before writing some larger sites in
         | Go. Quick comparison of Go vs Rails:
         | 
         | Pros: More performance, multi-threaded extremely capable web
         | server built-in, culture of simplicity and low-dependencies, no
         | breaking changes, goroutines, ideal for small services, static
         | binaries (all deps included) so no need for rbenv, docker etc
         | etc, no included JS, great stdlib (far better than Ruby's IMO),
         | NO INHERITANCE.
         | 
         | Cons: No standard structure others are familiar with, you'll
         | need to find/write code for things like migrations, auth,
         | rendering views, skeleton code generation.
         | 
         | For things you need to find/write this may seem intimidating
         | but it's an opportunity to explore the bits you liked about
         | rails and jettison the bits you didn't like or need, and the
         | stdlib includes a lot of what you need at a low level (e.g.
         | html templating, crypto libs). I cannot emphasise the
         | importance of no breaking changes, it's so refreshing compared
         | to other language ecosystems like Ruby or JS.
         | 
         | Overall I'm really happy with Go for web apps and would choose
         | it again in a heartbeat, particularly over Ruby and Rails
         | (which I also like, but has performance issues and cultural
         | issues IMO).
        
         | dhagz wrote:
         | I only use Go for two things: CLIs and web services. There are
         | a lot of frameworks out there to help you develop web services
         | in Go, but what really impresses me is that you don't really
         | need them - you can get surprisingly far just using the
         | standard library.
        
         | lawn wrote:
         | You should also consider Elixir with Phoenix, as it's a
         | comparable experience with Rails (although not as many
         | libraries) while giving you much better performance. And
         | Phoenix LiveView is just an incredible productivity boost,
         | there's nothing quite like it.
        
           | princevegeta89 wrote:
           | Have been working a lot with Elixir lately. It's just that I
           | wanted to see where Go stands
        
       | Zababa wrote:
       | Congratulations on those 12 years! Generics and supply-chain
       | security seem like a very nice focus for the next year. That's
       | one point where JavaScript seems to be stagnating a lot, so I'm
       | glad other people are taking it seriously.
        
       | qqumut wrote:
       | I prefer Rust.
        
         | askonomm wrote:
         | Then why are you commenting on a thread about Go? Just to be
         | dick?
        
           | steeve wrote:
           | Unfortunately this situation happens way too often.
        
         | philosopher1234 wrote:
         | Impressive. This sums up Hacker News in 3 words.
        
       | jrockway wrote:
       | A good twelve years. Go really changed the way I think about
       | programming. I used to be excited by programming language
       | features instead of what problem I was actually trying to solve
       | with programming. I'd spend hours condensing 10 lines of
       | perfectly working code into 1 line of the most concise text
       | possible; huffman encoded better than even gzip could imagine.
       | And I'd feel great about it. I'd imagine people reading it and
       | thinking "wow, there's no way I'll ever be as smart as jrockway,
       | I should nominate him for Extreme Excellence And Awesomeness
       | award!" Sadly, there is no such thing. Go taught me that it's
       | just structs, for loops, and if statements, and if you want
       | someone to be impressed, they should be impressed by what the
       | program does for them, not what language features you used to
       | implement it.
       | 
       | It has also ruined other programming languages for me. "go get"
       | doesn't print 30 lines of text telling me that a new minor
       | version of "go get" is available, and that I should stop what I'm
       | doing, rm -rf node_modules, upgrade it, and then resume what I'm
       | doing. It just pauses for a bit, and then I have the library. (I
       | also love reading about the node community's push to make
       | installing libraries not run arbitrary code on your machine.
       | Yeah, I've been doing that for years with Go. It's great. I can
       | use a library and it can't print a "hire me!!!" ad at install
       | time. What an innovation!)
       | 
       | I also remember struggling for years with not being able to run
       | other people's software. There was an RPM package, but not a
       | Debian package, so I have to build it from source. ./configure;
       | make; oh no, the c compiler I have can't compile this code. With
       | Go, you can just emit a binary for every supported platform dump
       | the binary somewhere, and everyone in the world can download it
       | and run it. No installing packages, no finding the right version
       | of Go (that doesn't exist in your Linux distribution because they
       | never ship up to date versions of programming languages). Just
       | software, running, forever.
       | 
       | It's really good stuff. Go is the tool that lets me make
       | software, and not worry about bullshit. And that's revolutionary,
       | even 12 years later.
        
         | throwaway894345 wrote:
         | Agreed. It still surprises me that so many other languages fail
         | at the fundamentals (minimal learning curve, static binaries,
         | fast builds, reproducible dependency management, great tooling,
         | great stdlib + ecosystem, etc) and yet many devotees of those
         | languages have positively hyperventilated about Go's error
         | handling and type system for 12 years. Go is finally getting
         | generics and I'm sort of cautiously excited about it (like I
         | was when Apple added the TouchBar to MacBook Pros), but any net
         | benefit is going to be positively negligible in comparison to
         | the degree in which Go raised the bar on the fundamentals.
        
           | kaba0 wrote:
           | I'm not arguing that there are languages where the state of
           | tooling is bad to say the least, but how did Go raise the bar
           | compared to something like Java or C#, the actual "blue-
           | collar" languages?
        
             | throwaway894345 wrote:
             | There's a lot to like about Java and C#, but here are a few
             | things that Go improved upon that spring to mind. Note that
             | in some cases, Java and C# may have caught up in the
             | interim. Note also that some things (e.g., low-latency GC)
             | understandably weren't available from day 0 in Go, but
             | followed quickly:
             | 
             | * Static binaries by default
             | 
             | * Single, straightforward build system (no DSLs)
             | 
             | * Single, ubiquitous code formatter
             | 
             | * Minimal learning curve
             | 
             | * Zero-work package publishing
             | 
             | * Zero-work documentation generation and publication
             | 
             | * Testing framework out of the box
             | 
             | * Production-grade HTTP server out of the box
             | 
             | * Low latency GC out of the box
             | 
             | More generally, C# and Java have always seemed to have a
             | philosophy of "make everything as abstract and configurable
             | as possible, and make the user understand every
             | configuration option in order to do anything (overwhelm the
             | user with configuration)". Granted, I haven't used C# or
             | Java seriously since Go was open sourced, so it's possible
             | that these are among the things that improved in C# and
             | Java following Go's release.
        
         | grumpyprole wrote:
         | I'm happy to entertain the idea that Go is a sweet spot for
         | many, but please let's not pretend language features are
         | universally bad. After all, Go benefits enormously from a
         | garbage collector and its language-level support for Hoare's
         | CSP. Two very important features that e.g C and C++ do not have
         | (they do however have structs, for loops and if statements).
         | 
         | IMHO Go certainly chose wisely when it left out many OOP
         | features of questionable value. And perhaps in doing so, it
         | avoided the whole OOP culture, which has produced a lot of
         | over-complicated software and tools. The culture of simplicity
         | in Go is a really good thing and worth defending. However, we
         | should be open to the idea that one or more additional language
         | features might help to further this goal.
        
         | leoc wrote:
         | If you think there's some virtue in writing verbose and
         | inexpressive imperative code, what does Go provide in that
         | department that you couldn't have got from Java 1.44?
        
           | jerf wrote:
           | I have often thought that if you could travel back in time
           | and make Java's interfaces work like Go, there would be no Go
           | today. The first-order effects of that change may not seem
           | like much, but the second-order effects of that change is
           | profound. In Java, interfaces must temporally precede their
           | implementations; in Go they don't have to. This turns out to
           | be _huge_ in practice. It turns out that huge swathes of all
           | that boilerplate and frameworkitis that Java is so well known
           | for are just trying to get around the consequences of that
           | mistake, because _all_ the interface-based structure has to
           | be laid down in advance.
           | 
           | It isn't the only difference between the two, but I think it
           | would have consumed enough of the oxygen of the niche Go is
           | currently in that Go might never have been born.
           | 
           | In practice, I find Go to be just slightly harder than
           | working with dynamically typed languages, rather than a huge
           | step, and the benefits I get in return make me prefer it for
           | almost any task above 200-ish lines. I definitely can not say
           | the same about Java, because of this difference and the
           | second-order effects it has on the entire ecosystem.
           | 
           | It is still completely practical to create a production-level
           | Go project by just cracking open a text editor and typing
           | "package main" into your editor and typing away. I get the
           | impression most people would not consider that a practical
           | way to start a production-level Java project.
        
             | kaba0 wrote:
             | Java's nominal typing is both better and worse at the same
             | time - but go is not novel in that area, plenty of similar
             | languages existed before as well, so I don't think having
             | it contributed to go's success.
             | 
             | As for your last paragraph, I feel like we often mean
             | something different between a production-level go and java
             | project. Non-IDE java development is entirely possible, but
             | I think a prod project usually means something much larger
             | than it does in case of go.
        
           | Andys wrote:
           | It is lighter and faster and requires no runtime.
        
             | kaba0 wrote:
             | Than Java 1.14? Yes. Lighter is true of current Javas as
             | well, but faster is dependent on the program. Go can often
             | prevent garbage from being generated in the first place,
             | but when creating garbage is a must, Java will happily
             | handle heaps up to a terabyte in size, and its GCs are
             | simply the state of the art.
             | 
             | Also, Go most definitely has a runtime, what runs the GC
             | otherwise?
        
               | Andys wrote:
               | But its also faster to compile and use as a developer.
               | And by runtime I mean there's no JVM. If you're used to
               | Java you should probably just stick with it, but using Go
               | is a huge relief to me.
        
           | ignoramous wrote:
           | Well, at some level you could say Go (pre 1.18) is Java 1.44
           | but with _speed_ as a differentiator. Development speed,
           | build speed, deploy speed, and runtime speed.
           | 
           | If Russ Cox ever proposes to rename Go to Java _Script_ , I
           | guess no one would complain. ;)
        
           | grey-area wrote:
           | Epic troll, but there is life outside The Kingdom of Nouns.
        
           | Zababa wrote:
           | Not having to wrap your imperative code in classes is a big
           | plus.
        
           | initplus wrote:
           | Go is constantly being improved and refined compared to Java
           | 1.44, there is a strong community of third party packages,
           | you aren't shoehorned into the OOP box by basic language
           | design, you get green threads in the form of goroutines while
           | in Java land you are dealing with native threads & the issues
           | they involve (curiously just learned Java <1.3 actually did
           | use green threads, I suppose they were a casualty in the
           | efforts to improve performance), the Go stdlib is much leaner
           | but simultaneously much more useful compared to the Java 1.44
           | equivalent (even latest Java stdlib is missing basics like
           | JSON!), date/time handling is sane compared to pre-Java 8
           | equivalent, etc. etc.
        
             | kaba0 wrote:
             | Comparing a moving thing to a static one is quite
             | meaningless, but regarding third-party packages the JVM is
             | parallel only to the python and node ecosystems.
        
         | the_gipsy wrote:
         | > With Go, you can just emit a binary for every supported
         | platform dump the binary somewhere, and everyone in the world
         | can download it and run it.
         | 
         | Does this hold true? Don't you need to switch to musl or
         | something, to build a static binary?
        
           | mdaniel wrote:
           | I believe you may be thinking of `CGO_ENABLED=1` which causes
           | golang binaries to fail to run on musl distros
           | 
           | So yes, your comment is probably right, but I get the
           | impression the grandparent was a tiny bit tongue in cheek
           | anyway
        
         | tdeck wrote:
         | > I used to be excited by programming language features instead
         | of what problem I was actually trying to solve with
         | programming.
         | 
         | This happened to me too, without using Go. I think I just got
         | older.
        
           | throwaway894345 wrote:
           | The nice bit about Go is that this maturity is baked into the
           | philosophy and thus the language, the tooling, and the
           | ecosystem where it benefits even younger developers. For
           | example, your own hard-earned wisdom is great but it doesn't
           | automatically make your language's package manager (or any
           | other software you depend on, including libraries) better.
           | But when that kind of wisdom is _idiomatic_ , everything is
           | better even when it's built by more junior developers.
        
             | tdeck wrote:
             | Oh, I'm not necessarily suggesting that my lack of
             | curiosity about new language designs is a good thing. In
             | fact I think it's kind of a mixed bag. I'm only clarifying
             | because I don't want to seem to be implying something
             | negative about younger developers.
        
               | throwaway894345 wrote:
               | I didn't think you were implying anything about younger
               | developers, I was noting the rather significant
               | difference between "I've matured as a programmer" and
               | "maturity was baked into the language I use and its
               | idioms, tools, ecosystem, etc".
        
           | adamc wrote:
           | I came here to say that. I agree with your analysis.
        
         | new_stranger wrote:
         | > I'd spend hours condensing 10 lines of perfectly working code
         | into 1 line of the most concise text possible
         | 
         | Which is also the hardest part of convincing people to use Go
         | for me: "Why can't I just .map()/.filter()/.find()?" followed
         | closely by "Why do I always have to check for errors?"
         | 
         | What is odd to me is that while yes, my Go code is more verbose
         | than my node services - I always end up writing less Go for the
         | same thing.
        
           | initplus wrote:
           | I'm a huge go proponent, but I do think the lack of
           | map/filter/find etc. is a big downside to the language. I
           | know how to write for (if item == myItem...) or a for (if
           | item > max...) but it feels like a colossal waste of time
           | every single time I write one of these loops.
           | 
           | Go would benefit a lot more from some basic slice
           | manipulation tools compared to features like generics that
           | have actually made it into the language.
           | 
           | The error handling I don't find so frustrating - it's great
           | that it explicitly marks at the call site which functions can
           | potentially error. It's like a working version of an inverse
           | noexcept from C++. I do wish they would take a leaf out of
           | swifts book though, with the try keyword. In practice error
           | handling flow in my go programs is identical to using
           | exceptions, it would be nice to have some helpers to make
           | this default less verbose without losing the ability to
           | distinguish at the call site which calls are error-y.
        
             | grey-area wrote:
             | I imagine they'll add map/filter/find after generics are
             | in. It's pretty easy to define some slice types though
             | which include those in the meantime, type Slice []string
             | and add some functions then just use your new type for
             | collections.
        
           | fpoling wrote:
           | Most perceived verboseness of Go comes not from the language
           | or libraries but from the formater that does not allow to
           | compress 3 lines of the error check down to single
           | 
           | if err != nil { return err }
        
             | Zababa wrote:
             | > if err != nil { return err }
             | 
             | I'm far from a Go expert, but I feel like this line is a
             | bit pointless, especially if you write it a lot. At this
             | point, why not just not handle the error, or panic?
        
               | closeparen wrote:
               | The community strongly discourages panic.
        
               | ohCh6zos wrote:
               | A huge issue with Go is 'idiomatic' Go.
        
               | Zababa wrote:
               | I think a panic is still better than a chain of if err !=
               | nil { return err } that bubbles up and does nothing. Of
               | course the best solution would be proper error handling
               | but not everyone does that (and it's not always obvious
               | what to do).
        
               | merb wrote:
               | and most of the time you can't handle it anyway. I mean
               | consider you are having a database query and it fails
               | because the connection error'd (network split). what to
               | do know? restart the network switches and wait? of course
               | not in http you will just print a 5xx err and hope it
               | comes back. in go you need to bubble up these errors to
               | your middleware and handle it there.
        
             | throwaway894345 wrote:
             | If this is the case, I think the fault here lies with
             | flawed perception and not the formatter.
        
               | fpoling wrote:
               | The formater in many cases essentially doubles the number
               | of lines. That requires to scroll much more frequently
               | than with more compact formatting.
        
               | throwaway894345 wrote:
               | I understand, but I take issue with the implication that
               | compression makes code more readable.
        
             | pxue wrote:
             | Compressing this into 1 line provides absolutely nothing
             | for the reader, in fact, it absolutely takes away
             | reability.
        
               | The_Colonel wrote:
               | Readability absolutely suffers when almost everything you
               | see on your screen is boilerplate.
        
               | thatswrong0 wrote:
               | Seriously. I see so many functions in my code see that
               | consist of 1 line of thing I actually care about followed
               | by 3 lines of boilerplate if err not nil... over and over
               | again.
               | 
               | IMO if Go didn't have its tooling, no one would care
               | about it.
        
             | stouset wrote:
             | Worse,                   if res, err :=
             | actually_important_bits(...); err != nil {
             | return nil, err         }
             | 
             | The actually important bits are hidden in the middle of
             | line noise. In the "common case" where
             | `actually_important_bits` is just a simple function call
             | it's not necessarily as bad, but the problem is when you
             | have ten successive instances of this and _one_ is slightly
             | different. It 's impossible to notice the important
             | difference at a glance.
             | 
             | For an industry that is just starting to understand that
             | code is read hundreds of times more often than it's
             | written, golang fails at the few things we actually know
             | for certain about what makes it easier to understand code
             | at a glance.
        
           | jerf wrote:
           | My non-Go code is starting to look more like my Go code.
           | 
           | One of the things Go taught me is that I was not being as
           | careful about my errors as I should be. It can be argued that
           | exception-based handling provides you a nice baseline
           | default, but it makes it _way_ to easy when doing network or
           | system-type programming to thoughtlessly default to that,
           | when you need to be _thoughtfully_ defaulting to that.
           | 
           | With sufficient care, exception-based programming and errors-
           | as-values converge in the end anyhow in "code that treats
           | errors correctly". But my exception-based code is a lot more
           | informed by the errors-as-values approach now; a lot more try
           | statements with catch statements that actually _do
           | something_.
           | 
           | Even Haskell's very nice Either monadic handling can make it
           | _too_ easy to be in the heat of the moment and not thinking
           | about what the errors actually mean and what I can do about
           | them.
           | 
           | I don't think it's appropriate for every domain, which is why
           | I qualified the code I tend to work on. But in those domains
           | I'm thinking a lot more about how every single line of code
           | can go wrong rather than leaning on default exception-based
           | handling and expecting it all to work out.
        
             | vlunkr wrote:
             | > One of the things Go taught me is that I was not being as
             | careful about my errors as I should be.
             | 
             | I identify with this so much. Especially when dealing with
             | external things (file system, database, network) things can
             | go wrong at nearly every step. And yeah, that means you
             | have to check errors at every step, but it forces you to
             | think about how you want to handle them, and what message
             | you want to propagate when they happen. As a result, my Go
             | code has very few unexpected errors in production.
        
               | new_stranger wrote:
               | Hard to overemphasize this. Handling errors is similar to
               | the benefits that writing tests provides - slower
               | upfront, but a more stable product gets shipped.
               | 
               | Handling errors everywhere means problems are already
               | solved before they happen. No 1 am pagerduty alerts
               | because we didn't consider what would happen if a DNS
               | server hung until we timed out and thought just wrapping
               | in a try/catch and crashing was a good idea.
        
             | ohwellhere wrote:
             | This is exactly my experience. Being forced to handle so
             | many more errors showed me how much error handling I was
             | inadvertently eliding in other languages!
        
             | JoelMcCracken wrote:
             | I think this is for sure the first time I have _ever_ heard
             | someone say that Haskell makes it _too_ easy to handle
             | error cases.
        
         | caente wrote:
         | > I used to be excited by programming language features instead
         | of what problem I was actually trying to solve with
         | programming. I'd spend hours condensing 10 lines of perfectly
         | working code into 1 line of the most concise text possible
         | (...) they should be impressed by what the program does for
         | them, not what language features you used to implement it.
         | 
         | Interestingly, what made me go through similar evolution was
         | the very language in which I was trying to do all those things,
         | namely Scala. After a few years of trying to be "smart", I
         | realized that the problem was usually bigger than the language.
         | 
         | So perhaps, it wasn't Go, nor Scala, who helped us in our
         | realization, but life and experience?
        
           | throwaway894345 wrote:
           | Our individual lives and experiences don't make the package
           | manager better, though. Rather, Go's package manager (and its
           | overall philosophy more generally) is good because Go was
           | developed by people who had a lot of "life and experience".
           | And it seems intuitive to me that someone who uses a language
           | with a strong, mature philosophy would influence even more
           | junior users.
        
           | agumonkey wrote:
           | I believe he has a point. Go was from day one trying to walk
           | a different path. It was wisely dumb, pragmatic, simple (even
           | though yeah verbose on many fronts). It changes your focus on
           | external value rather than internal value.
        
         | shaan7 wrote:
         | > Just software, running, forever.
         | 
         | Until your users realize that if there was a security
         | vulnerability which was fixed, a system upgrade is not enough.
         | They will have to either hope that you haven't moved on, or
         | build things themselves. But then, thats not a problem with Go
         | specifically, thats a general issue with "static link all
         | things".
        
           | msie wrote:
           | Ah, but what if the updated shared lib broke other apps
           | depending on the old version? Pros and cons.
        
       | wtf_is_up wrote:
       | The thing about Go that pulled me in around 10 years ago was that
       | I could inspect the source code of an open source Go project on
       | GitHub and actually tell what was going on. And on top of that I
       | could easily cross-compile and deploy binaries in a way that blew
       | automake/CMake away. And of course the goroutines... no more
       | pthreads. It's a real case study in opinionated language design.
        
       | kryptonomist wrote:
       | To me, the greatest advantage of Go is the build time, which is
       | almost instant. So you get the joy of programming like in
       | Python/Js, being able to test very quickly your code, without
       | having to deal with stupid errors coming from type mismatch or
       | function parameters.
       | 
       | Plus, you get the performance of a compiled language, with a
       | simple syntax. Sure, you get just slightly better results with
       | C/C++/Rust, but then you deal with complicated OS level calls,
       | memory and library deployment issues (problems fixed by Go). Yes,
       | a few benchmarks show C#/Java almost as fast, but at the price of
       | a highly optimized syntax not seen in any average programmer. An
       | average guy get superb performance with Go without complications
       | from day 1.
       | 
       | And absent object oriented features are quickly forgotten.
        
         | maleldil wrote:
         | > C/C++/Rust, but then you deal with complicated OS level calls
         | 
         | What OS-level calls are you doing in C++/Rust that you aren't
         | in Go?
         | 
         | > library deployment issues (problems fixed by Go)
         | 
         | How is Go's library tooling better than Cargo? I believe Go's
         | is strictly worse, with its URL-based imports and how it deals
         | with major versions.
        
           | Thaxll wrote:
           | I think OP is talking about single binary with no
           | dependencies here.
           | 
           | As for go mod, yes it's not perfect but it's as powerful as
           | Cargo. https://golang.org/ref/mod
        
         | throwaway894345 wrote:
         | > So you get the joy of programming like in Python/Js, being
         | able to test very quickly your code
         | 
         | Ironically the canonical Python type checker, code formatter,
         | etc take _ages_ to run on even small code bases.
        
           | bobbylarrybobby wrote:
           | I think a lot of that is that Python doesn't launch a server
           | that handles code analysis/formatting requests, so every time
           | you want to do another round of things-to-do-on-save, they
           | all have to do be done more or less from scratch (some info
           | can be cached between runs, but if you're launching a Python
           | process that's like 100ms right there...). I imagine if there
           | were a Python code server that handled formatting and type
           | checking without ever shutting down, it would be quite
           | speedy.
        
             | MapleWalnut wrote:
             | Mypy provides a server to help with this called dmypy:
             | https://mypy.readthedocs.io/en/stable/mypy_daemon.html
        
             | bombela wrote:
             | I have some sort of python language server running with
             | neovim to highlight type errors. This is definitively not
             | fast to add errors. But being asynchronous it's palatable.
        
           | wbobeirne wrote:
           | Check out https://github.com/microsoft/pyright, it's pretty
           | snappy if you don't mind some JS in your ecosystem.
        
         | ryandvm wrote:
         | C#/Java are almost as fast, but not for immediate execution
         | environments. If you have one off invocations of the code, Go
         | executables will beat the pants off Java as you wait for the
         | JVM to fire up and for HotSpot to kick in.
        
           | ed25519FUUU wrote:
           | Maybe fast in principle but rarely in practice. I've never
           | once worked in a Java codebase that started up shorter than 5
           | or 10 seconds.
        
           | throwaway894345 wrote:
           | I've heard smart people argue convincingly that the JVM
           | doesn't actually take long to fire up, and that this is
           | something of a myth. It may take a bit of time for the JIT to
           | optimize, but that shouldn't impact basic CLI tools (un-JIT-
           | ed code is basically just interpreted code, and that runs
           | quickly enough). I'd be curious to hear from people who have
           | looked into this.
        
             | kaba0 wrote:
             | For smallish programs, a recent JVM will start up in 100ms.
             | This is enough to make some CLI tools (like eg. git, with
             | many separate invocations that return almost instantly)
             | slightly bad to use, but longer running CLI tools are
             | perfectly fine with it. There is also Graal to AOT compile
             | classes and that way the startup time is truly negligible.
             | 
             | What actually increases JVM startup time is class loading,
             | as it has to do byte code validation and the like for each
             | new class. This is only apparent for largish frameworks
             | though.
             | 
             | As for JIT, there is no much point for short-lived
             | programs. Like, most python scripts are run without that
             | and people write prod code in it.
        
           | jpavel2 wrote:
           | I write a variety of CLI tools for my own use in Java.
           | 
           | On this low-end Chromebook (Samsung Chromebook 3 with a
           | Celeron N3060 @1.60GHz) I can start the JVM, load the classes
           | for my CLI program, and print a help message,
           | jpavel@penguin:~$ time rcr -h         Usage: RCloner <config
           | path> get|put <entry> [args]                RCloner <config
           | path> list                  real    0m0.316s         user
           | 0m0.208s         sys     0m0.126s
           | 
           | in less than 1/3 of a second. And this is with stock openjdk
           | version 1.8.0_302, which doesn't include the startup time
           | improvements of Java 10 & 12.
           | 
           | Sure, I wouldn't write utilities meant to be piped one into
           | another, but for standalone CLI tools, the JVM startup time
           | isn't prohibitive at all.
        
             | leodriesch wrote:
             | I think he was talking more about serverless functions,
             | where 300ms longer for answering an HTTP-request would be
             | pretty long.
        
       | quadcore wrote:
       | I cant believe they are moving forward with "generics".
       | Programmers on average already tend to make things more
       | complicated than they should be. Now every single module in the
       | ecosystem is gonna use more abstractions, generics to fit their
       | social environment. Its well known that abstractions are the
       | devil. How many modules are gonna use generics when they should
       | not? Most? Programmers are bad at programming and they are social
       | herdy beast - they are human. Their code must follow the social
       | norm. The consequences of that could be terrible for the
       | language.
       | 
       | I dont understand why they move forward with this. Go is
       | absolutely awesome, it's a gem, adding generics is too risky.
       | This is such a bad news for me (i didnt know). I'm trully
       | affected.
        
         | adwn wrote:
         | > _Its well known that abstractions are the devil._
         | 
         | Then why are you programming in Go, instead of directly writing
         | x86-64 machine code? Remember that even assembly is an
         | abstraction...
        
         | noah_buddy wrote:
         | I think there are many very simple and understandable
         | situations where having the option of generics gives you a lot
         | of power. Like any programming concept, it's just another tool
         | in the box, if you don't want to use it, don't use it. If you
         | disagree with how others are using it, wouldn't that mean these
         | programmers are bad in your view and you shouldn't be using
         | their modules anyway?
        
         | jrockway wrote:
         | If you want to write unmaintainable code in Go, it's already
         | very easy; just use interfaces incorrectly. Go lets bad
         | programmers write bad programs. If you have a solution to that
         | problem, your programming language will be the one that kills
         | all current programming languages.
         | 
         | Generics will be similar; people will misuse them, and you'll
         | curse their names when you have to dive in and debug it. But it
         | will also let good programmers write very good programs and
         | libraries, and that's going to be a huge benefit for everyone.
         | As we've seen with interfaces, they can be misused, but they
         | can also be used correctly. Just look at the standard library
         | for examples of how they work well. io.Copy() was written once
         | and can work on buffered streams, disk files, HTTP bodies, ...
         | anything! That's a good use of interfaces. We're going to see
         | the same with generics, and it will make a lot of people's
         | lives easier and more enjoyable.
        
           | machiaweliczny wrote:
           | Elm kinda had such guardrails but they are hindrance, so it's
           | all about balance (or letting them off purposely - which
           | makes lang implementation hard as you need to compile half-
           | broken programs). That's why I think interpreted code will
           | win due to productivity gain or we get something that
           | compiles even faster than Go or real hot-reload.
        
           | quadcore wrote:
           | Everything you say compfort me in the fact this is going to
           | be bad. Everything I read in the article about generics
           | compfort me in the fact this is going to be bad.
           | 
           | Example: first you agree with me "its _already_ easy to write
           | bad code ", well you agree then its gonna be easier. Your
           | example about io.Copy. Yeah bingo, absolutely io is the
           | exception, the only case I know in 25 years of programming
           | that is made tasteful with generics. Actually its the only
           | case I know in 25 years of programming where a diamond-like
           | multi inheritance structure is okay. IoBase,
           | IoBaseRead:ioBase, IoBaseWrite:ioBase, Io:ioBaseRead,
           | ioBaseWrite. You get the idea.
           | 
           | Do you realise the language grammar is modified? They are
           | modifying Go's grammar. Man, they gotta have some balls to
           | make virtually a new language after 12 years of success.
           | 
           | Im open. I am. But the idea is bad on paper, now the signs
           | are too.
        
             | quadcore wrote:
             | Yet another bad sign:
             | https://news.ycombinator.com/item?id=29179738
             | 
             | No generics. Wait...
             | 
             | I have no idea what political conundrum they went through
             | to move forward with generics. I can only hope a miracle
             | happens and I end up surprisingly surprised by that new go
             | feature. I weighted my words: we need a miracle here.
        
         | brokencode wrote:
         | Generics are not that complicated or hard to understand, and
         | most of the time developers don't even need to interact with
         | them, except to say what type of data will be used in a
         | collection.
        
         | AnimalMuppet wrote:
         | > Its well known that abstractions are the devil.
         | 
         | Woah there. No, it is _not_ "well known", nor is it correct.
         | _Over_ abstraction is very problematic (and very common), true.
         | But _under_ abstraction is also problematic. There is a sweet
         | spot, and it 's hard to find. But the correct answer is
         | emphatically not "no abstraction".
        
           | quadcore wrote:
           | That's what I meant, in compressed form. Plus we know you
           | better err on the side of under abstracted in practice. So
           | what I meant is we know abstraction is where the devil lies
           | because in practice programmers tend to over abstract to look
           | smart. With generics as for one.
        
         | ohCh6zos wrote:
         | Programming is always going to be complicated as long as the
         | domain is complex. Go as is has traded having no learning curve
         | for having nothing to offer.
        
           | convolvatron wrote:
           | I think a dumb language for dumb programs is a really
           | valuable contribution - hardly nothing to offer.
           | 
           | is it less suitable for hard programs than other environments
           | - almost certainly
        
             | ohCh6zos wrote:
             | Thank you, that's an excellent point.
        
           | handrous wrote:
           | What it offers is that code you didn't write is significantly
           | easier to read & understand than in most languages.
        
             | kaba0 wrote:
             | But code you didn't write yourself but still have to wade
             | through is still harder to read and understand than code
             | that was not required to be written due to a better
             | abstraction.
        
               | handrous wrote:
               | Depends entirely on how long ago I wrote it, though.
               | 
               | Maybe it's a style thing, but I tend to have a lot more
               | trouble with "WTF does this (leaky, inevitably)
               | abstraction _actually do_ and where does that _actually
               | happen_? ", when reading code, than with _too much code_.
        
             | ohCh6zos wrote:
             | This hasn't been my experience. Go is incredibly difficult
             | to read because all Go code looks the so similar, lacking
             | intentionality or style, and it's so verbose that it takes
             | a very long time to grasp what any given thing does in
             | totality.
        
       | AtNightWeCode wrote:
       | 12 years and still no proper error handling. World stars. ;)
       | Seriously, the error handling is a big problem with Go. Not the
       | way it works, the way it effects how people do control flow in
       | general.
        
         | fourseventy wrote:
         | Thats your opinion. I love the error handling in go. I think
         | its superior to the traditional try/catch approach most other
         | languages use.
        
         | nineplay wrote:
         | Error handling is easily one of my favorite things about Go.
         | 
         | No 'oops I forgot to put in a try/catch and now my code died
         | with no explanation'.
         | 
         | No 'I forgot a finally ( or didn't realize I needed one ) and
         | now I'm leaking resources'.
         | 
         | No 'should I return Null or false or an error code?'.
         | 
         | No '20 log messages for the same error because every function
         | is reporting it'.
         | 
         | The Go model
         | 
         | - Return err, always as the last parameter
         | 
         | - When you need more context, add it to the error before you
         | return it
         | 
         | - There is a calling function that reports errors. Maybe
         | main(), maybe a subscriber, maybe a goroutine. There can be
         | other situations of course but the point is that there's a
         | clear ownership. If someone is logging errors in a higher up
         | method, they should be prepared to explain why in code reviews.
        
           | latchkey wrote:
           | There is no catch for array (or slice) index out of bounds.
           | You either code it in yourself or the best you can do is
           | watch for `recover()` and log it.
           | 
           | I wish that one use case was handled better. It is just too
           | easy to mess up.
        
           | nkozyra wrote:
           | > Return err, always as the last parameter
           | 
           | Well unfortunately, not always.
        
             | nineplay wrote:
             | If you have a good linter it will flag code where err is
             | not last
        
           | the_gipsy wrote:
           | Go errors are better than exceptions, yes, but way worse than
           | Result<T,E>.
           | 
           | There are too many ways too screw up error vars + nils +
           | control flows.
        
           | kbd wrote:
           | > No 'oops I forgot to put in a try/catch and now my code
           | died with no explanation'.
           | 
           | This is so backwards. First, I _want_ my program to
           | immediately crash if I have a bug. Go is like shell in that
           | it keeps going even if there 's an error. Second, I'm used to
           | getting stack traces, Go is the language that will give "no
           | explanation" by comparison if there's a failure.
        
             | vlunkr wrote:
             | > First, I want my program to immediately crash if I have a
             | bug.
             | 
             | An error being returned doesn't always mean there's a bug.
             | 
             | > Go is like shell in that it keeps going even if there's
             | an error.
             | 
             | With both Go and shell scripts it's up to you if you want
             | the program to keep going when there's an error.
        
             | grey-area wrote:
             | Your users typically don't want the program to crash, spare
             | a thought for them.
             | 
             | Re stack traces, they're fine I guess, but I prefer a well-
             | crafted error message to 200 lines of irrelevant file
             | locations/functions.
        
               | JoeyJoJoJr wrote:
               | I want my program to crash obviously during development
               | so that I know of the existence of bugs, which can be
               | ironed out before getting to production.
        
               | grey-area wrote:
               | That's the theory.
               | 
               | In practice it's impossible to exercise all the inputs
               | your programs may get, and then they crash in production
               | when users do things you don't expect.
        
               | kaba0 wrote:
               | Which is better than having a bug silently be in
               | production for years to come due to a silent error.
        
               | kaba0 wrote:
               | That's the point of exceptions. They bubble up! I can
               | manage them at a place where it is appropriate.
               | 
               | Something had happened during the processing of this web
               | request? Catch the exception and convert it to an
               | appropriate status code.
               | 
               | You should only ever let exceptions fall through "main"
               | when the problem is really not something you can manage
               | to handle.
        
               | grey-area wrote:
               | That's the theory.
               | 
               | In practice often people let the exception eater in main
               | handle it, and it either logs somewhere nobody looks or
               | returns this sort of generic error and exits:
               | 
               | https://www.google.com/search?q=Microsoft+Word+has+encoun
               | ter...
        
             | nineplay wrote:
             | I don't know what scale of projects you've worked on. When
             | you're dealing 100K requests/second you very much do not
             | want to immediately crash. It is absolutely the worst think
             | your code can do.
        
               | kaba0 wrote:
               | What framework, language crashes due to an exception,
               | regardless of scale? That exception gets mapped to a http
               | status code and that gets returned.
        
           | AtNightWeCode wrote:
           | 1. You have something that catches and logs all uncaught
           | exceptions.
           | 
           | 2. Defer is nice. As easy to forget as using in C#.
           | 
           | 3. Always null/nil. Uncle Bob is plain wrong here.
           | 
           | 4. Stack trace. But you should keep things wide and shallow.
           | No matter what technology you use.
           | 
           | In Go it is about as easy to swallow errors as with try-
           | catch. But my post was more about how all the if-statements
           | generates more unnecessary if-statements.
        
             | ssteel wrote:
             | The if-statements are not unnecessary if you want to handle
             | errors in place and make the code highly readable. Just
             | because you don't like it doesn't make it wrong.
        
             | Thaxll wrote:
             | 1. In most web server you have a panic middleware that does
             | exactly that.
             | 
             | By default in Go uncaught panic go to stdout.
        
             | nineplay wrote:
             | These are great designs that have been completely ignored
             | by developers in every large scale codebase I've ever
             | worked on.
             | 
             | "That's the developers fault, not the languages"
             | 
             | Look, the old grey mares of the programming world are doing
             | the best they can. I'm not going to blame C because its
             | developers usually make it up as they go.
             | 
             | But we've learned things over the past 50 years, and one of
             | the things we've learned is that company defined 'best
             | practices' and code reviews can not catch all the mistakes
             | that developers make and all of the things that can bring a
             | service to its knees.
             | 
             | Go has the benefit of experience. It knows what mistakes
             | developers make and it is going to prevent them from doing
             | that. There is Right Way To Handle Errors in Go.
             | 
             | How many times have I seen uncaught exceptions? I saw one a
             | week ago.
             | 
             | How many times have I lost resources because I didn't
             | realize something I was calling could throw exceptions?
             | Dozens.
             | 
             | Null/Nil exceptions. I couldn't count the null pointer
             | errors I've had to fix in my time. Probably in the
             | hundreds.
             | 
             | "should" keep things wide and shallow - somehow when Java 8
             | came out all the Lambda programmers lost this message.
             | 
             | None of these practices scale. We know that because we've
             | seen it
        
             | philosopher1234 wrote:
             | >But you should keep things wide and shallow. No matter
             | what technology you use.
             | 
             | This is literally the exact opposite of what I believe, and
             | the bane of my existence at work. Wide and shallow code is
             | spaghetti. Too many APIs = continuous confusion and
             | relearning.
        
         | lawn wrote:
         | I find it fascinating that some hate it and others love it.
         | 
         | I personally vastly prefer Rusts Result<T, Error> and
         | Erlang/Elixirs {:ok, T} you pattern match on or crash the
         | process and recover.
         | 
         | The code is cleaner while it also makes harder to make
         | mistakes.
        
         | mountainriver wrote:
         | It's never actually been a problem for me, I prefer Go errors
         | over most languages
        
           | jrockway wrote:
           | I agree with this. What I like about the Go method is that
           | all errors are equal -- they look the same if it's a stack of
           | microservices running at different companies, a bunch of
           | goroutines communicating state with each other, or if you're
           | just calling a local function that fails. It's the same every
           | time, and the programmer can cut through the noise and make a
           | complicated error from a complicated system simple, concise,
           | and easy to understand.
           | 
           | People seem mad that they have to plumb around `err`, and
           | that they have to provide useful context with fmt.Errorf. I
           | see that as letting good programmers make good systems. The
           | default in other languages is useless -- line numbers and
           | arguments is all you are allowed to have, and when something
           | goes wrong it takes up your entire screen with noise. Not as
           | good as everyone thinks it is.
        
           | AtNightWeCode wrote:
           | I can live with the error handling. But as I wrote. The
           | problem is that it encourages if-programming. Something that
           | is a problem in the Go community.
        
             | handrous wrote:
             | If it's helping keep the "'if' considered harmful" crowd
             | away, I say keep it. There are plenty of other languages.
        
               | mountainriver wrote:
               | Yeah exactly, conditionals around errors are fine.
               | Nothing like being pedantic for no reason
        
             | mseepgood wrote:
             | since when is if-programming a bad thing
        
               | skybrian wrote:
               | It depends on what kind. I didn't find maintaining
               | codebases littered with platform-specific ifdefs all that
               | fun.
               | 
               | If statements used for error checking are a bit verbose
               | but basically fine.
        
               | mseepgood wrote:
               | Go doesn't have platform-specific ifdefs sprinkled
               | throughout the source. Platform-specific code is
               | separated into files guarded by build tags as recommended
               | in 'The Practice of Programming'. Compile-time control
               | flow is not mixed with runtime control-flow.
        
               | skybrian wrote:
               | Sure, that was in C. Go is an improvement.
        
               | AtNightWeCode wrote:
               | What you learn at school when it comes to programming is
               | to avoid if-statements for control flow. It is error
               | prone. If-statements are mainly used for various types of
               | guards.
        
               | mseepgood wrote:
               | 'if' is the epitome of control flow (next to looping).
               | It's fundamental to computer programming. It's honest.
               | Don't be ashamed of control flow, don't hide your control
               | flow as if it didn't exist.
        
               | morelisp wrote:
               | > It's fundamental to computer programming.
               | 
               | I'm weakly pro-if, but no, it's not. We went a lot of
               | years without it, and some rending and gnashing
               | accompanied its introduction.
        
               | Thaxll wrote:
               | vs exception based control flow which is way worse.
        
               | xh-dude wrote:
               | I really think Go's opinion here arises from a sense that
               | some abstractions of control flow just should be verboten
               | for concurrency. For example exceptions dumping a stack
               | trace in a concurrent program is often OK and
               | occasionally extremely cursed.
        
               | AnimalMuppet wrote:
               | And what you learn after a few years in the real world is
               | that, when school tells you "this is the right way",
               | they're almost always wrong. Or, there at least almost
               | always wrong in many circumstances. The real world is a
               | _lot_ more complicated than they teach you in school, and
               | the correct answer is almost always  "it depends".
               | 
               | Should you avoid if-statements? It depends. What are you
               | going to have to do instead? You're going to have to do
               | _something_. Is that something going to be more
               | understandable for your co-workers for the lifetime of
               | the code? Maybe, depending on your co-workers.
               | Maintainability over the lifetime of the code far
               | outweighs and  "should" that they tell you at school.
        
       ___________________________________________________________________
       (page generated 2021-11-10 23:02 UTC)