25 ms·
I Want Off Mr. Golang's Wild Ride
- zxcvbn4038 7y agoWhat is the point of a ten page rant like this? If the guy doesn’t like coding in Go, just stop using Go, problem solved. How many more times are we have to have the language X is different then language Y and I hate feature Z discussion? These are popping up almost daily. We could probably automate generating a daily rant with commentary, and let all the Joe Nobody coders get back to whatever they are trying to accomplish.
- adamrezich 7y agoit is often easier to learn from someone else's mistake than to have to make the mistake yourself. what's not to be gained by learning from someone else's experience? why do you see criticism (with actually-encountered, real-world examples, no less!) as being without merit?
- krallja 7y agoHardly anybody writes a retraction after three years of “mongodb is great in production” — they silently switch to a new product, and maybe say something positive about it too. These kind of rants are hard-earned battle scars of former zealots learning their lesson, and should not be discarded.
- _bxg1 7y agoI think the mistake may be assuming that Go is meant to be a general-purpose language. From what I can tell, it's purpose-built to be a "web services" language, and its design-decisions center around that. What does that mean? - It's expected to be run on Linux servers (not Windows) and developer workstations (probably not Windows). - It needs to be fast but not blisteringly fast. Micro-performance concerns like the Time object thing are devalued. - Embedded use-cases are probably not given too much attention. - Agility in working with dynamic data (because that data is often foreign) is valued over flawlessly safe types. By deciding not to worry about certain use-cases, the language can be more developer-efficient for its intended use-cases. In this light, for better or worse, I think the decisions made make a lot more sense.
- zug_zug 7y agoExcept docker is written in go. Guess they never got the memo to not use go for non-webservices...
- lwb 7y agoDocker’s primary use case is also web services.
- g_delgado14 7y agoUbuntu is used (mostly?) for web services. Is Ubuntu suitable to be written in Go?
- eudoxus 7y agoUmm..what? Ubuntus primary use case was not web services, it was a user-friendly PC OS compared to the Linux variants at the time. It's picked up a lot in the server space because of the familiarity of it, with respect to package management et all.
- _bxg1 7y agoFair, although it has very similar constraints/goals to those listed above
- jjnoakes 7y agoIf the language was meant to be run on unix machines for web services, it shouldn't support anything else in a half-done manner with silent errors and corruption. The situation as it is now is just poor language and/or library design - choosing to support different operating systems with an API that requires the wrong thing to happen in some cases.
- _bxg1 7y agoIf you workstation does happen to be Windows, support-with-edge-cases may be plenty good enough for you to get your work done and if you run into a problem on your dev machine, it's much less of a big deal
- umvi 7y agoMaybe I'm a zealot, but I don't really consider "doesn't work as well on windows" a con of a language. C# is (or at least used to be) utter garbage on Linux compared to Windows. I don't hold that against C#, but rather recognize that Linux/Windows are very different, and that compiler maintenance and development is non-trivial (and obviously Microsoft is going to prioritize Windows). This article is basically a rant that Go was designed with *nix in mind and that Windows is a second-class citizen by comparison.
- karatestomp 7y agoThere's some stuff in there about it not handling valid edge cases on Linux particularly well, either, though.
- The_Colonel 7y agoWhat is it then if not a con? I mean, C# not running well on unix systems was immediate show stopper for a lot of projects but we can't call this a "con"?
- umvi 7y agoIt's only a con in the context of your use case and requirements. It's not a con for everybody, so in the general case I would instead call it a limitation. Every piece of software in the world has limitations. The limitations are only cons in the context of your requirements. Is it a con of SQLite that it is missing features when using it with the JFFS2 filesystem? Maybe, depends on your use case. If your system doesn't use JFFS2, then it's not a con worth considering.
- The_Colonel 7y agoThat's just word play.
- fortytw2 7y agoI absolutely agree. The one time I had the great misfortune of building software for windows I was extremely happy to see Go worked at all. Linux and OS X largely work the same way due to their shared Unix-ness and pretty much everyone I’ve ever met or talked with uses Go on one of those two platforms. If you have to develop software primarily for Windows, maybe don’t use Go - it’s easily the least actively maintained OS target and there are many options for languages that are well supported on Windows by vendors who actually care. Kind of the same folly as trying to write an iOS app not in Swift or ObjC and then complaining it doesn’t work well.
- kodablah 7y ago2/3rds about platform FS incompat, last third about only a couple of things like time comparisons being monotonic now (does more good than bad IMO). I suspect if issues of such importance are enough to make you want off the "wild ride", you will not find a ride suitable.
- jjoonathan 7y agoHe presented them as typical examples, not as issues of such importance as to independently make him off the "wild ride." He also compared them to alternatives that he found favorable, which specifically addresses the idea that alternatives are worse. It could be reasonable to disagree with the content of his argument, but it didn't have either of these structural problems.
- kodablah 7y ago> it didn't have either of these structural problems. Disagree...the volume/importance of grievances should be directly proportional to willingness to abandon. That a few examples can be provided isn't an indictment of the ecosystem anymore than it would be if I did the same to those the OP found favorable.
- jjoonathan 7y agoHe chose to go deep instead of broad. That was an editorial tradeoff to keep the length this side of an encyclopedia, and I don't think it's fair to criticize him for it unless you're also going to argue that the generalization he asked us to take on faith doesn't hold -- in other words, that the example he gave in which a simplifying API decision backfired is atypical. I haven't used much Go, but the bit that I've played with gave me the distinct impression that "opinionated simplification" wasn't just common, it was the defining quality of the entire language, which would strongly suggest that OP's complaint would easily generalize to a hundred other APIs. Is that not the case?
- sascha_sl 7y agoUh okay, lots of "but windows" and a few misinformed takes about the http lib (using contexts over using a client instance with a timeout set) alongside ripping apart a random package I've never used or heard of for having a huge dependency graph. Such a long article, for this?
- bfrog 7y agoI felt the same way after writing a large (100kloc) project in Go, this is back when go was 1.0 or so as well. It started off well enough, but eventually started to fail in helping me create the software I needed to make.
- earwetr 7y agoi cannot comment on v1.0 but i too work on larger project and it is tiresome to write so much code, many repetitions and the same stuff in general. but i think it is not the language that is the problem. plainly, it's just the sheer size of the project. sure, DRY and generics would help out but i guess only to you as a dev, to save some time, not to the project itself. when i jumped into the go world and have learnt that code generators are VERY popular. I hated the idea and it was a big no no. but in time I came to like it and now i am a big fan. i like to use protocol buffers and generate code from them so that i have a nice schema as single source of truth that is well documented and strongly typed. with lyft's protoc-genstar, it is very easy to write your own code generator.
- martinni 7y agoNo matter what, after 100k loc, you'll encounter language quirks that irritates you. It's a matter of how complicated it was to find and what the work around is.
- alharith 7y ago> which makes a lot of problems impossible to model accurately Impossible? > (instead, you have to fall back to reflection, which is extremely unsafe, and the API is very error-prone), Extremely unsafe? > when you make something simple, you move complexity elsewhere. Does it? Or did you, in reality, not really make it simpler? > Go says “don't worry about encodings! things are probably utf-8” Does it? https://blog.golang.org/strings https://blog.golang.org/strings It just sounds like the author is very frustrated at some seemingly minor inconsistencies (from their perspective), and the extreme language used for things that are not that extreme are evidence in my opinion. Blogging can be a good exercise to shed some frustration, I definitely understand that aspect. Not sure this needs to be shared as a good example of anything or taken in any light, other than "someone is venting."
- mushufasa 7y agomain gripe seems to be that go will "optimize for the 90% case, ignoring correctness" -- particularly leading to issues on non-unix systems like windows. That fits Go's stated goals afaik. While I understand the author ran into problems for their use-case, I did not find this rant compelling as a general criticism.
- martinni 7y agoI agree. I would rather keep things minimal and have 90% correctness, than a weird and complicated interface that's 99% right.
- defnotashton2 7y agoSame because if you try to create the % case you end up with things like ASP. NET and entity framework. Working with those for 5 years I was constantly annoyed with how far I could add super complex features only to have to unravel them to implement a simple lower level edge case. And in my experience this too easily reflects poorly on the devs "well I found a blog post for ef that does what we need in 30 seconds.." which just isn't the case. I migrated to golang and find its nuances much easier to swallow. No generics? True - write a generator for your use case. It's really not that hard..
- sagichmal 7y agoWhat a ridiculous and narrow thing to get so upset about.
- crimsonalucard 7y agoIt's not ridiculous. Functions should not be returning garbage values when an error occurs. This is the worst part of javascript and certainly it's not pleasant to uncover this in Go.
- cheese4242 7y agoClickbait title. Should be titled "Golang doesn't work well with Windows".
- jackbravo 7y agoGranted, the article is pretty long, and spends a lot of time talking about this windows pitfall that I was also about to abandon it. Then it speaks of other examples like the monotime issue which I think is a better example of what he is advocating.
- danesparza 7y agoSpecifically, the filesystem. Other parts (memory management, cross compilation, goroutines, channels, etc) work just fine.
- earwetr 7y agoi went through the pain points of Go myself but that was at the beginning when i was expecting behavior i was used to from previous language(s) and from trying to force the previously learnt norms onto Go. Reading the blog post(i wrote something similar that got a ton of views here few years ago) it sounds more like the issue is between the keyboard and the armchair, not with the language itself. As with anything else, if you don't like it, don't use it. If you like Rust, Rust away.
- dickeytk 7y ago> (Note that path/filepath violates Go naming conventions - “don't stutter” - as it includes “path” twice). That guideline is for package/content name, not package directory names. https://blog.golang.org/package-names https://blog.golang.org/package-names
- skywhopper 7y agoYeah, the author misunderstands the naming scheme which actually suggests this sort of repetition. See also, io/ioutil.
- fasterthanlime 7y agoMy mistake, I removed the relevant paragraph in the article.
- iudqnolq 7y agoI still see it, maybe cached?
- ainiriand 7y agoIf somehow we had a way of checking Golang's source and submit our desired changes...
- klohto 7y agoI seriously hate this argument. Go and have a look at the issue the golang is discussing currently. Do you seriously think that everything can be fixed by a simple request? Most of the time it wouldn't fit with the way Golang is going. It's not a critique of some bugs in Golang source code but the mentality and flow surrounding changes. Do you except the author that submitted change overhauling the whole way Golang handles Unix vs Windows would be accepted? I do not agree with the author, but that is fine. It's fine for me, understand it's not good for his use cases. Saying "duh, just submit your request" is stupid as it gets.
- ainiriand 7y agoObviously what I mentioned is just an oversimplification. I expect that when some particular piece of software (open source in this case) is causing major trouble to a big chunk of its users, they get together to fix it. In the particular case of this user, some of the problems are are really related so I can imagine that if they were widespread it would´ve been taken care of. I am sorry for using sarcasm to take a detour from my real point and I was just making some light-hearted fun about op's problem.
- klohto 7y agoApologizes for not getting the sarcasm, it seemed real enough.
- gameswithgo 7y agoA lot of people seem to be missing an overarching point, which is the benefits of a language having Sum types, so that edge cases can be represented clearly, and in a way where the consumer of the api can't fail to know they exist, and can't fail to handle them. Anyone thinking of making a new language today, should really get some familiarity with Option and Result types. They make so many things not only safer, but also nicer to use.
- fhood 7y agoI surprises me that most people here aren't up in arms in agreement with this point. Code that is silently incorrect is an absolute disaster on an enterprise level. I spend a lot of time writing seemingly redundant double and triple error checking into my code, only to have the designers of the LANGUAGE say, "yeah, most filepaths are utf-8 so seems good enough to me".
- gameswithgo 7y agooption types are spreading pretty well these days. Zig, for instance, has them, even as a low level C replacement language.
- dualogy 7y agoEven C itself has unions since forever. Optionals, enums, bools, err-or-result constructs are (highly ergonomic) sugars atop of unions.
- busterarm 7y agoThere's a huge cult of Golang being the "one true way" right now and any logic that could potentially contradict that is going to cause folks to throw the blinders up. Your point about that being a disaster in enterprise is exactly correct and I have huge misgivings about these people above writing the large majority of our software architecture. This is after we switched to Go from Java where these same people did some of the same things. Lesson not learned.
- 0xdeadbeefbabe 7y ago
- weego 7y agoIt constantly lies about how complicated real-world systems are, and optimize for the 90% case, ignoring correctness I don't know how this comment appears to come as a new thought after them using Go in production. I don't use it at all for work but that is literally my understanding of the point of Go; granular "correctness" as a trade off for the productivity it provides if you're doing things that are just on the "good path"
- crimsonalucard 7y agoRust is great it follows modern programming techniques and theory but it focuses a little too much on zero cost abstractions and because of that the abstractions are a bit complicated. Go is easy to learn but poorly designed with an incomplete type system hence all these strange issues. There is a vacuum that exists between Rust and Go. A language that utilizes modern Algebraic Data Types (like rust) but does not necessarily need to create abstractions just to make everything zero cost (like Go).
- hajile 7y agoIt's not a void. StandardML file the niche well and Ocaml is getting close (just waiting for multicore support). The issue is a company that wants to put in resources.
- jhoechtl 7y agoCame here to say OCaml wojld be the sweet spot. Sorry about multicore. It's like Perl6. A dream which will never come true or your accept F#.
- logicchains 7y agoPerl6 exists.. well, it did for a year or two until it was renamed Raku.
- lizmat 7y agoNote that Perl 6 has been very much a thing since December 2015 (first official release). However, last October it got renamed to Raku (https://raku.org https://raku.org using the #rakulang tag on social media). And it is still very much a thing. If you want to keep up to date, you should check the Rakudo Weekly News (https://rakudoweekly.blog https://rakudoweekly.blog).
- crimsonalucard 7y agoFunctional is ideal, but these languages are harder to learn and not intuitive (like rust). Outside of idealism we need a language that can be procedural simply because that is what people are use to. Something like Go with ADTs.
- fhood 7y agoThe author spent a lot of time dwelling on Window's filesystems, at which point many of the readers got bored and started commenting. There are actually a couple of excellent points in here, the majority of which relate to Go's tendency to just be silently completely wrong in its behaviors from time to time, and is absolutely packed with hidden gotchas.
- whatever_dude 7y agoThis. I like, and agree, with the conclusion, and wish more people would get to it: > Over and over, Go is a victim of its own mantra - “simplicity”. (...) > It constantly lies about how complicated real-world systems are, and optimize for the 90% case, ignoring correctness. > This fake “simplicity” runs deep in the Go ecosystem. I've always liked simplicity and on my own design, I tend to go for abstraction; trying to make it easier for consumers of my API. But nowadays more often than not I find myself preferring to be explicit about the underlying idiosyncrasies when needed. This is partly due to my recent experiences with Rust, and this post seems to concur: > Rust has the opposite problem - things look scary at first, but it's for a good reason. The problems tackled have inherent complexity, and it takes some effort to model them appropriately. In that sense, I especially like the approach to `Permissions`/`PermissionsExt` that Rust takes. It makes it clear what the tradeoffs are, and allows consumers to implement their own high-level, abstracted API without compromises.
- twic 7y agoA post about fixing Date in JavaScript got me thinking about why it took so long for languages to get good date/time APIs. I think it's because it took so long to accept that date and time really is complicated. If you sit down and work it out carefully, you end up with Joda-Time (more or less - not in all the details, but in the set of abstractions). If you balk at that and make something simpler, you make a subtly but fundamentally broken API. It took a long time for us to get comfortable with the level of complexity in Joda-Time, but now nobody thinks a serious date/time API can be substantially simpler. It sounds to me like you and the author are saying that Go does this balking systematically.
- dilap 7y agoIf you imagine a spectrum of languages from sloppy-but-"easy" to precise-but-"hard", with something like Python or Ruby way off on the left and something like Rust way off on the right, Go is sitting somewhere in the middle. And so if what you're craving is absolute precision and maximal avoidance of errors or incorrect behavior, then Go is not going to be your jam. I sympathize w/ that. That said, these specific complaints don't strike me as that bad. - Filesystem perms exposed on windows, which just no-op. This seems pretty reasonable, though! - Filesystem paths represented as str type, which is assumed to be utf8, but doesn't have to be. This also seems reasonable! If you want to check for invalid utf8 and specifically print out something special in that case, nothing in Go is stopping you from doing that. This is a classic "easy but sloppy" vs "hard but precise" tradeoff. - Timeout thing -- I'm a little confused here, or maybe not up-to-date. He says let's do things the "modern" way and pass a context to do HTTP timeouts, which apparently doesn't work, and then goes off on a 3rd party package to then fix this which has an insane dependency graph. But...if you just set the Timeout field on the http client, everything works correctly. So what's the problem? Or am I missing something?
- fhood 7y agoThe http client isn't always directly exposed. I agree with the author. Context is a per request object and timeout should be able to function on a per request basis. Client is often shared and reused, and thus not always exposed in certain design patterns. If context has a timeout why doesn't it work as you would expect? Also, now that I think about it, why does the basic http.get call mentioned in every go networking tutorial not have a default timeout?
- dilap 7y ago(I have never personally used context, so I'm not so sure what the expectations are with that.) Looking at the http docs, I don't see any reason to believe setting a context for a request would control timeouts. If the complaint is, "the http library API does not provide a way to set timeouts on a per-request basis," then OK, I guess, that's true, but I don't see why that should be a huge issue (just use different clients for the different timeout values you need). But if you really don't want to do that, it should be easy enough to access the underlying network connection and set the timeout before reading the body, though I've never done this. What Go is doing here still seems very reasonable from my perspective...
- sudhirj 7y agoMost of this rant is a disagreement of how Go handles file system differences between Unix and Windows, most of the rest is complaining about some badly written library. May be good to know if you’re dealing with any of that, but this much effort would be much better served submitting a proposal to change whatever the author is so worked up about. Either the proposal is accepted, or the Go community will provide a response if the proposal is written with due consideration.
- time0ut 7y agoBased on the title, I was expecting a post about some sort of production horror story or some difficult edge case upgrading to 1.14.
- 0xdead 7y agoSo a language doesn't work correctly when it didn't give you a guarantee that it would? Big fuckin surprise!
- h2odragon 7y agoI'm sure there's real issues; but this reads as an extended whinge on "Windows and Unix are Different and languages wrap those differently whaaa!" If you want OS interfaces that look the same wherever; then choose a portability layer that abstracts that for you.
- deleted 7y ago[deleted]
- typon 7y agoI don't understand why you would create a statically typed language but not actually take advantage of types, instead typing everything with generic types like string. Why make the user pay for complexity in types but not actually deliver their promise? This is the problem with C and Go doesn't really solve it either
- hinkley 7y agoWe just ran a pretty high profile 20 year experiment with Stringly Typed languages - Java. Generally we try to avoid the mistakes of the previous generation (and make the same ones as the one before that, half the time) so this is confusing to me. I wonder how many Android contributors he had working with him while these decisions were being made.
- terminaljunkid 7y agoThere is a sweet spot and for different people, that spot lies in different places. Having a proliferation of types is bad for everyone but highest order FP Weenies among us.
- marcus_holmes 7y agoCan we just stop with the "Rust vs Go" shit? If you want me to take a critique of Go seriously these days, pick another language to compare it to. Any other language. And yeah, I'm aware that 5 years ago there were a ton of "Go vs Java" articles. I didn't think much of them then, either.
- asdkhadsj 7y agoIt's not, imo. It's an example of extremely differing philosophies - of which Rust is a great example of the opposite spectrum of Go. I imagine there may be a couple other examples, maybe something like Haskell (I wouldn't know), but I'm guessing the author just knew Rust better for this comparison. It's easier to illustrate problems that shouldn't be problems (in your eyes) if you have solutions for them - especially solutions that you believe work well. Rust's take on these nitpicks is something that the author clearly thinks Go is lacking on. In my view, this post is a critique on Go and the "simplicity" mantra it has; and only that.
- marcus_holmes 7y agoI'd buy that if there hadn't been approximately 48764576459674 "Rust vs Go" (well, more usually "this is why Rust is way better than Go and you're some kind of moron if you're not switching to Rust today") articles in the last few months.
- asdkhadsj 7y agoOkay, let me ask this then - what language would be better compared to contrast the shortcomings of Go that the other takes issue with? Certainly not C++, no?
- marcus_holmes 7y agoIn 5 years' time, when there are a gazillion "Rust vs ${Nim}" articles out there, extolling the virtues of another language and pointing out the shortcomings of Rust, then let's ask this question again. I'm not questioning the critique - no language is perfect, and Go certainly has its share of problems. I'm questioning the sudden rash of "Rust is awesome, Go is shit" articles over the last few months. It's not a good thing.
- miguelmota 7y agoGo is my favorite language but I do agree that Windows support has always felt like an afterthought.
- tyrankh 7y agoI think this post summarizes to, - I don't like the file-related packages - What's up with this random 7 star library having a lot of transitive dependencies - Rust for life - In summation, Go is the worst
- fasterthanlime 7y agoNot that this is a good faith summary, but I've updated the article to point out that it's not just "this random 7-star library", but in fact, 266 publicly-available Go packages.
- cdelsolar 7y agoYour rant largely has to do with a library someone wrote that did not handle dependencies well. A few years ago you would have complained about lack of module support at all. I have a toy project that's relatively simple, and the Javascript frontend has a lockfile that is literally over 10000 lines long.
- filleduchaos 7y ago> Your rant largely has to do with a library someone wrote that did not handle dependencies well I am rather curious about how you concluded that "lots of dependencies bad" was the point of that section of the article and not, perhaps, the absurdity of having to compile an empty file to get around the solution to a bug being hidden from end developers.
- fasterthanlime 7y agoI was already shipping Go code a few years ago, and the various vendoring tools gave me a lot less grief the new module system has. Besides, it still had all the same limitations, the same standard library choices, the same sloppy abstractions. The rant applied then and it applies now - and focuses not on any specific problem outlined in the article, but the general philosophy of the language, its standard library, and its ecosystem.
- pcj-github 7y ago
- Thaxll 7y ago"With a Go function, if you ignore the returned error, you still get the result - most probably a null pointer." Well you should handle the error in the first place.
- Seenso 7y ago> Well you should handle the error in the first place. That's like saying you should just write bug-free code in the first place.
- Karunamon 7y agoGo goes out of its way to ensure you handle the error. You have to do something with that err return, otherwise it's a compile error. If you're just throwing it away without checking, we've gone from the mere mistakes everyday developers make to irresponsibility. There's a reason most go code is littered with "if err != nil" on nearly all function calls.
- hota_mazi 7y agoGo does absolutely nothing to ensure you handle the error. The only thing in Go source code that you see more often than the boiler plate "if err != nil" is "a, _ = foo()". It's all too easy to ignore an error in Go.
- Sphax 7y ago> The only thing in Go source code that you see more often than the boiler plate "if err != nil" is "a, _ = foo()". Where did you see that ? because that's not been my experience at all, and I've looked at a lot of Go code.
- shazow 7y ago> Go does absolutely nothing to ensure you handle the error. Go has many community linters available, https://github.com/kisielk/errcheck https://github.com/kisielk/errcheck is popular for checking unhandled errors. If you'd like a combo-pack, check out https://github.com/golangci/golangci-lint https://github.com/golangci/golangci-lint which includes all of the popular linters in a configurable way.
- madhadron 7y ago> The Go way is to half-ass things. This used to be known as the New Jersey school, and is the underlying philosophy of Unix: build a bunch of little pieces that work a lot of the time and kind of fit together if you remember the gotchas, then call it a day. There is an essay on this that I am unable to locate right now which mentions the horror of someone working on ITS when they asked how Unix solved a rollback on error case in a system call and were told, "Oh, we just leave it inconsistent, and the application programmer has to deal with it." Does anyone else remember this citation? I truly am failing to find it this morning.
- skrebbel 7y agoSounds like it might be straight from the original "worse is better" essay: http://dreamsongs.com/RiseOfWorseIsBetter.html http://dreamsongs.com/RiseOfWorseIsBetter.html > The MIT guy did not see any code that handled this case and asked the New Jersey guy how the problem was handled. The New Jersey guy said that the Unix folks were aware of the problem, but the solution was for the system routine to always finish, but sometimes an error code would be returned that signaled that the system routine had failed to complete its action. A correct user program, then, had to check the error code to determine whether to simply try the system routine again. The MIT guy did not like this solution because it was not the right thing.
- simscitizen 7y agohttps://en.m.wikipedia.org/wiki/Worse_is_better https://en.m.wikipedia.org/wiki/Worse_is_better And I happen to agree with it.
- ptah 7y agoi think your problem is with windows, not go
- kissgyorgy 7y agoIf you don't care about Windows, half of the rant is just not interesting for you. So even if you accept that he is right in every single point, excluding those parts there these are not a lot of problems. EVERY language has problems, even Rust.
- whateveracct 7y agoHere's an example of why Go's simplicity is complicated: Say I want to take a uuid.UUID [1] and use it as my id type for some database structs. At first, I just use naked UUIDs as the struct field types, but as my project grows, I find that it would be nice to give them all unique types to both avoid mixups and to make all my query functions clearer as to which id they are using. type DogId uuid.UUID type CatId uuid.UUID I go to run my tests (thank goodness I have tests for my queries) and everything breaks! Postgres is complaining that I'm trying to use bytes as a UUID. What gives? When I remove the type definition and use naked UUIDs, it works fine! The issue is Go encourages reflection for this use-case. The Scan() and Value() methods of a type tell the sql driver how to (de)serialize the type. uuid.UUID has those methods, but when I use a type definition around UUID, it loses those methods. So the correct way to wrap a UUID to use in your DB is this: type DogId struct { uuid.UUID } type CatId struct { uuid.UUID } Go promised me that I wouldn't have to deal with such weird specific knowledge of its semantics. But alas I always do. [1] https://github.com/google/uuid https://github.com/google/uuid EDIT: This issue also affects encoding/json. You can see it in this playground for yourself! https://play.golang.org/p/erfcSIe-Z7b https://play.golang.org/p/erfcSIe-Z7b EDIT: I wrongly used type aliases in the original example, but my issue is with type definitions (`type X Y` instead of `type X = Y`). So all you commenters saying that I did the wrong thing, have another look!
- skrtskrt 7y agoI'm not sure, I kind of like this? Personally I would never create different UUID types for each DB struct, and have never seen that done. type DogId struct { uuid.UUID } is type composition (Sorry if I'm not using the right term there). Isn't this exactly how you're supposed to do what you're trying to do in Go?
- hajile 7y agoIs there even a single go abstraction that doesn't leak it's guts everywhere?
- thedance 7y agoThere aren't any abstractions in any language or library that don't leak everything about what they are trying to hide as well as everything about their own implementation. That's just life. It's impossible to hide complexity. Whatever wraps one thing will be strictly more complex than the wrapped thing was.
- carapace 7y ago> Computers, operating systems, networks are a hot mess. They're barely manageable, even if you know a decent amount about what you're doing. Nine out of ten software engineers agree: it's a miracle anything works at all. I like that he identified the real problem right at the start.
- 0xdeadbeefbabe 7y agoYeah so do I. It would have made a nice tweet.
- DLA 7y agoWindows-focused rant. Plus a few reasonable points. Every language is complex at some level and in their own ways-Rust included. Every language hides some of the complexity of layers below it like assembly and thus hides hardware details. Computers are complex. Point granted. Fact is Go is a very reasonable set of compromises that let's real enterprise-scale work get done and run with solid performance. I've done work on mostly Nix systems but have cross-compiled for Windows when needed. These are wildly different OSes and some adjustments are needed thusly in the code. Go has faults. The "OMG Go has no generics so it's total trash" argument is just silly. Generics are coming. Personally, Go has never let me down with anything I've asked it to do -- ETL flows, servers, streaming data processing, CLI programs, networking tools, etc. Use whatever tool fits your needs.
- HideousKojima 7y ago>Go has faults. The "OMG Go has no generics so it's total trash" argument is just silly. Generics are coming. Until it has them it's a valid complaint. And the fact that they're finally coming 11 years after the language's creation is another matter
- throwaway894345 7y agoThis is silly. Lots of people are very productive in Go without generics. Even more productive than many languages that have generics (including Rust). Lots of people are very productive in languages without static typing at all. Generics will significantly improve a relatively small proportion of use cases.
- jimsmart 7y agoFWIW: Java was originally released in 1996, it had no generics, and didn't gain them until 2004 - 8 years after the language's creation. Was Java "total trash" before 2004? Not really, it was still useful in lots of use cases - it just didn't have any generics. Go at least has generics for its built-in collection types (maps, slices) - which, in that respect, arguably places it ahead of where Java was for a whole 8 years. https://en.wikipedia.org/wiki/Generics_in_Java https://en.wikipedia.org/wiki/Generics_in_Java
- gavinray 7y agoHoly shit, the entire explanation of the absurd reasoning behind needing to use the getlantern/idletiming lib, and the debacle behind unraveling it's dependencies is pure gold. When the breadcrumb trail to dependency-hell stems from a file whose contents are: // This file is intentionally empty. // It's a workaround for https://github.com/golang/go/issues/15006 I about fell out of my chair. Pure gold.
- Liru 7y agoMy most popular project on Github is currently a program I slapped together in Go a long time ago. The `sync/atomic` issue mentioned at the end of the article is THE issue that made me stop considering Go for anything other than trivial things. Lack of decent error handling, a terrible builtin json library, constant `interface{}` to poorly substitute for generics, the package management issues that made Node.js look well-thought-out by comparison, struct field tags, and generators provided by the core team that set off linters provided by the core team with no good way to silence them kind of piled on before that, but the `atomic` issue is the one that made me avoid it. The author is right, all the little things add up. Note that a bunch of these may have been fixed since I last used it, but honestly, I haven't checked because it was frustrating working in it and debugging it. It's a shame, `pprof` and the race detector are pretty cool.
- terminaljunkid 7y agoTL;DR I am on Windows and Go doesn't play well with its weird filesystem. It is all Go's fault for relying on highly used server OS semantics and therefore Go's simplicity is lie.
- shadowgovt 7y agoIt's a pretty good article. The tl;dr is that golang is a POSIX-focused application programming language that is incorrectly advertised as a platform-agnostic systems programming language.
- flohofwoe 7y agoIsn't basically all of this shortcomings of Go's standard library, not "Go the language"? The Go standard seems to be heavily geared towards doing work on the server-side, and "server-side" essentially means "Linux" today. If I'd need to write "client-side" cross-platform code that also needs to run on Windows, Go wouldn't be my first choice, also not my second or third. And TBH, most other languages are not that much better (Python might be the only notable exception, and even this requires different code paths for "Windows vs the rest of the world" here and there). For this type of cross-platform code, it's almost always better to talk directly to the underlying OS APIs and put those under a thin custom wrapper library instead of relying on the language's standard library.
- pdq 7y agoGood point. Also, client side in Go is usually web interfaces, which work across any platform.
- fasterthanlime 7y agoA standard library says a lot about the language. Even if someone made a much better path/file handling library for Go, another one of its strengths are the ubiquitous interfaces you can rely on across libraries. Unless the superior library gained a lot of adoption really quickly, it would remain largely irrelevant in the face of the standard that was set years ago by the Go authors.
- throwaway894345 7y agoLook at Go’s HTTP library. It’s much lauded for striking a good balance between performance and ease of use, but it’s not as performant as it could be. For that, fasthttp exists and is quite popular although not nearly as popular as the standard HTTP library. Your comment gives the impression that this is a failure because the library for niche performance cases hasn’t become the go-to library for the general case. I disagree—it’s ideal that we have a canonical general purpose library and another for high performance cases. Perhaps you would argue that we should have interfaces that allow for a pluggable performant implementation and an easy-to-use general purpose implementation? This is all well and good, but it’s inherently not possible, because the interface is about ease-of-use and the performance is achieved by trading off on friendliness. You might offer Rust as a counterpoint since many of its standard libraries use an interface that is suitable for the general case and the high performance cases; however, this is a lie: these interfaces (and the core language) are manifold harder to use than their Go equivalents. In other words, Rust’s “general purpose” interfaces trade ease of use for the ability to support high performance implementations. This tradeoff isn’t inherently bad, but it is bad to pretend as though it’s inherently good or that there is no tradeoff at all.
- pmarreck 7y agoGo needs good criticisms like this. I will never understand why this language is so popular.
- bsdubernerd 7y agoIt's due to the same reason Rust is: it's backed by a large popular company investing in the language and being loud about it, which leads to a rapidly growing mindshare and ecosystem around it, which is essential for adoption. This is not meant as a criticism toward go or rust: the history shows several cases where this happened before irregardless of the technical merits. A language still needs to become popular, it's not like we're lacking great languages nowdays. It's certainly easier if you're big and can provide the founding around it.
- AnimalMuppet 7y agoThe backing can get you publicity. If the language is lousy, though, the publicity won't help it. But publicity can turn an obscure good language into a well-known good language. I think the bigger thing that corporate support gets you, though, is a better library (more complete, more debugged, and more polished). That is an essential ingredient for language popularity. Up through Java, it was enough. But these days, I think that there's one more ingredient needed: Solve some problem that isn't well-solved in other existing popular languages. Go has pretty good answers on multiple threads and network services. Rust has the borrow checker. Those are useful enough pieces to gain traction for those languages.
- klodolph 7y agoWith the path example… just try to combine this with flags, so we do something like: $ ./my_program --file="$(printf "\xbd\xb2\x3d\xbc\x20\xe2\x8c\x98")" Well, just try to write the program that does that in Rust, without using some option-parsing library that hides all the details, and then try to figure out how to get it to work equally on Windows. To spoil the answer, it turns out that OsString only exposes a couple conversion routines and can’t be manipulated, and people have been trying to figure out a way to add a string-like API to it for years. Rust’s “do it the right way even if that exposes lots of complexity” approach here has its drawbacks.
- tedmielczarek 7y agoThe point isn't that it should be easy to do terrible broken things like this. The point is that you will encounter these things in the real world and have to deal with them in some way. Rust's OsStr[ing] let you do that. If you really have a burning need to create files whose paths are not valid Unicode you can do that in Rust but you will have to jump through some hoops. I don't see that as a problem.
- klodolph 7y agoI’m not saying that it should be easy, just that the API shouldn’t introduce significant amounts of additional complexity. For the very simple case of "I want a command-line option which specifies a path as an OsString", Rust’s way of doing things makes things hard. By comparison, in C++, I am used to dealing with paths as std::string on Unix and std::wstring or std::u16string on Windows, and this C++ approach is a lot easier. Rust’s OsString design is too smart by half, and if I use env::args_os(), I can’t easily do simple tasks like "test if this string starts with '-'" or "split this string by the first '=', if it exists". As far as I can tell, the way to go is to convert OsString to Vec<u8>, do your processing there, and then convert back… but that only works on Unix, because arbitrary Vec<u8> aren’t safe to convert back to OsString on Windows because they may not be valid WTF-8. So you can take the approach on Windows of going through encode_wide().collect() and it just goes downhill from there. :-(
- 7y ago
- fortran77 7y ago> So, no errors. Chmod just silently does… nothing. Which is reasonably - there's no equivalent to the “executable bit” for files on Windows. It's simply not true that Windows doesn't have "execute permissions" for files. It does: https://docs.microsoft.com/en-us/windows/win32/fileio/file-security-and-access-rights https://docs.microsoft.com/en-us/windows/win32/fileio/file-s... It's just that the people who wrote the go library couldn't be bothered to abstract this interface across all platforms.
- mehrdadn 7y ago+1 came here to say the same thing. This seems more like a problem with the standard library authors not putting in enough effort than anything else.
- pcj-github 7y agoGot really tired and bored with this. Maybe structure the article with some sort of meaningful abstract so that you can summarize the points you want to make up front without having to subject the reader to 9/10ths of this article.
- bsimpson 7y ago> Nine out of ten software engineers agree: it's a miracle anything works at all There was a beautiful rant about a decade ago called something like "everything's broken all the time and nobody cares." The gist of it is that all software is written by people. Anyone who's written software knows that it's usually riddled with hidden corner cases, unfortunate tradeoffs, rushed deadlines, etc. Software is also moving into critical spaces like aerospace, medicine, banking, etc. The thrust of the article is that we're trusting more-and-more critical infrastructure to a discipline that anyone who's worked in knows is untrustworthy. Does anyone remember the link to the article? I've often wanted to re-read it and share it with people, but I've never been able to find it.
- saityi 7y agoThe first article that comes to mind for me is Programming Sucks, although it's not quite the same as your description. https://www.stilldrinking.org/programming-sucks https://www.stilldrinking.org/programming-sucks
- krallja 7y agohttps://medium.com/message/everything-is-broken-81e5f33a24e1 https://medium.com/message/everything-is-broken-81e5f33a24e1 ?
- adamch 7y agoI think you're thinking of Everything Is Broken by Quinn Norton https://medium.com/message/everything-is-broken-81e5f33a24e1 https://medium.com/message/everything-is-broken-81e5f33a24e1
- temac 7y ago> Software is also moving into critical spaces like aerospace, medicine, banking, etc. The thrust of the article is that we're trusting more-and-more critical infrastructure to a discipline that anyone who's worked in knows is untrustworthy. "Anyone" who's worked in those industries knows SW can be done in a trustworthy way. At least not less than other engineering disciplines. "hidden corner cases, unfortunate tradeoffs, rushed deadlines" in uncontrolled proportions are a symptom of lack of discipline, either originating directly at low level (even if maybe mainly because of cultural influences, but I mean, what is not?), or under pressure from the hierarchy. The same conditions can led to critical failures of other kind of engineering realisations. One key point of critical failures resulting from hierarchy pressure is that it does not absolves the engineers doing the work, and some engineering culture actually recognize and teach that. Other cultures mixe everything in the same pot without even an once of ethics nor serious reliability thinking, and you get people maintaining the myth that software just can't be reliable, that the whole industry - without exception - is in an eternal crisis, and that that's even normal because the field is "young". None of that is true; you even have plenty examples around you, and decades of history to study. And of course, we must remain exigent so that the quality does not decline just because of a kind of self prophecy.
- totalperspectiv 7y agoMy main takeaway is the quote from scottlamb: > ... these sorts of statements contribute to my belief that Go is an opinionated language that I should hesitate to choose for anything that the language's authors haven't specifically considered in depth.
- draw_down 7y agoI think this is a great, in-depth examination of why your spidey senses should be tingling when you hear about something being "simple". "Simple" at this point means "something I like", and "complexity" are all the things I don't like.
- sitzkrieg 7y agoi wrote go professionally on a project for a year in a single very intense push, and i was burned by every single thing listed in the article. felt like uphill impedance mismatch the whole way. its nice to see it articulated well
- donatj 7y ago> burned by every single thing listed in the article Really? That seems absolutely bizarre to me, I've been writing it professionally for ~8 years now and never hit… any of these. I mean I basically never interact with Windows on any level, but none of this has ever bit me.
- sitzkrieg 7y agothis was cross platform forensics software ripe with edge cases
- irrational 7y ago>when you make something simple, you move complexity elsewhere. This applies to so many things. I wish I could get non-technical people to understand that making something simple moves the complexity elsewhere.
- joeldg 7y agoThe short of this seems to be that golang isn't a scripting language which is what the author seems to need. Maybe I am wrong here but it sounds like he got a hammer and decided everything was nails and painted (hammered) himself into a corner. He could always submit a PR on all the windows specifics he is discussing, but those are not going to be priority for most people in my experience.
- SpaceManNabs 7y agoI have become annoyed at go for completely different reasons than OP. I wrote my blog using go as the backend a few years ago. Deployed it on Google App Engine. Every time Go updates or the App Engine SDK updates, it is a super pain to update my site. I almost want to throw it all away now that Go is handling dependencies in a completely new matter.
- deleted 7y ago[deleted]
- tschellenbach 7y ago2+ years on Go, 13 years on Python and JS. Some Kotlin and Java as well. Go is by far the best programming language you can find to build scalable microservices. Hands down, years ahead of anything else.
- zemnmez 7y agoi cant help but feel Go is the new Javascript. Everyone wants to complain about how its semantics as a language do not align with their favorite programming paradigm. In this case, having complex, algebraic type-based abstractions that attempt to accurately reflect subtleties that are rarely important. Yes, Go, as Javascript has unique failure cases and subtleties, but they are (as of 2020) very productive languages within their particular paradigms. That's not to say either language is beyond criticism, of course. But it's a little silly to think that a language that supports the 99.9% of writing a service well, but does the .1% badly as a tradeoff for simplicity is a fundamentally broken language because it doesn't share those aspirations. We might as well be complaining about the lack of pointer arithmetic in Python.
- reggieband 7y agoClassic: “There are only two kinds of languages: the ones people complain about and the ones nobody uses.”[1] The thing that bugs me is the comparison to Rust. I mean, the author did caveat that he chose it because Rust provided the best available counter examples to his specific gripes. But my issue is that comparison seems to make a false conclusion: Rust is better. My intuition says if the author used Rust (or any other language) as much as they have used Go, and in the same environments solving similar sized problems, they would have a completely different 1000+ word rant on all the things they hate about that language. We have an expression "use in anger". It describes a particular kind of understanding that only becomes available when we face the real problems and not just idealized ones. I even see smaller rants within this comment section showing how the very systems he lauds in Rust have sharp corners when used in anger. I thought this rant had many good points and highlights many shortcomings of Go. I would have preferred that it did not contain the comparison which draws an implicit conclusion that IMO is likely incorrect. 1. https://www.goodreads.com/quotes/226225-there-are-only-two-kinds-of-languages-the-ones-people https://www.goodreads.com/quotes/226225-there-are-only-two-k...
- eximius 7y agoRust is better _at the problem presented_. Rust not being perfect does not mean other languages can learn from its successes.
- reggieband 7y ago> Rust is better _at the problem presented_. What I'm suggesting is that wasn't demonstrated. Go had a real-world used-in-anger problem. That was compared to an idealized solution in Rust. It seems to me that this is an unfair comparison. Fair enough, it is hard to demand anyone who wishes to make a comparison between two programming languages to have built equivalent massive systems that stretch each language to their limits. But the point of the article wasn't to compare languages, it was to show the kinds of problems exposed in Go when it is used in massive real-world systems. So maybe it would have been better to leave the comparison out.
- 7y ago
- _wldu 7y agoArticles like this are evidence of Go's huge success.
- altmind 7y ago50 Shades of Go: Traps, Gotchas, and Common Mistakes for New Golang Devs, a good read about go quirks and unexpected behaviors http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang/ http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in...
- ungerik 7y agoI wanted a little bit more from FS department, so I rolled my own: https://github.com/ungerik/go-fs https://github.com/ungerik/go-fs
- jbverschoor 7y agoHaha
- lanius 7y agoFor those unaware, the title is a reference to a hilariously long user-created ride in Roller Coaster Tycoon 2 titled "MR BONES WILD RIDE" [1]. The ride's exit connected to its entrance, so passengers were forced to repeatedly ride the roller coaster forever. [1] https://knowyourmeme.com/memes/mr-bones-wild-ride https://knowyourmeme.com/memes/mr-bones-wild-ride
- CameronNemo 7y agoHave you not heard of Mr. Toad's Wild Ride?
- dellinspiron 7y ago(Comparing a function in Rust's sdtlib to Go's:) > Of course there's a learning curve. Of course there's more concepts involved than just throwing for loops at byte slices and seeing what sticks, like the Go library does. > But the result is a high-performance, reliable and type-safe library. > It's worth it. When I first saw Go, I was blown away. Not by its features, but rather the lack thereof. It seemed like one last "Hail Mary!" from the C programming community to get "back to basics". But, as the author showcases, the time when programming was about manipulating arrays with pointers is, if not behind us, hopefully on its way out.
- dellinspiron 7y agoComparing Rust to Go: > Of course there's a learning curve. Of course there's more concepts involved than just throwing for loops at byte slices and seeing what sticks, like the Go library does. > But the result is a high-performance, reliable and type-safe library. > It's worth it.
- ggm 7y agoScuolo di Michaelangelo "god, this Carrera marble is so hard to work in why can't we just pour concrete into rubber moulds like the garden gnome factory next door" Michelangelo "fine, I thought you wanted to learn how to sculpt perfect buttocks but whatever" Jeff Koons "that garden gnome idea, how about now I know how to carve Carrera marble I make one in marble" Scuolo ..."Jeff.. we hate you" The GO authors are gifted. They make tools gifted people understand. If you aren't gifted, they are difficult tools to use. (I'm not gifted btw)
- luord 7y agoI kept waiting for practical examples that showed how these shortcomings made go a non-starter, and ultimately all I got was a mention, right at the end, about how he hit a particular bug multiple times. I mean, currently I work in a go shop and I hate nearly everything about it, all just from what he calls "the bad", which is enough to make me not feel precisely happy about writing it. The content of this article, what he calls "the ugly", comes across as a bit nitpicky in comparison. Nonetheless, it is a good article about string and path handling, time, and being irresponsible with what one is depending on.
- physicles 7y agoHaving used go full-time for the last 3.5 years, this article didn’t feel like a twist of the knife. Yet all the language evolution efforts I’ve seen in the last two years make me think that early Go was, mixaphorically speaking, lightning in a bottle that won’t strike twice. - I’ve never hit the file system stuff. We all use Linux; all our code runs on Linux. I’m curious who the people are who are using Go on Windows. - Network timeouts are a stupid gotcha I first hit about six months into my go tenure. You can set read/write timeouts on the Transport that’s used by the connection though; not sure why that isn’t covered. - The wall clock time thing is new to me and looks crazy complicated; I’m angry that it’s something I have to know about now. It’s bad enough that time.Time operator == and .Equals() behave mostly but not quite the same. Something that’s not in the article: the tooling situation (autocomplete, source navigation, and so forth) IS STILL WORSE THAN IT WAS TWO YEARS AGO. The old tools were perfect but were never updated for module support. gopls is still an unfinished mess; last week I had to write a script that auto-kills it if it uses more than 3GB of memory.
- 7532yahoogmail 7y agoI'm c/c++ over 20 years, go 1 year, Python 5+ years. I work at a company with a guy on the c++ standards committee with the internal sdlc and engineering training for large scale, commercial systems to boot. This article is a rant. Not an engineering take down of go. There's just not much of substance here. Were I to care about windows (I don't) for serious cross platform os interaction, go isn't your hammer of choice. I've turned to go recently for some I/O heavy apps of a micro-service type which it is fine for. I also turned to go because of God awful c++ build times and bad build systems in the sense that they assume all code is in a single branch. By switching to go I also prevent less experienced programmers from linking in legacy c++ libraries and the evil that comes with them. Go has delivered. My needs are such that protobuf/flatbuffer are good enough for types and go's lack of generics is irrelevant. I'm pushing bytes across a network pipe in which each message admits simple transforms/operations. Now I am keeping my eye on three things that I think go could burn me on: - garbage collection - channels ... cool but slow - something unixy/multicore/close to the bare metal ... Like kv store Those things I'd be reticent about doing in go. Folks, we need 2-4 languages with their connections to libraries and tool chains in our toolbox. While we remain dominated by c++ (a complex beast of a language) I am looking to add a functional language to my kit (ocaml/Haskell). Btw good engineers need a formal language too. I recommend tla+ and there's a guy in hacker news here that's got good books on it. Recommended! Highly concurrent code ought to modeled in tla+ first before leaving your app language gun and taking the canolli. Cheers
- kkredit 7y agoThis is an excellent example of Waterbed Theory: "This is a theory which says that if you push down the complexity in one part of a language or tool, there is a compensation which increases the complexity of another part of the language or tool." http://wiki.c2.com/?WaterbedTheory http://wiki.c2.com/?WaterbedTheory
- madmax96 7y agoI think its worth pointing out that the Rust code is more broken than the Go code in this example. Because Rust is trying to come up with a sane way to display the filename (a) it prevents users from using encodings the language designers did not anticipate and (b) it prevents the solution from integrating with other system tools. For instance, you can't run `rm "$(rust_program)"`, but you can with the Go solution. But discussing any of this means you've missed the point of languages like Go. Instead of arguing about the best way to to represent pathnames that aren't a valid byte sequence under $PREFERRED_LOCALE, we should be talking to our customers and solving their problems.
- philpearl1 7y agogetlantern/idletiming has 9 stars and 2 forks. This is not something the general Go community uses
- GiantSully 7y agoGo is an opinionated language, but opinion is not just right or wrong, and it’s getting complicated with time passing by. Opinion might be prejudice. Anyway, I like the multiplexing and go routine in go.
- donatj 7y agoI'm late to the show here, but I think the whole argument around filepaths needing to potentially be encoded before being presented to end users is a non-issue / how most languages I've worked in have handled it? Does rust have some fancy handling? Sure? Is it syntactic sugar? Absolutely. Maybe I've been working in Web too long, but encoding a value before handing it to the user seems second nature.