22 ms·
Ten years of “Go: The good, the bad, and the meh”
- deleted 3y ago[deleted]
- seeknotfind 3y agoGreat article. Go may have generics, but because old Go code doesn't, and the standard library doesn't, it still feels like the language doesn't sometimes.
- Pxtl 3y agoBasically learning the lessons of Java and C# all over again. Yes, there are features you can defer implementing until later, but their absence infects everything until you do. I still see cases where people have to drop down into ADO.Net code for C#, and the fact that you still see DBNull.Value instead of just a simple null value, much less a proper Option type is infuriating. Like I write a lot of Powershell code and their stuff still returns DBNull.Value when returning a null value from the DB, when nullable value-types were introduced almost 20 years ago.
- recursive 3y agoThe documentation for DBNull [1] seems to have some idea that DBNull represents something entirely different. > Do not confuse the notion of null in an object-oriented programming language with a DBNull object. In an object-oriented programming language, null means the absence of a reference to an object. DBNull represents an uninitialized variant or nonexistent database column. For all the explanation though, I couldn't fathom what its talking about. [1]: https://learn.microsoft.com/en-us/dotnet/api/system.dbnull?view=net-7.0&redirectedfrom=MSDN https://learn.microsoft.com/en-us/dotnet/api/system.dbnull?v...
- stefncb 3y agoI don't know C#, but I'll take a guess: I think it's exactly the same issue as null in Lisp and Lua — you sometimes want to differentiate between null as in "I returned no value", and null as in "I returned the fact that there is no value". Or null vs false vs empty list in the context of Lisp. This distinction becomes very clear (and sometimes very annoying) when you realize that in Lua, setting a table key to null completely removes it, so there's no way to store the concept of a missing value unless you define a special value (like DBNull). A slot being null literally signifies its absence.
- kazinator 3y agoThere is no difference between "no value" and "the fact that there is no value". "The fact that" is just rhetorical verbiage. There is an ambiguity in a polymorphic container between a present entry indicating a null value, and a null return indicating there is no entry. E.g. hash table being used to represent global variables. We'd like to diagnose it when a nonexistent variable is accessed, while allowing access to variables that exist, but have a null value. This is because the variables are polymorphic and can hold anything. When we are dealing with a typed situation (all entries are expected to be of a certain type, and null is not a member of that type's domain) then there is no ambiguity: if a null appears in the search for a value that must be a string, it doesn't matter whether "not found" is being represented by an explicit entry with a null value, or absence of an entry.
- tedunangst 3y agoThis rhetorical verbiage matters a lot in a language like Lua where you can pack an array full of dbnull sentinel types but filling it with nil results in an empty array.
- recursive 3y agoI don't know lua. But the behavior you describe seems like a quirk of lua tables. Instead of having `table.get(key)` return a sentinel value, you can replace it with `table.has_key(key)` and `table.get(key)`. I'm not sure about the ergonomics of the trade in lua. But in C# the ergonomics of `DBNull` are terrible. If it were just replaced with `null` everywhere, everything would just be better. IMHO.
- SPBS 3y ago> Yes, there are features you can defer implementing until later, but their absence infects everything until you do. I still see cases where people have to drop down into ADO.Net code for C#, and the fact that you still see DBNull.Value instead of just a simple null value, much less a proper Option type is infuriating. This DBNull.Value may be a problem for C#, but idiomatic Go has largely been untouched by the introduction of generics.
- Mawr 3y agoCorrect, a new language feature doesn't magically inject itself into all existing code. This simple fact is sadly commonly missed by many.
- kubb 3y agoCopilot and the like are good for Go, because you can generate all the boilerplate code they make you write. As for the success, it's obviously the minimal set of language features, conformance to established paradigms, not being very broken and being backed by Google. There's a ton of suboptimal choices in Go, but overall it can work for many applications.
- earthboundkid 3y agoDart is backed by Google.
- crop_rotation 3y agoThe stdlib is the killer feature of go. Several times I wrote high enough performance small services/servers that people not familiar with go were astounded with (mostly the speed of writing the code and memory usage). I made many go converts this way. And I always only had to use the stdlib (many benefits when writing within a company).
- adtac 3y agoI consider the stdlib to be Go's best feature too. As a somewhat contrived example, can you name any language that lets you write a HTTP/2 TLS endpoint that computes the HMAC of a PNG file's pixels without any dependencies? And if something is still missing, it's probably in golang.org/x (which is basically stdlib)! After that, I probably consider readability at 3am [1], defer statements, explicit error handling and fast compile time to be the most important. [1] Readability of not just your code: being able to go-to-definition into stdlib and immediately understanding it without having to grok a million unrelated decorators/FactoryFactoryFactory/std::_Vector_iterator<std::_Vector_val<std::_Simple_types<<block>>> is incredible
- afandian 3y agoJust cos I was curious and Java has a pretty good comprehensive library. - PNG: https://docs.oracle.com/en/java/javase/14/docs/api/java.desktop/javax/imageio/package-summary.html https://docs.oracle.com/en/java/javase/14/docs/api/java.desk... - HMAC - https://docs.oracle.com/en/java/javase/14/docs/api/java.xml.crypto/javax/xml/crypto/dsig/SignatureMethod.html#HMAC_SHA1 https://docs.oracle.com/en/java/javase/14/docs/api/java.xml.... You need Jetty for HTTP/2.
- crop_rotation 3y agoJava also has a comprehensive stdlib but the golang stdlib is designed so much better, and has a small number of simple and orthogonal concepts. (e.g io.Reader and io.Writer go a long way, compared to the 20 io interfaces in java).
- cogman10 3y ago
- whimsicalism 3y agoGo was successful because it came after decades of pretty much no language putting good networking tools in their stdlib.
- etiennedi 3y agoNot sure if that alone is what made Go successful. But yes, having great networking tools in the stdlib is very refreshing! One of the things Go got right.
- deleted 3y ago[deleted]
- ilyt 3y agoNot just networking but focusing on concurrency. In before if you needed to make a highly concurrent network app you had to get into asynchronous programming that generally makes code looks shit (or at least slightly worse) and harder to debug. With Go and goroutines taking IIRC around 8k for start you can "just" spawn as many of them as there are connections and write your code as if it was serial one. Add some half-decent concurrency primitives and it's pretty easy to not fuck up highly concurrent and highly parallel code.
- veber-alex 3y ago> Go’s error handling is more verbose than those other languages, but structurally, there’s a lot of commonality under the surface. In Go the type system doesn't force you to check for errors, the same way as languages with null pointers don't force you to check pointers before dereferencing them. That's the real problem with errors and null in Go, not the verbosity (though that doesn't help)
- aliasxneo 3y agoThe typical answer is that Go doesn't allow you to not address values returned from a function. So, to ignore an error, you'd typically have to write: result, _ := myfunc() That being said, I most certainly prefer the approach that Rust takes to this problem.
- Thaxll 3y agoIf there is a single result you can also on ignore the return value by calling myfunc()
- veber-alex 3y agoa, err := f() if err != nil { return } a, err = f() This will compile.
- aliasxneo 3y agoI'm not at all defending the practice. I agree it's very easy to navigate around this. My answer is just the canonical one I've seen over and over again in books about Go.
- masklinn 3y agoIt's not just that it's "very easy to navigate around this", it's that it's not true. The incorrect statement piggybacks on Go forbidding unused variables, however that has two absolutely major holes: First, it requires having a variable in the first place, if you call a function for its side-effect and don't remember that it returns an error, Go won't tell you. Second, Go only errors on dead variables, not dead stores, since conventionally the error variable is "err" you can easily forget to check one of them, and Go won't say anything because the err variable was read in one of the other checks. It's even worse if you're one of the weirdoes which uses named return variables, because named return variables are always used: func foo() (v int, err error) { a, err := bar() b, err := baz() v = a + b return } compiles just fine. But at least you're returning the second error. No such luck if you're using named return variables for documentation: func foo() (v int, err error) { a, err := bar() b, err := baz() return a + b, nil } go also has nothing to say about this.
- Veraticus 3y agoVery insightful. Re: the generics point — As a Go programmer I always thought the generics complaint was kind of silly in practice — complicated code should be simplified and made more concrete, not more generic. I’m glad generics were implemented, if only to silence the chorus of people who didn’t even use Go but whined about the lack of them. Their inclusion has simplified the stdlib and led to some cool new functions. Nevertheless I think people implementing them in their own projects is basically code smell and they are a symptom of poorly thought-out code rather than excellent code. Anyway. This was a good initial post and a good follow-up. Go is my favorite language out there right now for its clarity, power, and ease-of-use. And with loop variable capture coming (the biggest remaining foot gun in the language in my experience) the language is only getting better.
- jeswin 3y ago> power What power?
- Veraticus 3y agoThe power of voodoo
- icholy 3y ago> Nevertheless I think people implementing them in their own projects is basically code smell and they are a symptom of poorly thought-out code rather than excellent code. Who needs data structures right?
- Veraticus 3y agoUh, generics are not data structures and generics are neither the only way nor the best way to interact with data structures.
- lillywastaken 3y agoDo you think it is somehow more elegant to have a specialised version of a data-structure for every single type that may need to be placed into it? Or just to ignore the type whatsoever and erase it via interface{}? Even Golang's designers obviously realise that generics are a better way to interact with data structures because the standard types map and array were always "generic", just special cased as such.
- tail_exchange 3y agoI was very skeptical of Go, but after trying it, it quickly became my main and favorite language. I think the drawbacks of the language are easily offset by how powerful and simple it is. Its biggest flaw imo, which I don't think was mentioned in the article, is that Go did not learn from The Billion Dollar Mistake in Java: null references. You have zero protection against nil pointers, and this is likely not something that can be changed now without breaking backwards compatibility.
- ilyt 3y agoLack of sum types and thus impossibility of just having Result<T,E>-like type for returning errors is bigger one for me, I didn't get bitten by nulls all that much in Go Although I guess that feeds into eachother, sum types would eliminate any need for null types in the first place.
- whimsicalism 3y agoYes, sum types would solve the problem - you are both identifying the same issue imo
- packetlost 3y agoI would have taken sum types over generics, personally. It kinda sucks because you can't create something like Rust's `?` operator without them or making serious kludgy compromises.
- fsociety 3y agoNil is a carefully chosen name in Go, and was a trade-off which was made. It’s not quite right to compare it to null in other languages. I agree it is not as safe as a language like Rust, however it was the right trade-off to make in my opinion. The main protection you have against nil pointers are nil receivers, and knowing when to use reference semantics vs value semantics.
- veber-alex 3y agoWhat's the tradeoff? what advantage having null pointers give?
- stpedgwdgfhgdd 3y agoWorked with Go over 6 years; my biggest annoyance at the beginning, verbosity of error handling, has mostly gone away. In most cases the explicit error handling helped us hardening the code. What does still bother me is the lack of proper enum support. I remember when Java boosted their enum support and the way it impacted the quality of the code. Sure would love to see something similar in Go.
- dewey 3y agoFully agree with your points. In my experience if people flag error handling it almost always means they didn't spend enough time with the language yet, as in the day to day work it's a non-issue.
- za3faran 3y agoJava now has records, record patterns, pattern matching, and switch expressions. Things that the golang author still don't seem to understand the need for (quite ironic for a language that claims it makes concurrency easy).
- Mawr 3y agoIs that more or less ironic than Java copying Go's goroutines and still struggling to add value types?
- za3faran 3y agoJava's designers have consistently mentioned the approach they're taking that Java has the last mover advantage. They cautiously see what features other languages applied, and take what gives them the highest value compared to the complexity introduced. Java's virtual threads are already superior to golang's approach because they're working on structured concurrency from the start. Value types are a huge proposition, but they seem to be coming along nicely. They have already baked in nullables/zero values into the design, something that is a pain in golang, and a big gotcha and source of bugs. The interesting thing is that Java already beats golang because of its superior GCs, particularly in large programs, so it will be interesting to see what sort of performance improvements come out of value types.
- wolfspaw 3y agoGo has turned into an Awesome language. I'm one of those that cannot use a PL that has no generics... It kills the DX of Algorithms and Data Structures. Now it has Generics, soft RT GC, and it might even get official Arena Allocation. I /LOVED/ the Matklad comment of |error handling converging|, indeed -- it seems that PL community evolved to "any-error" + annotation-at-call-site.
- marssaxman 3y ago> the DX of Algorithms and Data Structures sorry, what does this phrase mean?
- unmole 3y agoDX is Developer Experience.
- marssaxman 3y agoThanks! I had vaguely imagined it might be related to differentials.
- User23 3y agoI'm guessing that DX means "developer experience" here.
- c-cube 3y agoIt still doesn't have sum types. Maybe 10 more years and Go can catch up to SML (a language from the 1970s). That's a big weakness for a static language this millennium.
- synergy20 3y agoI learned Go on and off in recent years on the side(daily job does not need Go), I like its battery included stdlib and cross platform support. I do feel its binary size is large comparing to c and c++, and multiple Go executable can not share libraries as easily as how c/c++ uses the shared lib, when I have a few Go binaries they add up, and I do storage constrained embedded development a lot. On the desktop side, I really hope Go can have a GUI in its stdlib, something like what Flutter/Dart does: adding a Skia kind of engine and let me do GUI cross platform, that will make Go main stream like wild fire.
- synergy20 3y agohttps://github.com/flutter/engine/blob/main/impeller/docs/faq.md https://github.com/flutter/engine/blob/main/impeller/docs/fa... Impeller is the Skia replacement and is in full c++ that supports all platforms. It will be great if Go team can work with them(both are in Google) and make Impeller a render engine for Go. With this no more bloated electron.js and no more Java/Swing or Qt, what a dream for the day.
- akmittal 3y agoExecutable size is big or small to which system we are comparing to. It's definitely bigger than C/C++ but considerably smaller than nodejs/electron. Also having a single binary is good in lots of cases because then you don't have the install runtime/separately install shared library
- citrusybread 3y ago>multiple Go executable can not share libraries as easily as how c/c++ uses the shared lib https://pkg.go.dev/cmd/go#hdr-Build_modes https://pkg.go.dev/cmd/go#hdr-Build_modes you can actually build with shared libraries :) I think most people I've seen use go, only use a single application, or have it turned into a docker container; so for them this is pointless but just fyi. I personally dislike static linking but I see why it was used so heavily with go.
- synergy20 3y agonot really, it's not something Golang really cares a lot to say the least, to become 'mainstream', Golang actually has to embrace more use cases. https://github.com/golang/go/issues/47788 https://github.com/golang/go/issues/47788
- bborud 3y agoGo didn't try to be overly clever and abstract. That rubs quite a few people the wrong way, but it also means you are less likely to have to work with people who try to be clever. My first reaction when seeing Go is that it smelled of "old fart". It looked straightforward and unexciting. I'm an old fart. I like straightforward and unexciting. It tends to lead to code that I can still read 6 months from now. I want to make stuff and not endure people boring me with this weeks clever language hack they came up with that expresses in one unreadable line what could have been expressed clearly in 3 lines.
- Veraticus 3y agoYeah this was my primary complaint with the inclusion of generics. People will try to be all clever and their code will wind up as an unreadable, unmaintainable disaster. It has definitely led to some cool stuff, but I prefer boring, verbose, and clear any day.
- pie_flavor 3y agoProblems are generic, such as having a tree collection. For solving generic problems, you can either use language generics, or reflection, or type erasure, or codegen. The latter three are about as far from 'boring and clear' as you can get. Still verbose, though, but I don't expect that's a benefit.
- Veraticus 3y agoI would say 95% of people who are trying to solve a complicated problem with reflection, type erasure, or codegen are solving the problem the wrong way. Obviously I'm glad these tools exist, and some problems can indeed only be solved with them. But I think people reach for them as a first solution and make bad code as a result. Go strongly encourages you not to reach for bad solutions, which is one of its bigger advantages, in my opinion.
- woooooo 3y agoCollections obviously need to be generic though. Slices and maps were generic from day 1 in go so it's not like this is controversial.
- iamcalledrob 3y agoI am immensely thankful for Go. The simplicity of the language and the stdlib is shockingly well thought out -- things like io.Reader are so obvious and yet not part of many other languages. The language has made me a better programmer. And the cross-compilation story is chefs kiss. Working on a cross-platform project where in Go, I write code and it just builds. In Java, I fight with Gradle. In Swift, I fight the type system and the way everything's constantly deprecated. It's not all perfect. I wish the generated binaries were smaller. I wish the protobuf library wasn't awful. And better Cgo/FFI would be nice. But overall, I've never been so productive.
- za3faran 3y ago> Working on a cross-platform project where in Go, I write code and it just builds I've worked on large golang code bases that had to build on bazel, and I had the same experience fighting it. It has nothing to do with the language. > In Java, I fight with Gradle. So gradle's issue, not Java's. See above.
- maccard 3y agoPretty much every golang project I've ever touched builds with `go build`. Most that have makefiles just call `go build`, and the makefile is more for building docker containers, or doing infra-related things. If a project is in go, 98% of the time `git clone XXX && cd XXX && go build` will work. That is absolutely not the case with C, C++, Java, python. > So gradle's issue, not Java's. See above. The issue exists with maven too, but _not_ with go build, which is OP's point.
- adrianmsmith 3y ago> If a project is in go, 98% of the time `git clone XXX && cd XXX && go build` will work. I can’t speak for the other languages but I reckon this is the case for Java projects. Git clone, cd XXX, mvn clean package. Potentially messing about with whether you have Java 8, 11 or 17 installed which saddens me to mention. But if you are into Java, you have them all installed already, and just need to make sure the right one is activated when you do the above steps.
- wk_end 3y ago> Again, it shows how things have changed that I praised Go’s type inference as an advance in the state of the art, but now the Hacker News crowd considers Go’s type inference to be very limited compared to other languages. "You either die a language nobody uses or live long enough to be one people complain about." This rubs me the wrong way. Even back when Go first came out, anyone who knew anything about programming languages rolled their eyes at pretty much everything about Go's type system, including the inference. Just because Sun couldn't figure out how to do it in the 90s doesn't mean that type inference wasn't mostly solved in the 70s. Well before many people were using it or lived any real length of time, Go's always been a language people have - rightly - complained about. That said...nothing in the original post says anything along the lines of "Go's type inference [is] an advance in the state of the art", so I might be misunderstanding the author here.
- softirq 3y ago> anyone who knew anything about programming languages rolled their eyes at pretty much everything about Go's type system And Go has succeeded despite these condescending diatribes on how a language needs to have a Hindley-Milner type system with ADTs and type classes to be useful. Go made me truly realize how insufferable the PLT community is, and why they are so absolutely lost when it comes to creating successful languages. In under a decade Go swept up entire markets with a simple, down to earth language you can learn in a day and keep in your head. It optimized for the masses and the common cases and has absolutely eaten the lunch of these languages with lauded type systems that takes several courses in formal logic to even get started with.
- nullwarp 3y agoGo really is great. There was a big argument around a new project we were starting whether to do Go or Clojure. What we did to settle the debate was to ask an entry level dev that was just starting if he was interesting in writing two sample applications in each language, having known nothing of either. Nothing complicated but touched enough points (HTTP endpoints, database interaction) A full day later was still trying to get the Clojure app working correctly. He finished up the Go one in like an hour. Since then we've brought new devs on with zero Go experience and they are up writing good code in a day. I can't imagine where we would be if we had gone down the Clojure route.
- deleted 3y ago[deleted]
- j1elo 3y agoI'd categorize not being able to convert "unused thing" errors into warnings during development iterations as one of "The Bad". Just today I had a couple blocks of code which were causing erratic issues. Wanted to see if it was the second one, so I quickly commented it out. This is just an exploratory development session, no need to comply with code quality guidelines. Still, the code failed to compile because now I had to worry about 8 lines with stuff that had become unused. The stubbornness about not adding an escape hatch for, again, exploratory intermediate development iterations is unnerving. "But code should not leave unused stuff around". I agree. That's why after a hundred iterations, in the final compilation phase for production, this kind of errors-are-warnings flag would be disabled.
- pravus 3y agoI use a technique I call "runtime comments": if false { ... stuff I don't want to run right now but the compiler still has to deal with it ... }
- j1elo 3y agoWell, for that specific case (it was a well defined block that could be all selected and commented out in order to disable it), your technique would have worked fine, true :) But of course it can get tiring and not be very practical if the logic to disable is a little bit more spread out (I'd say having to "if false" anything more than 2 paragraphs or blocks of code would already start to feel annoying)
- irq-1 3y agoThis is just an intractable problem: if there is any way for people to leave unused code, they will. If you want the code to be clean, you cannot have (for example) a debug mode that allows unused code, because the code will just be left in 'debug' format. Eventually the community shared code will have so much debug-but-it-works code that you'll never get a system of clean code. And think of what the current strict rule has done: go is the only(?!) language that has a consistently clean ecosystem. When's the last time you looked at go code that huge chunks commented out? That said... it is annoying. More annoying the less import the script, and the faster you want to test something.
- aptenoforst 3y agoIts a shame that Go as a language is so lacking, the tooling is amazing. I wish there was something like Go but with an actually good programming language attached.
- kansface 3y agoThis is pretty much my take, too. Go as a compilation target?
- erik_seaberg 3y agoI’ve noodled around with generating review-ready Go from CL (because macros), but it’s hard to flatten subexpressions (like multiple-value-bind around a call that returns a value and an error) into blocks of statements that assign to new temp vars, and I couldn’t expect arbitrary CL to just work, it’d be more of a CL-flavored DSL for generating loops and error handling.
- Night_Thastus 3y agoWhat do you think Go is missing?
- aptenoforst 3y agoAnything that made programming easier in the last 30 years. I miss Hindley Milner type inference, ADTs, default immutability, sane error handling, pattern matching, and functional collection manipulation. I'm not even mentioning the time it took to add generics to the language, which should've come from the beginning, and we got a bad implementation of it. Not saying that it HAS to have all of this, but at least 1 or 2 things of that list would already make Go have much better ergonomics. Go has no excuse since it's a relatively new programming language, and it could've got some of those from the start.
- Night_Thastus 3y agoTBH, it sounds like you want a functional language (type inference, pattern matching, collection manip), of which there are many. GO is not such a language. But then you want ADTs, which aren't really functional. I'm not sure you can have both in a clean way. The closest you might get is a multi-paradigm language that tries to allow both, like C++. Default immutability is great in a language like Rust where it's designed from the ground up to warn you as much as possible at compilation when something is wrong. You can rely on the compiler a lot. But adding default immutability to a language that isn't designed around the same concepts seems odd. You don't gain the same kind of benefits, but you do have to deal with the tedium. Worst of both worlds, in my view.
- anonyfox 3y agoComparison with Emacs: an awesome operating system that still needs a great editor. Go: amazing tooling/libs, only needs a great language :-) But a few tweaks, like proper Enums and a Option/Return Type (to avoid excessive err != nil), maybe a compilerflag to force dealing with errors (instead of _ it) - much better. If I can wish for something, then some native map/filter/reduce to avoid excessive for-loops…? :-)
- stevemk14ebr 3y ago"What I got right...Using capitalization for the public/private distinction in functions, methods, variables, and fields" I disagree with this strongly. Due to this when you need to change one of these things to the opposite it involves changing every use site as well. This has far reaching implications for refactoring, wrapping external code when you really do need to expose its guts, etc. Any time you need to do this in a non-manual fashion you're required to parse all of the code exactly perfectly (ASTs and such). Even go itself has not figured out how to do this, rf is still experimental and not complete: https://pkg.go.dev/rsc.io/rf https://pkg.go.dev/rsc.io/rf. Example use case: https://github.com/golang/go/issues/46792 https://github.com/golang/go/issues/46792 I much prefer the non-viral public/private attributes other languages use.
- LastMuel 3y agoShort of changes within the module itself, if you switch a Public function to a private function in another language, how are you not having to go change everywhere it's being used?
- tialaramex 3y agoI'd guess the typical situation is you had thought maybe a public API featuring enunciate_spools() was a good idea, but eventually you realised actually nobody actually wants to enunciate spools and few people know how, when you see other people's code that calls enunciate_spools, it's always either a bug (and they shouldn't have) or test code that is inappropriately testing your stuff not their stuff. So you make it private, in say Rust that's an ABI break, so you need a semver bump, but you aren't changing your code. Internally normal_operation does need to enunciate spools, not to mention the acrobatic use of it in complex_operation and fancy_coroutine but that's because it knows intimately what spools are and why it's enunciating them - it's an internal design element, not an API. In Go, you have to rename it everywhere. Maybe your tooling helps with that. OK, but, not having to do it also helps with that and for everybody.
- alcover 3y agoAgreed. First thing I frowned at when considering Go. (Plus it looks a bit messy. foo.Init() ?). That and reserving the verb `make`..
- vl 3y agoThe biggest go problem in practice is ironically omitted in both blog posts: Verbosity of error handling! There should be a shorthand for returning if last ret value is non-nil in one line. Otherwise all you code is littered with: if err != nil { return err } and it makes it four times as long and way less readable as a result. This needless verbosity really reminds me of Java. Also, go fmt is not opinionated enough! There really should be one way to line break and max width. Right now you can't rely on it to magically format it as it "should be" and fire-and-forget when typing.
- candiddevmike 3y agoYour code shouldn't be littered with that though, those errors should be wrapped or have some kind of logging/handling associated with them. If you find yourself just returning err all the time, you're not doing it right, IMO.
- vl 3y agoIn practice if you look into existing codebases, it is littered. defer is used for RAII-style clean up, so in 95% of the cases it's just return the error and that's it.
- sethammons 3y agoReal world code base developed over a decade. Handles billions of emails. Searching our prod code, "naked" if-err-return-err showed up in about 5% of error handling cases, the rest did something more (attempted a fallback, added context, logged something, metric maybe, etc). If you are doing a naked return you are gonna have a bad time.
- didntcheck 3y agoIf only a language could have a built in feature to propagate an error up the call stack, recording its context as it goes! It's always surprised me how negative of a reception checked exceptions had, since they provide the forced handling (or explicit propagating) of (value, err) or Result<T, E>, but with an automatic stack trace and homogeneous handling across the ecosystem I imagine some of the disdain in Java specifically came with how unergonomic they are with lambdas. Either you don't allow them at all, like in most standard library functional interfaces, or you do, but now every caller has to handle a generic Exception. I guess what was really needed was being able to propagate the "check" generically, e.g. <T, E> T higherOrder(Supplier<T throws E> fn) throws E { return fn.call(); } So a call site of higherOrder would only be checked as far as fn is I'm unsure if that's even possible to do (and if other languages have done it) or if it leads to undecidability. I'm very rusty on PLT
- worik 3y agoA bit off topic but... I need some resources for evangelizing GO. I do not use it, but... I have a colleague who needs/wants to replace a PHP/Laravel mess. They are talking up Node.js I think GO would be a better choice This article is close to what I need, but is there anything better? The server side code they are looking to replace is handling sensitive financial information and I am very queasy using Node.js in that domain
- nubinetwork 3y ago[flagged]
- Alifatisk 3y agoGo is loved because of three reasons. - Simple - Highly concurrent - Impressive networking stdlibs
- mrbonner 3y agoWorking with Python and Java over the years, I have this feeling that Go isnt battery included. Maybe I miss out 3rd party libraries I am very familiar with? For instance, Python has parse library to help parsing inputs without the need for RegEx. Java has lots of “common” collection libraries. I just feel exhausted coding the same from scratch in Go either because no such library exists or being told just copy and paste!