14 ms·
Go Is a Shop-built Jig (2014)
- stouset 8y agoThe title of this submission reads like a No True Scotsman fallacy.
- otterley 8y agoFlagged for changing the blog post subject to clickbait.
- draw_down 8y agoCome on.
- mda 8y agoit impossible to not roll my eyes when i read such a title.
- amzans 8y agoEdit: I had used a quote from the blog post as the title, but updated it to match the blog post as I realised it was a mistake. The original title was: "Go feels under-engineered because it only solves real problems".
- jmull 8y agoI think this is from 2014? Anyway, it hardly seems fair to give yourself choices (by introducing that “LlamaKit” library) and then criticizing Swift because there’s different ways to approach the problem. (And I wonder if LlamaKit does anything besides obfuscate code? Hopefully I’m just missing some context.)
- tptacek 8y agoHe's not criticizing Swift. He's a Swift programmer who prefers working in Swift to working in Go.
- tptacek 8y agoI've always felt this is one of the better characterizations of Go. Great programming tool. Not an especially great programming language. A lot of the time, more than we acknowledge in PL slapfights, that's what you really want. And, sometimes, being in an efficient but limited language allows you to focus better on your problem domain, which can be useful creatively.
- gok 8y agoOn Go-the-language, I agree. It takes a few things from PL design that have widely been shown to be helpful and packages them up in a simple language that C/Java programmers can use to be productive in an hour or so. The implementation is a different story. It was really goofy to implement a new compiler backend, garbage collector, scheduler, calling conventions, and hey, why not make have the standard library make syscalls directly, what could possibly go wrong? The result has been the last several years has largely been spent reimplementing solved problems (basic compiler optimizations, a GC which is competitive with JVMs from 15 years ago, etc) rather than actually evolving the language. In short, I wish they'd stuck with their "just do a few things well" philosophy in both language design and implementation.
- dullgiulio 8y agoGo has never been a single implementation language. It had a GCC backend since the start. GC (Go Compiler) has very peculiar characteristics: for one thing, it's written in Go itself. Another important thing is that it's very fast. That was an objective since the beginning of the Go project. Finally, comparison with Java GC (garbage collection) are quite nonsense as Go has a very different allocation pattern than Java software.
- zippoxer 8y agoOne of Go's features is fast compilation, which wouldn't have been the case if it used LLVM. > a GC which is competitive with JVMs from 15 years ago I don't know where you got this impression, but it's absolutely wrong. Go's garbage collector is excellent. It has sub-millisecond pauses [1] (for multi-gig heaps), and it mostly runs in parallel to the application. You might be referring to Go's old GC, which was dropped when the current was introduced. [2] [1] https://groups.google.com/forum/?fromgroups#!topic/golang-dev/Ab1sFeoZg_8 https://groups.google.com/forum/?fromgroups#!topic/golang-de... [2] https://blog.golang.org/go15gc https://blog.golang.org/go15gc
- nine_k 8y ago> I would rather spend my time writing generic, elegant functions that help developers think deeply and correctly about their programs. Like Alex, falling back on for-loops and mutable state makes me feel like a bad programmer. But there is a certain tension between all that and shipping things today. (Emph. mine) It hits the nail on the head: there's a certain tension between speed and correctness. For some, there's never enough time to do the right thing, but always (inevitably) enough time to keep fixing a wrong thing. There are also diminishing returns of typing imperative code fast top to bottom, but having to deal with constant boilerplate and manually checking things that a machine could check, were the language more expressive. Somebody called Go "systems PHP"; I think it's very fitting.
- jrs95 8y agoEhhh I dunno about the PHP thing. I can see what you mean, but there’s a certain negative implication to it which isn’t accurate. PHP is bad because it’s inconsistent and doesn’t really have a coherent design. You can tell that it evolves by having things bolted on to it, and there’s all sorts of weird dark corners. Go really isn’t like that at all.
- nine_k 8y agoComparing to PHP, I mostly mean the mindset: the no-frills, "just code it in a few hours" approach. Solving the problem with the minimum care of any abstraction. It works pretty well for simple scripts. The problem is, of course, that the scope grows, and with it, the need for more powerful tools. Go does not have C's macros (phew), but has nothing else either, so people end up writing code generators.
- jrs95 8y agoAhh okay, I get it. This is pretty accurate. I do think they arrived to that from different places though. PHP being more about getting shit done and iterating quickly, and Go having the opinion that the wrong abstraction is worse than no abstraction at all. In Go’s case, it’s more of a reaction against the overuse of abstraction and GoF patterns in C++/Java/C# IMO.
- wejick 8y agoThis is exactly what I feel when using Go. Love the way I can really focus on solving real problem rather than trivial (but important things like styling and formatting). About generic, when I thought need it, I always able to find simpler design using composition.
- coldtea 8y ago>About generic, when I thought need it, I always able to find simpler design using composition. How exactly would composition help you e.g. make a general purpose reusable math library for different kinds of numeric types?
- jitl 8y agoI think the implicit argument is that “a general purpose reusable math library for different kinds of numeric types” is not a real problem. A real problem is, “I need to draw this triangle”, and using math.Cos w/ float64s works just fine.
- coldtea 8y agoAnd yet it's a problem anybody who makes any kind of library that should work with > 1 types, faces... Not just math and scientific libraries. Even a simple reusable data structure. And fact it's so commonly needed for this, that Go's slices and maps would have been useless unless Go's designers have not cheated and used genericity for themselves... And let's not get into reusable abstractions for behavior -- like a library that encapsulates the 5-10 more common uses for channels and goroutines (span N goroutines and wait for all to collect the results, span N and use first result, and so on).
- wejick 8y agoYou could say my usecase is on different scope than that. But I still on the against side of the generic. It will add (for me unnecessary) complexity to the language. Cmiiw even when have generic in place, we still need to write the code for each type right? Just the interface is the same. (this argument sounds silly actually, just want to say that)
- teddyh 8y agoGo might be nice and all, but I could probably never in good conscience use it seriously, for one simple reason: It’s dominated by Google. It was started by Google, and all of its core development (I assume) is done by Google people, with Google’s blessing. It’s even named for the company, making the ownership transparent and obvious to all. With something like C, C++, Lisp, Python or the like, you know that even if some large company abandons it, it probably won’t even make the headlines, since it won’t matter much for the rest of the users of the language – it has a large enough user base that the language will be fine. But what if the controlling company decided to abandon Dart, Swift, C#, Go, etc.? It would kill the language in an instant. Or if they decided to simply take the language in a new direction more suited to the company but contrary to the wishes of its global user base? I can’t work under those conditions, and neither should anyone else accept to do so. To clarify: If, say, at least two thirds majority of the development of the language was no longer done by a controlling company (and if the supposedly non-affiliated developers were not also all incidentally employed by the same company), and, in the case of Go, the name was changed, I would probably not have a problem with using any of the aforementioned languages. P.S. Rust is a slightly special case, since it’s dominated not by a company, but by the Mozilla Foundation, making it slightly more dependable than an arbitrary company.
- coldtea 8y ago>Go might be nice and all, but I could probably never in good conscience use it seriously, for one simple reason: It’s dominated by Google. It was started by Google, and all of its core development (I assume) is done by Google people, with Google’s blessing. I don't think Google is particularly the problem here. Go has lots of people working on and with it from outside Google. The problem is that the core team is very resistant to any kind of outside ideas (while not being always brilliant with their ideas to compensate) -- and the community has fossilised to those loving the same ideas as well. It encourages a groupthink that's not there in other languages. Contrast with e.g. Swift, which while run by Apple, has a great community participation story (to the point to going into too much bikeshedding).
- p_l 8y ago
- venning 8y agoThis article contains a dead link in the third paragraph marked as "bugs the lead language designer". Here is an archive.org link from the same time period: https://web.archive.org/web/20140822173033/http://gophercon.sourcegraph.com/post/83845316771/panel-discussion-with-go-team-members https://web.archive.org/web/20140822173033/http://gophercon....
- mindslight 8y agoThough to continue with the analogy, you don't want your entire workshop to consist of ad-hoc tools that kinda-sorta work for narrow purposes. You want your basics to be solid, well-designed, and applicable generally - so that you're not already having to account for their individual exceptions and shortcomings when you layer your hacky jigs on top. I feel like there's a physical workshop analog of how (Lisp) macros get you one and only one additional layer of abstraction. I've made an impromptu "table saw" by fastening an upside-down circular saw to a piece of plywood, but it certainly wasn't a basis for doing anything greater and I had to be real deliberate about plugging that thing in.
- kodablah 8y ago> Very cross-platform out of the box. Not “sort-of cross-platform as long as it’s unix” like C/C++ Wut? Firstly, no it's not. I have to drop into MinGW just to interface with native libs statically. Many languages don't do this. Secondly, C++ is very at home on Windows. Not a very good FFI story for something that is very cross-platform that it only binds w/ C libs with only one Unix compiler (gcc). It's like you got the phrasing exactly backwards and need to switch Go and C/C++. > Go feels under-engineered because it only solves real problems. Until I list the ones it doesn't. Or are they not "real"? You know what? I'm not reading these things anymore. We know the type...supposedly senior devs writing a bunch of words about one language over another, cherry picking specific things for both to fit the narrative. I feel like this is how Michael Moore would write blog posts comparing languages. Sorry to hop on this article like this, saw it a couple of days ago with the Java/Kotlin blog post too and I'm seeing it every so often. And I like Go and Java. I'm afraid I just don't see these language opinions as that valuable anymore since I write in them all myself and know better. Edit: In retrospect, probably a bit harsh. But I'd prefer the journalistic lang X does this but not this approach over the op-ed.
- anothergoogler 8y agoSee, this is why I don't blog. Something hits the top of HN and you go from "guy writing about tech for fun" to "supposedly senior dev" faster than you can blink.
- kodablah 8y agoMeh, people like me shouldn't be able to make you feel bad about what you write. I would recommend ignoring me or disagreeing with me the way I have with the author. Otherwise, this would be the reason why I don't comment on HN. My comment hits the top and someone complains faster than you can blink.
- tptacek 8y agoI'm an old C++ programmer who's had the pleasure of doing an XP codebase and I would pick Go any day of the week over the early-aughts C++ I remember working in --- but I concede this may have gotten better since then. While I don't think he was trying to say Go solves every real problem (rather, just that the subset of problems Go solves are all practical and not theoretical), it would be constructive if you could take the time to list the problems you think Go is bad at solving, and why. I'll probably agree, but I may also learn something, and I'll definitely learn more about where you're coming from.
- AlexCoventry 8y agoIn Swift, what's wrong with writing the imperative version to start with, then switching to the monadic version as there's time to polish, or as the function logic evolves to a point where other styles are clearly preferable?
- tptacek 8y agoNothing at all. His point is just that there's cognitive burden associated with making those kinds of decisions in Swift, and there isn't in Go, because you don't have those options. All things considered, he prefers Swift. But he's productive in Go as well. I've had similar experiences. I find that for some problems --- not all of them --- I can drill in quicker in Go, because the problem is all I can really think about; there isn't enough elbow room in the language to really spread out and work on the task of making things elegant. At my last company, I found that writing an emulator in Go was super straightforward, and I think Go made that task easier than a "better" language like Clojure or Swift would have. But in addition to an emulator, we also wrote a compiler, and writing a compiler and SSA optimizer in Go was fairly unpleasant. Not prohibitively so, but enough that I noticed it.
- danenania 8y agoI think it’s kind of akin to the premature optimization people do when they think they have ‘big data’, but really don’t. If you’re really doing heavy list processing, transforming complex data structures, etc., then you’re probably going to miss map, reduce, and friends. But for most real world problems, the code is faster to write, faster to run, and easier to understand with a few dumb loops. It’s always tempting to do things the clever way, but Go made me realize how rarely it’s actually beneficial.
- wolf550e 8y agoFor compilers and optimizers, people have said pattern matching support in the language is very beneficial. I bet there are other tasks where something like algebraic data types and pattern matching would make the code much simpler, and it's not really hard for the language to implement.
- solidsnack9000 8y agoSo again, in the end, Go turned out to be a language for solving real problems rather than a language filled with beautiful tools, and so you build real solutions rather than finding excuses to use your beautiful tools. Don’t try to make Go what it isn’t. If you’re trying to solve abstract CS problems in their most generalized forms, then you may find it frustrating. But if you’re trying to solve specific, practical problems in the forms professional developers typically encounter, Go is quite nice. This is a straw man argument. How many people who complain about Go -- or evaluate it for a project, drop it and move on -- start out solving non-real problems?
- Animats 8y agoThe error handling in Go seems verbose: if err = logit(FrobulatingMessage); err != nil { return err } if err = f.cleanupOldest(); err != nil { return err } There's an advantage, though. You can easily insert code for an error case. You might add, if cleanupOldest fails, something like logError("cleanupOldest failed unexpectedly while cleaning up chain") if that's an unlikely but possible event that needs to be investigated. Big operational shops do that. It's hard to stick debug code in the middle of an expression.
- deleted 8y ago[deleted]
- TheDong 8y agoThe equivalent in rust, for a fair comparison: Before: frobulate(message)?; After: frobulate(message).map_err(|e| { error!("error happened: {}", e); e })?; // or, more like the go one if let Err(e) = frobulate(message) { error!("error: {}", e); return Err(e); } It's really not that different in the debug case than go, but the normal case is less painful to deal with.
- krylon 8y agoI cannot really put my finger on it, but Go is basically perfectly compatible with the way my brain works. Its semantics so far have not surprised me, and I only have to look up the language specification very, very rarely. Most of the time (like 90+ %), I can just let my intuition guide me. Of course, Go has its share of problems, but that one huge advantage dwarfs those problems entirely.
- defertoreptar 8y agoMaybe it's because I've gotten better over the last year, but since I swapped from Java/python/c++ to a Go project, I've reduced my "find the answer on Stack Overflow" time by at least 75%.
- marcus_holmes 8y agoThat, plus the lack of magic. I can always understand what a Go program is doing because of the simple semantics and lack of magic. It's an underrated benefit to be able to browse the source code of a dependency and grok it easily, first time.
- JepZ 8y agoI love Go, I really do. But there are some issues that should be fixed (maybe in 2.0). I'm not so sure if we really need full-scale generics like in Java or Rust, but the interface system (which is the Go solution for the Generics use-cases) certainly needs some improvements. For example, when you write a container lib which expects an empty interface as input you constantly have to cast the type while using the lib. The result is code which looks awful when you use the container and horrible when you look at the container implementation. Next, using slices of interfaces is just another bad joke [1]. there might be technical reasons for the current state, but I am sure there are ways to solve those issues. One thing I am not quite sure about the way Go handles bindings methods to interfaces. Currently, that is not supported and the practical way to do it anyway is to embed the interface into a struct and bind the methods to that struct, but that feels more like a hack than anything else. Another thing that keeps bugging me is the requirement for map keys to be comparable while that is just some internal property which some types have and others don't. For example, functions are not comparable and therefore you can't use them as map keys. Finding out about such stuff really sucks when functions are considered first-class citizens. That said, I have to add that I enjoy a lot of the positive sides of Go and while I wish those issue will be fixed someday, I will gladly continue to use it even with those issues. [1]: https://github.com/golang/go/wiki/InterfaceSlice https://github.com/golang/go/wiki/InterfaceSlice
- dullgiulio 8y agoI don't understand: what do you mean with binding methods to interfaces? Interfaces just represent a bunch of functions that an object must provide (and you can call when you "mask" the object behind the interface).
- JepZ 8y agoWell, normally you bind functions to types like: func (m myType) calcRandom() int { return m.nine } But there are some situations when it would be useful to be able also bind functions to interfaces (e.g. some of them are similar to use-cases for abstract classes in OOP): func (i myInterface) calcRandom() int { return i.Nine() } While I would consider it a clean language design to be able to do that too, it brings some additional complexity and as we know Golang doesn't like complexity. As I said, I am not completely sure of the consequences such a change would bring with it and if it would enable bad practices. So I would not push too hard for that one, but some of the other issues I mentioned are issues of which I am pretty sure that they should be fixed.
- akhilcacharya 8y ago> When writing the Swift function, I found myself spending a lot of time thinking about how to write it. Should I use >>== or .flatMap()? Should I use my custom Result here at all, or should I stick to standard Swift and return NSError?, or maybe Bool with an NSErrorPtr? This was my first time using Result<Void>, and I started asking myself if I should create a typealias for that and maybe a helper function for the slightly strange looking success(()). The var bothered me. It always feels like a hack in FP, like you’re not smart enough to do it right. I wrote a different version that didn’t have a var. That duplicated self.cleanup in two places. So I started working on a new function that would let me include the conditional in the functional composition. I made and re-made a lot of choices. This has basically been the entirety of my experience with Scala. Having too many options - including just writing Java without semicolons - is ultimately not great for my own productivity.
- closeparen 8y agoI’ve written production code in Go professionally every day for two years. None of the language design complaints in these thinkpieces are a real problem. You learn the idioms and it works out. Go’s showstopper problem is dependency management. Fighting with Glide costs at least 30% of my time and every moment of it is excruciating. My organization started migrating to Dep just as Google announced its decision to have the Go community continue thrashing around on the issue even longer. My advice: do not even begin to engage with the details of the langauge. That’s a waste of time. Understand that dependency management is horrifically broken and that Google considers it reasonable to thrash between experimental half-baked solutions forever. However much you may hate Java, Maven terminates with a correct output in less than an hour, which is more than I can say for anything in the Go ecosystem.