41 ms·
Go: What we got right, what we got wrong
- dekhn 3y agoThis is a retrospective written by Rob Pike, one of the creators of the Go language. I worked at Google at the time go was created and had coffee with Rob from time to time and got to understand the reasons Go was created. Rob hates Bjarne Stroustrup and everything C++ (this goes back decades). C++-as-used at Google (which used far more threads that he says) had definitely reached a point where it was extremely cumbersome to work with. I can think of some other things that they got wrong. For example, when I first started talking to Rob and his team about go, I pointed out that scientific computing in FORTRAN and C++ was a somewhat painful process and they had an opportunity to make a language that was great for high performance computing. Not concurrent/parallel servers, but the sorts of codes that HPC people run: heavily multi-threaded, heavily multi-machine, sophsticated algorithms, hairy numerical routines, and typically some sort of interface to a scripting language with a REPL. The answers I got were: Go is a systems programming language, not for scientific computing (I believe they have now relaxed this opinion but the damage was already done). And a REPL wasn't necessary because Go compiled so quickly you could just write a program and run it (no, that misses the point of a repl, which is that it builds up state and lets you call new functions with that built-up state). And scripting language integration was also not a desirable goal, because Go was intended for you to write all your code in Go, rather than invoking FFIs. A number of other folks who used Go in the early days inside Google complained: it was hard to call ioctl, which is often necessary for configuring system resources. They got a big "FU" from the go team for quite some time. IIUC ioctls are still fairly messy in Go (but I'm not an expert). I think Go spent a lot of time implying that goroutines were some sort of special language magic, but I think everybody knows now that they are basically a really good implementation of green threads that can take advantage of some internal knowledge to do optimal scheduling to avoid context switches. It took me a while to work this out, and I got a lot of pushback from the go team when I pointed this out internally. IN short, I think go could have become a first-class HPC language but the go team alienated that community early on and lost the opportunity to take a large market share at a time when Python was exploding in ML.
- leetrout 3y agoI dream of a world where we have Go or something similar with the same / similar UX of Jupyter Notebooks. I keep an eye on Julia but I never make the leap to use it and still pickup Python (or Go).
- zozbot234 3y agohttps://github.com/evcxr/evcxr https://github.com/evcxr/evcxr can run Rust in a Jupyter notebook. It's not Golang but close enough.
- Art9681 3y agohttps://github.com/gopherdata/gophernotes https://github.com/gopherdata/gophernotes I've had this bookmarked for some time and just havent gotten around to it.
- leeoniya 3y ago> And scripting language integration was also not a desirable goal, because Go was intended for you to write all your code in Go, rather than invoking FFIs. "just avoid cgo" is a something i've heard many times from all Go devs
- liampulles 3y agoInteresting context. I use Go a lot for enterprise backend type work and I have to say I'm glad its not geared towards being an HPC language, but to each their own.
- randomdata 3y ago> I believe they have now relaxed this opinion Or is it that scientific computing is starting to realize that it can benefit from a systems programming language? Scripting langages are great for exploratory work, but if you want to put to work into production, scripting starts to really show its limitations. There is a reason systems languages exist. There is good reason why they both exist. They are different tools for different jobs.
- 3y ago
- njharman 3y ago[flagged]
- deleted 3y ago[deleted]
- google234123 3y agoThe value it’s brought to Google has definitely not been worth the cost. It did not really replace other languages. If you join Google now as a new engineer, you will likely be writing C++, Java, or maybe a web language
- scythe 3y agoA friend of mine who works for Google noted that they hardly use Go internally, and quipped, "Google invented Go to sabotage its competitors."
- erik_seaberg 3y agoThat used to be the joke about open sourcing GCL and borgmon, I guess some of which ended up in k8s. Good luck out there!
- bananapub 3y agoor as actually happened, jsonnet and prometheus! I still wonder how many potential competitors the mapreduce and bigtable papers eliminated. perhaps it doesn't matter since the people that blindly adopted such things without enough thought might have got mired in some other nonsense anyway.
- mrkeen 3y agoI thought the same thing about Facebook and "move fast and break things" !
- leetrout 3y agoCan you say more about this? Was Go inspired / derived from the use of sawzall and it just performs its intended uses in other parts of the company?
- iainmerrick 3y agoGo was designed specifically as a better C++ (that is, a better successor to C). Its use as a Sawzall replacement was a lucky accident, I think -- that just happened to be the first niche where it took hold. Sawzall was not a widely-liked language, so people had already been trying to replace it with Python, but Go had better performance and stronger typing so it was a better fit. Go really found its footing as a better Python (for some use cases) rather than a better C++.
- leetrout 3y agoI picked up Go in 2012 as a Python dev in need to doing some bit twiddling over the wire for Modbus. I never shipped that code but it blew my mind how easy it was to just twiddle those bits and bytes and it just worked. A decade later and a couple almost full time Go jobs under my belt and it still surprises me how well most things Just Work™. I love the Go language and I love the Go community. I appreciate what Rob, Ian, Russ and the others do for Go and I appreciate that this talk / blog is honest about the "bumps in the road" working with the community. There's not much point in beating a dead horse around this but having lived through it I find it very hard to believe they didn't know exactly how they were behaving, especially in regards to the package management debacle. Never the less the blog is also correct that we have landed at a very good solution (Drew's legitimate complaints aside). Here's to another 10 years of Go and the inspired / similar languages (Zig, Deno, etc) and hoping we continue to grow as a healthy community.
- zozbot234 3y agoZig and Deno are not very comparable to Golang I think. Elixir and ReasonML would be more like it. From Google themselves there's also Dart.
- antod 3y agoBeing that Deno is tooling rather than a language, I think it is safe to say it is inspired by / comparable to Go tooling. To me it feels like writing JS/TS with Go tooling.
- biomcgary 3y agoMy favorite thing about the core Go team is their willingness to say "No" (to all sorts of stuff) and "Wait for the right implementation" (for generics). I'm a computational biologist rather than a programmer, so my use of Go waxes and wanes, but when I come back to Go, my code compiles and the language works the way I expect. That being said, I do appreciate Rob Pike's willingness to admit mistakes on the learning curve on community engagement without capitulating on adding all the shiny objects.
- jtasdlfj234 3y agoI would have more respect if they at least admitted to the flawed type system but instead say it is not a problem. It is disappointing to see past mistakes repeated in a new programming language. Even the Java language creator was humble enough to admit fault for the null pointer problem. The Go devs do not have such humility. https://github.com/uber-go/nilaway https://github.com/uber-go/nilaway
- deleted 3y ago[deleted]
- coolgoose 3y agoThe nil handling (or the lack of) in go is right now my biggest annoyance with the language :)
- grumpyprole 3y agoIt's interesting that they brought in Phil Wadler to help retrofit polymorphism, it literally is history repeating itself (Wadler did Generics retrofit for Java over 20 years ago).
- knorker 3y agoI think two big failures were: 1. Nil pointers (two types of them, even!). We knew better even then. 2. Insisting that the language doesn't have exceptions, when it does. User code must be exception safe, yet basically never use exceptions. The standard library swallows exceptions (fmt and http) Those are the biggest day to day concrete problems. There are many more that are more abstract, but also hurt.
- randomdata 3y ago> Insisting that the language doesn't have exceptions Insist in what way? The Go website insists that Go has actual exceptions, unlike the pretend exceptions that are actually errors passed around using goto like you find in Java and other languages inspired by it.
- lokar 3y agoSo many people confuse errors with exceptions
- groestl 3y agoErrors are just checked exceptions where you get the chance to introduce bugs, by unrolling the stack manually.
- randomdata 3y agoErrors are things that can fail after the program is written (hard drive crash, network failure, etc.). Exceptions are things that were already broken when you wrote the code (null pointer access, index out of bounds, etc.) To put it another way, exceptions are failures that a sufficiently smart compiler would have been able to catch at compile time. Of course, creating a compiler that smart is a monumental task, so we accept catching some programmer mistakes at runtime as a reasonable tradeoff.
- groestl 3y ago
- VirusNewbie 3y agoI’m surprised they didn’t mention the horrible error handling as something they regret…
- righthand 3y agoBecause it’s neither horrible nor regrettable, it just doesn’t cater to your perfect idea of what it should be. It’s a smart way to encourage people to handle errors.
- bananapub 3y agoyou think it's "smart" to encourage a large fraction of function calls to have if err != nil { return nil, err } after it? really? you don't think it's just a very simple way to do it without having to do a lot of work in the language? and then make everyone use a linter to avoid bugs? oh and you can't always literally do 'return nil, err' because strings have to be ""? it's certainly defensible as a minimalist approach, claiming it's actually good or smart or ideal is a pretty weird take.
- righthand 3y agoYou think it’s “a lot of work” to write an if statement? Any of the proposed variations have shown to be either different syntax (weak valueless change) or would allow people to ignore handling errors. You can’t always return nil? is that a complaint that you are required to do things differently for data types that require it inside of a complaint about doing things the same? It’s not a weird take, things have tradeoffs, this is a tradeoff of using Go.
- unscaled 3y agoIt's not a lot of work, you can just let the IDE spew it off for you and feel like a certified J2EE programmer circa 2003 who lets the IDE write everything for them. But yeah, writing code is not the problem. Reading the code is. I think having 60% of your lines of code being: if err != nil { return err } Does make the code a tad bit less readable.
- moomin 3y ago[flagged]
- tomp 3y agoWhat other languages of comparable popularity do you know that had concurrency similar to Go's, and interfaces? Actually, name just one that has either, even today!
- ninepoints 3y agoErlang
- phinnaeus 3y ago> of comparable popularity
- throwawaymaths 3y agoIt was more popular than go in 2009
- Thaxll 3y agoErlang is not a popular language.
- tomp 3y agoErlang's processes might have similar semantics to Go's goroutines (green threads) but Erlang is a much simpler language, because it doesn't have shared state. A lot of work went into optimizing Go's GC to be able to cope with concurrency.
- easton 3y agoC#? It has channels and good concurrency stuff. I don’t know if it was as mature in 2007 when they did this work. edit: Concurrency, not the language itself. That was mature.
- w10-1 3y agoI really, really appreciate key people taking the time for retrospectives. It makes a huge difference to people now who want to make a real difference. But I'm not sure Rob Pike states clearly enough what they got right (IMO): they managed the forces on the project as well as the language, by: - Restricting the language to its target use: systems programming, not applications or data science or AI... - Defining the language and its principles clearly. This avoids eons of waste in implementing ambiguity and designing at cross-purposes. - Putting quality first: it's always cheaper for all concerned to fix problems before deploying, even if it's harder for the community or OS contributors or people waiting for new features. - Sharing the community. They maintained strict control over the language and release and core messaging, but they also allowed others to lead in many downstream aspects. Stated but under-appreciated is the degree to which Google itself didn't interfere. I suspect it's because Go actually served its objectives and is critical to Google. I wonder if that could be true today for a new project. It's interesting to compare Dart, which has zero uptake outside Flutter even though there are orders of magnitude more application code than systems code. Go was probably the key technology that migrated server-side software off Java bloatware to native containers. It dominates back-end infrastructure and underlies most of the web application infrastructure of the last 10 years. The benefit to Google and the community from that alternative has been huge. Somehow amidst all that growth, the team remained small and kept all its key players. Will that change?
- zozbot234 3y ago> Go was probably the key technology that migrated server-side software off Java bloatware to native containers Interesting point of view - Golang might be pithily described as "Java done right". That has little to do with "systems programming" per se but can be quite valuable in its own terms.
- grumpyprole 3y agoJava has a culture of over-engineering, to the point where even a logging library contains a string interpolator capable of executing remote code. Go successfully jettisoned this culture, even if the language itself repeated many of the same old mistakes that Java originally did.
- liampulles 3y agoSomething that I really like about go is how easy it is to make a monorepo, and how quick and easy it is to build all of the contained apps (go build ./...). I also find it really easy to make CLI tools in Go that can form part of unix pipelines, since: you just need a single go file and app-named folder to get started, it gives you a self-contained binary as output, and the Reader/Writer interfaces make it easy to stream and handle data line-by-line. We have a couple of CLIs at work that analyze multi-gig logs in a couple of seconds for common error patterns - Go is very handy for such things.
- kitsune_ 3y agoI know I sound salty here, but 10 years ago I got ridiculed on go-nuts, with dismissive comments from Rob Pike, because I dared to suggest that the way go get and module imports over the wire 1. worked, 2. were advertised in all their docs for beginners, and 3. how they were subsequently used throughout the community was ultimately harmful / shortsighted.
- hota_mazi 3y agoJust Rob Pike expressing to the world how ignorant he is of programming language theory that was discovered after 2000.
- GauntletWizard 3y agoI wish everyone were.
- kaba0 3y agoHe is ignorant of it even before 2000, see their for loop fck up.
- treyd 3y agoThe way Go's package system works, especially before modules, really feels like it was a hack over an earlier and even more limited system that was designed to be used entirely inside the Google monorepo that was made to work outside. The weird global namespace tree makes sense there, and the emphasis on checked-in codegen also make sense there when you consider that Google also includes build artifacts in their monorepo.
- capital_guy 3y agoThis was exactly what happened. Rob Pike mentioned in another talk that they overfitted the pre-module system to how Google deals with packages. So I think he/they have conceded this was a mistake
- p_l 3y ago
- bsaul 3y agoI’m surprised the fact that they manage to keep the language small and minimal isn’t mentionned as a huge success. To me that is the number one reason to use this language : it forces you to not be distracted by language constructs (there aren’t enough for that), and focus on what is it exactly you’re trying to build. Even as an educationnal tool, this is excellent. Maybe they don’t realize it because they come from C, but when you come from more recent languages that include everything and the kitchen sin, this is a godsend. It’s now to the point that whenever i develop a feature in a language, i ask myself « how would i do that in go » to ensure i don’t go fancy with the type system for no good reasons.
- troupo 3y ago> and focus on what is it exactly you’re trying to build. Instead, you're focusing on fighting the language limitations on your way to build what you want ;)
- bsaul 3y agoin my personal experience, go language "limitations" have always forced me to clarify and simplify my design. In the end, my code is way better than in my original intent.
- troupo 3y agoI had to write seven or eight identical functions transforming some data because Go didn't have generics. Hardly a "better code". They've now released generics, thankfully, but there are many places where there's unnecessary repetition and clunkiness because the authors "know better".
- bsaul 3y agoyou couldn't make those data conform to an interface and have the algorithm work on the interface ? in those scenarios i usually either work with interfaces, or composition (struct embedding), or as a final resort to codegen for things like generating bindings to database tables. the codegen is usually quite a good solution and makes debugging the generated code very straightforward, since it's all there, in the _generated folder, instead of in a temporary file generated by the compiler. it also makes the generator code a separate project, which IMHO is a better solution than using all kinds of macro and complex meta programmation directly in the final project.
- tptacek 3y agoInteresting bit here about the decision to use Ken Thompson's C compiler rather than LLVM --- something that people grumbled about, and that resulted in (especially earlier versions) less optimal generated code. The flip side of that decision is that they were able to do segmented stacks quickly; they might not have done them at all if they'd had to implement them in LLVM and fit the LLVM ABI. (He cites this as an example of the benefit of that decision, not the only benefit).
- pcwalton 3y agoThat part of the interview is incorrect about LLVM. I implemented segmented stacks via LLVM for Rust. It's actually pretty easy, because there is support for them in X86FrameLowering already (and it was there at the time of Go's release too). If you enable stack segmentation, then LLVM emits checks in the function prolog to call into __morestack to allocate more stack as needed. (The Windows MSVC ABI needs very similar code in order to support _chkstk, which is a requirement on that platform, so the __morestack support goes naturally together with it.) Actually, getting GDB to understand segmented stacks was harder than any part of the compiler implementation. That's independent of the backend. What I think the author might be confusing it with is relocatable stacks. That was hard to implement at the time, because it requires precise GC, though Azul has implemented it now in LLVM. Back then, the easiest way to implement precise GC would have been to spill all registers across function calls, which requires some more implementation effort, though not an inordinate amount. (Note that I think the Plan 9 compiler does this anyway, so that wouldn't be a performance regression over 6g/8g.) In any case, Azul's GC support now has the proper implementation which allows roots to be stored in registers.
- akira2501 3y ago> is incorrect about LLVM. He didn't say it was not possible, but that it would have required too much effort in modifying the ABI and the garbage collector. > because it requires precise GC Which is why they avoided LLVM for a much smaller and easier to manipulate existing compiler. Their point is that it would have slowed things down too much to even try it inside someone else's project. Sometimes "roll your own" is the best idea.
- einpoklum 3y agoThe structure of that post is weird, in that it's quite difficult to figure out where are the parts which were done right and where are those done wrong. Can someone tl;dr the done-wrong items?
- iainmerrick 3y agoIt’s a talk transcript, not originally written as a blog post.
- tubthumper8 3y agoThere's a (possibly non-exhaustive) list from a Reddit comment here. I can paste it if needed, otherwise will just link it: https://www.reddit.com/r/golang/s/wt1vpPtLgc https://www.reddit.com/r/golang/s/wt1vpPtLgc
- statquontrarian 3y agoI was surprised at the poor quality of serviceability given its enterprise deployment with k8s. No thread dumps without killing the process (or writing a SIGUSR1 handler). No heapdump reader so you have to use the memory sampler and hope you catch the problem (and that requires adding code), and viewcore is broken in new versions (and it doesn't work with a stripped binary which is most production binaries).
- deleted 3y ago[deleted]
- notpachet 3y agoI enjoy Go as a language, but I have always hated the gopher mascot. It's so derpy.
- jtasdlfj234 3y ago> It's so derpy. That's why I love it.
- softirq 3y agoThe fact that he doesn't mention context as a huge failing of Go is very suspect... I also find the post a little too self-congratulatory for what was essentially a reinvention of C with a GC at the right time, and not just C the language, but C's philosophy on programming. I think as Go has become more popular, the core of C has been drowned out by people coming from other languages who insist on too many libraries, too many abstractions, generic solutions at every level, and more features. Go today has essentially moved much closer to Java, and some projects like Kubernetes are without a doubt just Java projects with a slightly different syntax. Concurrency and interfaces I think are also a big fail in Go. Interfaces because they failed to add enough of them to the standard library for simple things like logging, filesystem access, etc, causing numerous incompatible implementations, which is something that wouldn't have happened if they hadn't been so gung-ho on interfaces being defined where they are used instead of having community interfaces. Concurrency is harder to summarize, but day to day you still get locking issues, libraries that don't expose interfaces that are easy to work with via coroutines (which is ironic given rob's finger pointing at async/await coloring), and as I said context is really a prime example of why CSP IS a bad model compared to mailboxes and the Erlang model of concurrency. Every function has to take an extra noisy argument, every function has to wait for a ctx cancellation, instead of just baking the semantics of cancellation into the language itself.
- cangeroo 3y agoInterestingly, several posts have already been flagged for having a similar perspective. I'd love to know why we're not allowed to discuss and elaborate on "what we got wrong" in fairly neutral technical terms.
- tptacek 3y agoIt's language-war drama, which is deeply disfavored on HN, because it's boring and spreads like kudzu.
- cangeroo 3y agoFair enough. And the world would be a better place with a positive-bias. Except that this article purports to be self-critical, so arguably the very topic of this thread should cover both the positive and negative of the language, and our comments are merely expanding on it. But thanks for the explanation, I appreciate it.
- chewxy 3y agoGopherConAU organizer here. Here's the whole playlist. I am not sure why I cannot make it public. https://www.youtube.com/playlist?list=PLN_36A3Rw5hFsJqqs7olOAxxU-WJGlXS0 https://www.youtube.com/playlist?list=PLN_36A3Rw5hFsJqqs7olO...
- cangeroo 3y ago(rant) That's nice, but also rather self-congratulatory. I was expecting some kind of acknowledgment of the deeper issues in the language. But perhaps that's the central issue, that the language is perfect in their eyes. I'm the problem. Well, okay then. I can't recommend the language, because of its type system, the error handling, the unsafe concurrency, the simplistic syntax, nil, default zero, and a large number of mainstream packages are abandoned. I now use Rust as my main language. It has a flourishing ecosystem and is visionary in so many ways that Go is not. Put more pointedly, I'm sure Go had its day, when it was competing with PHP as a backend language.
- zik 3y agoI don't think this comment really contributes to the discussion. It comes across as Rust advocacy without having any tangible points to make. First paragraph: "I don't like it". Second paragraph: snide comment. Third paragraph: "I don't like it". Fourth paragraph: "Rust is better". Fifth paragraph: snide comment.
- ncruces 3y agoThere's one thing in there worth discussing IMO: the focus on zero values (incl. nil). That's the Go mistake, the one that causes most of the issues for the intended audience, the one that can't really be fixed. It's a shame Pike doesn't really discuss this, even if it's hopeless now. The rest is just people projecting and self-selecting outside of the intended audience. Don't like it, don't use it, we don't all need to agree with you.
- campbel 3y agoZero values are fine, some benefits, some drawbacks. Workarounds exist for when you need to identify the difference between unset and zero.
- FridgeSeal 3y agoNo they’re not, they’re a horrible decision, and some of the “solutions” I’ve seen for working around them are band-aid-code at best. The design decisions around zero values infect protobufs too, and they suck to work around. The fact that an empty message can successfully deserialise into any valid protobuf is an insane decision and should have been thrown out long ago.
- aldousd666 3y agoI was following the mailing list as this was being developed way back then, but it always frustrated me that the team chose such a trite, un-googleable name for the language. I mean, if you want to find the community and the docs, you have to search for 'golang' which let me tell you, was not an automatic solution to the problem. That's actually my only complaint.
- xpressvideoz 3y ago100% agreed. In addition to this, due to some people not capitalizing the first letter of Go, distinguishing between the verb go and the noun go takes more time than usual when reading articles related to Go. Maybe to native speakers it doesn't matter?
- deleted 3y ago[deleted]
- chuckadams 3y agoAs opposed to the language whose name is literally a single letter?
- tubthumper8 3y agoAre you referring to C? I think the comment's point would be that when C came out there were no search engines, so nobody would've considered that. When Go came out, not only were search engines a critical everyday software, the Go language designers worked for a company whose original and flagship product is a search engine, so they should've known. (I also think the same criticism could be directed to other languages that are English words such as Swift, Rust, etc. but to a lesser extent)
- robaato 3y agoCurious as to no mention of the choices around interoperability and C FFI. "Rewrite in go" as the answer closes off a whole chunk of options.
- bb88 3y agoThat was the Java solution as well circa late 1990's. But in many cases that's true of python, and other languages. It's just easier if you can install a native library rather than one with a cumbersome build process.
- randomdata 3y agoPerhaps because there isn't just one choice? The Go team maintains two compilers, and each treat that interoperability differently. You have even more options if you reach out into the larger Go ecosystem (e.g. tinygo does things differently again).
- msie 3y agoI appreciate that he talked about examples in api documentation. I can't believe people are still writing documentation nowadays without examples.
- cogman10 3y agoI gotta say, reading this tells me exactly why Go struggles to evolve as a language. Go ahead, skimming the article tell me what go got wrong? Stumped? Yeah, well I was too. That's because a lead designer can certainly write paragraphs on paragraphs of "Look at how amazing and kool we are for being so smart" but doesn't seem capable of writing more than a half a sentence of "we got this wrong". I saw 2 things Pike believes go got wrong. Documentation and packaging. The rest is a lot of self congratulatory "Look at how smart we are and how dumb our critics are". No language is perfect, every language has it's own weaknesses (and go has plenty). Yet for some reason Pike can't help but gush over how perfect it is. Even with the 2 faults listed, the documentation fault very much has an undertone of "our functions are so simple but the dumb users weren't smart enough to understand the amazingness of our elegant code and libraries." > The key missing piece was examples of even the simplest functions. We thought that all you needed to do was say what something did; it took us too long to accept that showing how to use it was even more valuable. Go is a language designed in the last 20 years that decided "You know what wasn't bad about C? Pointers and null". Yet the only part pike can really fault is "well, we didn't know how to do package management so we sort of messed that up". He even goes so far as to talk about how interfaces are so good and generics are dumb even though go has the notorious `interface {}` used to try, in an type unsafe way, to pass around random objects. (But hey, pike hand waves that away with "the dumb community just isn't smart enough to accept the brilliance of our type system".) How can a language evolve when the lead designer puts on blinders to the community raising faults? When a "what we got right, what we got wrong" post is filled with how awesome the language is with scant reference to what is wrong? Even just openly dismissing concerns with the language? Contrast that with a lead language architect I really like, Brian Goetz (seriously, go watch his talks about evolving Java). His approach is nearly the polar opposite. It's "Ok, we've seen that a lot of people using java run into problem X, so we are going work hard to find language or library solutions which help improve things for the developers". They very rarely just dismiss problems and when they do it's more along the lines of "Well, we'd love to have it but ultimately there's not a good way we can think of to do this which is also backwards compatible." And you can really see that in the way java has evolved from 8->21. From adopting a faster release process, a ton of new language features, and a LOT of active development into the most painful parts of dev work. Virtual threads is a shining example of this. Java now has go like concurrency even though it took several iterations and trials to bring that in, they worked hard to evolve the language in a way that fits perfectly. Valhalla is another great example of the language working hard to solve real problems. A 10 year project open to the community working to fundamentally redefine the JVM memory model because the one designed in the 90s doesn't fit with modern hardware. But hey, if you like go, that's great. Just don't expect even an iota of evolution. Barring a change in leadership, generics is almost certainly the last new language feature (at least in this decade). A feature that landed primarily because of over a decade of articles and community screaming about how horrible the lack of generics impacts everything.
- synergy20 3y agoI really wanted to love Go, spent time learning it, bought a few books read it,etc. It did not work out for me for embedded field, it's too large in binary size, no real time due to GC, and I still need to interface with C code here and there. In the end, I'm back to c and c++, I consider my time on Golang is actually totally a waste. Go has its own uses e.g. native cloud or something, even there lots of alternatives exist. It's pretty hard to replace existing popular languages, as those languages are also evolving fast.
- deleted 3y ago[deleted]
- zik 3y agoAnything with a GC is an immediate killer for small embedded projects. Anything STM32 sized or less is going to struggle with GC due to lack of memory. But in the intervening years the average embedded device has got larger and more powerful so now I'm doing embedded programming on devices with Linux in languages like python and Go. So maybe just wait and your Go learning will be useful again?
- starttoaster 3y agoI'd say Go shines more on server application work. I'd be surprised to find it in an embedded system.
- deleted 3y ago[deleted]
- nmz 3y agoDid you try tinygo?
- synergy20 3y agoI don't do MCU level embedded, so no tinygo for me, but yes I'm aware of it.
- 4death4 3y agoThe anecdote about writing the compiler in C is very interesting. LLVM is obviously very popular these days, so it’s refreshing to see a counter example. I also love that the compiler was decidedly mediocre. It just goes to show that often the user ((or developer) experience is typically more important than the technical merits of a product.
- sapiogram 3y ago> It just goes to show that often the user ((or developer) experience is typically more important than the technical merits of a product. I think Go still won on technical merits, because it never really competed with other compiled languages, instead mostly converting Python and Java programmers. Compared to those, startup time and memory usage of go programs are leagues ahead, and the quality of the codegen doesn't change that much.
- norir 3y ago> Also, writing a compiler in its own language, while simultaneously developing the language, tends to result in a language that is good for writing compilers, but that was not the kind of language we were after. I have seen this sentiment a few times recently. First of all, it raises the question is a language that is not compiled in itself a bad language for writing compilers? My intuition is usually yes. Secondly, the implication is that a good language for compilers will not be good for other applications. I really don't understand this because a compiler will use most of the same building blocks that are used for other programs. I would really like more context into what the author is trying to say though.
- TheDong 3y agoWriting compilers is mostly aided by having a robust type-system and elegant tooling for parsers and AST transformation and so on. Writing a compiler requires computer science knowledge, requires thought. Haskell I think is a perfect example. It is a language that is well suited for writing compilers, but also very well suited for building services, backend applications, really anything if your developers are of average intelligence. Go, however, wants to optimize for developers who think a for loop is easier to understand than an applicative functor, who think that generics are unnecessarily complex. If you're trying to build a language for "the lowest common denominator, the average googler", that's the opposite of building a language for compiler writers, so in that case building a language that can represent such a hard CS problem well is counter productive.
- tmerr 3y agoThe ideal set of building blocks depends on the problem. If the building blocks make it easy to write concurrent code (Go, Erlang), then it becomes easier to write a server. If they make it easy to represent "A or B or C" and pattern match on trees (ML-like languages), then it becomes easier to write a compiler. Add to that: if you are trying to make an easy to onboard language, you want to look at how beginners use it, not experts. Someone writing a compiler for language X is certainly an expert in X.
- tubthumper8 3y ago
- leafmeal 3y agoMaybe I'm misunderstanding here, but it sounds like he's claiming they invented "interfaces". The Go interfaces seem like the same thing as a Haskell typeclass which predates them by a long shot. Either way a great invention that should be in more languages.
- plorkyeran 3y agoThe early days of Go appeared to be the work of a group of people who had not ventured out of their bubble in a very long time and were unaware of several decades of PL research, so it would be somewhat surprising if any of them knew what a typeclass was at the time. This is significantly less true now.
- LispSporks22 3y agoAs I recall the Go GC is a primitive 70s design as well. No idea if it still is.
- geodel 3y agoNo, it went back to 30s now.
- philosopher1234 3y agoGo interfaces are unique in that they are implicit. Duck typed, if you will. That is not present in Haskell.
- masklinn 3y agoThat is not unique, OCaml had structural (sub)typing in the 90s.
- jmyeet 3y ago> A key point was the use of a plain string to specify the path in an import statement, giving a flexibility that we were correct in believing would be important. Wrong. Importing a string is like a touchscreen UI in a car: it's deferring the problem. It's lazy. > But we didn't have enough experience using a package manager with lots of versions of packages and the very difficult problems trying to resolve the dependency graph. No one on the team had ever used Java? Really? Maven was ~8 yeras old when Go was released. It came from previous learnings and errors with Ant. Maven did other things too that aren't necessarily relevant or necessary (eg standardized directory structure). But the dependency system was really solid even if it was verbose because it was XML. > Second, the business of engaging the community to help solve the dependency management problem was well-intentioned This feels ahistorical. It felt more like the problem wasn't understood and/or thought important. This fits in with the importing a string: it's a way of not solving the problem, of kicking the can down the street.
- MaKey 3y agoI haven't seen someone mentioning Go's issues with crypto yet. After OpenSSH deprecated SHA1, the Go team took a year (!) to add support for SHA2 to x/crypto/ssh [1]. Gitea was one famous victim [2]. Furthermore it doesn't instill confidence to see a crypto maintainer bashing on GnuPG [3] and trying to discredit Dan Bernstein [4]. [1]: https://github.com/golang/go/issues/49269 https://github.com/golang/go/issues/49269 [2]: https://github.com/go-gitea/gitea/issues/17798 https://github.com/go-gitea/gitea/issues/17798 [3]: https://twitter.com/FiloSottile/status/1127643698676797441 https://twitter.com/FiloSottile/status/1127643698676797441 [4]: https://twitter.com/FiloSottile/status/1555669786826244096 https://twitter.com/FiloSottile/status/1555669786826244096
- raggi 3y agothe x/ packages languish a lot, the problem is they follow a development model that slows the rate at which new contributors succeed to send patches The stdlib crypto package I would describe as another of Go's big successes. OpenSSL has been a disaster for a very long time, and Go and perhaps most significantly agl managed to build and ship a very broadly exercised alternative implementation with an average very high quality, particularly from the perspective of having significantly fewer footguns in the public API.
- tialaramex 3y agoThis mentions gofmt as a "what we got right" and I think that's especially worth underscoring. This seems to many language inventors and proponents like a small thing but it delivers huge value because it eliminates one common bike shedding opportunity entirely from day zero of a Go project. I've seen several newer languages embrace this, either copying it quite intentionally or just figuring hey Go has one so we should make one as well. I've seen some pretty weird formatting rules but I have very rarely seen rules I couldn't get used to, whereas I have worked on plenty of codebases without enforced formatting rules where as a result it was harder to understand the code.
- onionisafruit 3y agoI have a tendency to futz around with code formatting. I like that go fmt makes that moot for the most part.
- gregwebs 3y agoThis seems like a more personal account of the ACM article they published [1]. In both they recognize that they didn't make a great new programming language in terms of a language specification but instead did a great job building up all the things around programming languages that may end up being even more important. In the submitted article they talk about inventing an approach to using interfaces and also an approach to concurrency. Go routines are identical to Haskell threads and interfaces are very similar to Haskell typeclasses (now that they support generic arguments). Haskell's preceded Go- it's interesting to see procedural programmers independently discover the power of ideas from functional programming. Go's one language innovation is to not require an interface implementation to declare the interface it implements. This is awful from a safety perspective but in practice it causes few issues and gets rid of awful circular dependency issues experienced in Haskell and now Rust. [1] https://cacm.acm.org/magazines/2022/5/260357-the-go-programming-language-and-environment/fulltext https://cacm.acm.org/magazines/2022/5/260357-the-go-programm...
- munificent 3y agoI think you're understating how important the fact that interfaces are structurally typed is to the overall effect of the feature on the language and—even more—its idioms and ecosystem. Go would be a deeply different language if types had to declare the interfaces they implement ahead of time. It's one of Go's main distinguishing features (or at least was until TypeScript came out and also had structurally typed inferfaces, for different reasons).
- masklinn 3y ago> Go would be a deeply different language if types had to declare the interfaces they implement ahead of time. GP literally mentions haskell which uses nominative typing and does not require types declaring the interfaces they implement (typeclasses they instantiate) ahead of time. If anything, Go's solution is worse because you have to conform the interface you declare to whatever already exists on the type. Type classes make the "type class interface" independent from the underlying type. And then it turns out Go's structural interfaces also play hell with generics, leading to the current... thing.
- lulznews 3y ago[flagged]
- vrnvu 3y agoThe biggest win for Go is its approach based on composition rather than inheritance. There isn’t any “architect engineer” building cathedrals with interfaces and abstract classes. There’s no cult behind needing to follow DDD in an event-driven architecture powered by a hexagonal architecture in all projects, or you are tagged as a bad engineer. We don’t have thousands of traits to define every possible code interaction, yes. From a type system point of view, Go is lacking compared to HM based type system, yes. Yes, it’s all pros and cons with this decision. We can agree on that. I’ve seen that the predominant enemy for a software project is software engineers. Go keeps them in line for the sake of the project.
- munificent 3y ago> There isn’t any “architect engineer” building cathedrals with interfaces and abstract classes. There’s no cult behind needing to follow DDD in an event-driven architecture powered by a hexagonal architecture in all projects, or you are tagged as a bad engineer. My experience is that you can also write simple non-over-engineered code in other languages too. Yes, it can require pushing against the wind of the prevailing culture sometimes but it's not, like, impossible.
- bb88 3y agoIf one chunk of code depends upon one and only one other chunk of code, then forcing the programmer to put an interface between them for unit testing does a disservice to the programmer. I really do prefer languages that make it easy to write unit tests.
- campbel 3y ago> I’ve seen that the predominant enemy for a software project is software engineers. Go keeps them in line for the sake of the project. Brilliant
- lmm 3y ago> There isn’t any “architect engineer” building cathedrals with interfaces and abstract classes. There’s no cult behind needing to follow DDD in an event-driven architecture powered by a hexagonal architecture in all projects, or you are tagged as a bad engineer. Isn't Go the big driver of Kubernetes? It feels like overarchitecturing is still there in Go projects, they've just made it distributed.
- munificent 3y ago> Critics often complained we should just do generics, because they are "easy", and perhaps they can be in some languages, but the existence of interfaces meant that any new form of polymorphism had to take them into account. I've been noodling on a statically typed hobby language and one of the things I'm trying to tackle is something like interfaces plus generics. And I have certainly found first-hand that Rob is right. It is really hard to get them to play nicely together. I still think it's worth doing. Personally, I'd find it pretty unrewarding to use a statically-typed language that doesn't let me define my own generic types. I used to program in BASIC where you had GOSUB for subroutines but there was no way to write subroutines where you passed arguments to them. I don't care to repeat that experience at the type system level. But I can definitely sympathize with the Go team for taking a long time to find a good design. Designing a good language is hard. Designing a good language with a type system is 10x harder. Designing a good type system with generics is 10x harder than that.
- hota_mazi 3y ago> But I can definitely sympathize with the Go team I don't. The hardest part in implementing generics is when you support inheritance of implementation. Go doesn't. Go had the easiest job in implementing generics. The only reason why they didn't was not technical: it was ideological and purely based in ignorance, and the fact that most Go designers stopped paying attention to the field of PLT in the late 90s.
- FridgeSeal 3y agoAll the ML and functional languages don’t seem to have this problem, and a lot of them have Type Systems that are far more sophisticated and capable that go’s.
- munificent 3y agoSML actually has a very simple, unsophisticated type system that isn't anywhere near as expressive as generics in most other languages (Java, C#, Go, etc.). In SML, there's no way to define a generic hash table that works with any type that implements a hashing operation and uses that hash function automatically. Type parameters are entirely opaque types that you can't really do anything with. To make a generic hash table, the user has to explicitly pass in a hash function each time they create it. In other languages, you can place a bound on the type parameter that defines what operations are supported and then the operations are found (either at runtime or monomorphization time) based on the type argument. If you don't have bounds, lots of things get easier for the language designer. But lots of things get much more tedious for the language user. It's probably not a coincidence that every language newer than ML with parametric polymorphism has some sort of bound/trait/constraint/type class thing. But bounds are where most of the complexity comes from.
- slowhadoken 3y agoI’ve never used golang in production but I toyed with it when it was first released and I enjoyed it. I just wish Google didn’t control it.
- oconnor663 3y agoThe post mentioned a few things that Go has done that seem to be "obvious" choices today: - automatic formatting - unified tooling - module/library support I'd add more items to that list, which aren't unique to Go of course, but where Go has clearly contributed to the new consensus: - composition over inheritance - compiling to native binaries - error values over exceptions - array slicing - no automatic integer type conversions There's plenty I don't like about Go, and I rant about it sometimes, but I also respect it. It moved the art forward. ...now can I please compile my code with unused variables when I'm deliberately trying to make my tests fail? :-D
- pitaj 3y agoInterestingly, all of those (except for automatic formatting) also apply equally to Rust. Maybe that's why there's such a "Go vs Rust" culture.
- tubthumper8 3y agoRust also has automatic formatting [0] I don't think the tooling is why there is a perceived "Go vs Rust" culture, I think that's due to (somewhat) overlapping use cases, or more probably that they were developed and came out around roughly the same time. There really doesn't need to be a "Go vs Rust" culture though. I think it should be obvious to most people that Go had a big influence on Rust and other modern languages for the benefit of having unified tooling, formatter, linter, etc. [0] https://www.rust-lang.org/tools https://www.rust-lang.org/tools
- pitaj 3y agoIt's my understanding that the Go compiler will format your code every time you compile. For Rust, its a separate tool invocation.
- masklinn 3y ago> It's my understanding that the Go compiler will format your code every time you compile. I do not believe that is the case. You have to invoke `gofmt` or `go fmt` on the project. You may hook it to precommit, or your editor might be configured to automatically run it on save, but afaik neither `go build` nor `go run` will auto-format.
- justinclift 3y ago> And of course, today there is an LLVM-hosted compiler for Go, and many others, as there should be. Isn't that the dead llgo effort? https://github.com/go-llvm/llgo https://github.com/go-llvm/llgo (now archived) Its readme points to a dead link on the LLVM website, and it looks like there's no matching Go project under the LLVM org. Does anyone know if there really is still a working LLVM based Go toolchain (other than TinyGo)?
- jayd16 3y ago> First, he was generalizing beyond the domain he was interested in [...] And then they proceed to dump on async/await. It's not a target concern for Go but often you want to run code specifically on a UI thread or call into a foreign function on some specific OS thread. AFAICT that's most easily done with async/await.
- pharmakom 3y agoI am not a Go user and the language has never appealed to me. On paper, it offers less than more established ecosystems for generalist backend development, such as C# and Java. Perhaps some Go users can weigh in?
- Animats 3y ago> the existence of a solid, well-made library with most of what one needed to write 21st century server code was a major asset. Yes. Go was funded by Google because Google had a problem. They needed to write a lot of server-side application code. Python is too slow, and C++ is too brittle. Go does very well in that niche. A big bonus was that Google people wrote the libraries you need for that sort of thing, and uses them internally. So, when you used a library, it was something where even the error cases were heavily exercised. I have some technical arguments with the language, mainly around the early emphasis on using queues for everything, including making mutexes out of queues. They got the "green thread" thing right for their use case. The "colors of functions" thing is a problem, and the arcane tricks needed to make async and threads play together in Rust are just too much. Go gives up a little performance for great simplicity. I'm amused at the old hostility to threads. I started out on UNIVAC mainframes, which had threads starting in 1967. (They were called "activities") By 1972, there were not only user-space threads, but they ran on symmetrical multiprocessors. There was async I/O, with user-space completion functions. There were built-in instructions for locks. The operating system was threaded internally. I thought of threads and multiprocessors as normal, and felt the loss of them when moving to UNIX. It was decades before UNIX/Linux caught up in this area. Several generations of programmers had no clue how to use a shared-memory multiprocessor. The early concurrency theory from Dijkstra was re-invented, with different terminology and often worse design than the original. The Go people understood Dijkstra's bounded buffers, and understood why bounded buffers of length 0 and 1 are useful. It was nice seeing that again. With the right primitives, concurrency isn't that hard. If you try to do it by sprinkling locks around, which was the classic pthreads mindset, it will never work right. It didn't help that UNIX/Linux had an early tradition of really crappy CPU dispatchers, so that unblocking a thread worked terribly.
- anthk 3y agoGo is not just a Google project, it's basically Plan9's compiler philosophy (and CSP) for Unix/Linux.
- mike_hearn 3y ago> Yes. Go was funded by Google because Google had a problem. They needed to write a lot of server-side application code. Python is too slow, and C++ is too brittle. I've said this elsewhere on the thread but will repeat: this doesn't match my memory of working at Google during this time period. This belief feels a bit like "go was for systems programming", a popular meme that doesn't make sense when examined. In 2009 Python wasn't really used for servers at all at Google outside of a few internal-facing utilities, so that idea can be disposed of immediately (exception: the YouTube acquisition). The biggest Python server developed by Google itself was iirc Mondrian, the code review tool, written by Guido van Rossum himself. It was later replaced by Critique, written in Java. At the time Google had a fairly strict three languages policy, designed to kill programming language fights. You could use C++, Java or Python. Python was used for scripts, C++ for infrastructure and Java for web servers. There was some overlap: Java was introduced to Google later than C++, and some web servers were still written in C++ because it didn't make sense to try and rewrite them, even though there were some initiatives around trying to do incremental ports to Java that hadn't really taken off. Also some infrastructure servers were written in Java (e.g. a database called Megastore). Core libraries were mostly C++ with JNI and Python bindings. There was also a loophole in that policy, in that some teams invented their own languages for internal infrastructure, so in practice the Google codebase also had some use of custom config languages and in particular Sawzall, also by Rob Pike. It looked syntactically a bit like Go. But overall people had a lot of freedom to choose, and new web servers were being mostly written in Java, with new database engines and similar being mostly written in C++. Writing async code did suck, and Go definitely got that right. But Go wasn't a project initiated by the senior management to solve a problem Google had. That's not because management was afraid of initiating such projects. Huge numbers of internal infrastructure projects were created and staffed by the relevant teams to directly solve developer pain points (e.g. the giant networking upgrades they embarked on at that time). But they were telegraphed in advance. I don't recall much complaining about this state of affairs. Build times were an issue until they got Bazel/Blaze working with remote build clusters, and at that point you could compile giant codebases in seconds because everything was cached remotely. Local compiler speed became largely irrelevant, especially as javac was very fast anyway. I don't recall exactly when this was, but I developed C++ servers around that era and Pike's 45 minute compile wasn't a common occurrence for me after Blaze caching appeared. I can imagine that would happen if you changed a core library and then recompiled something very high up the stack. The announcement of Go came as something of a surprise. If it had actually been developed to solve Google's problems it'd have been launched internally first and then developed with internal users for years before being exposed publicly, as was normal for Google. But this one launched to the public first. I recall people in my neck of the woods wondering what it was for: not something you'd expect if it'd really been driven by internal demand.
- HackerThemAll 3y agoWhy on earth this date/datetime formatting rule? > 01/02 03:04:05PM '06 -0700 Why all the awkward syntax?
- redskyluan 3y ago[dead]
- t43562 3y agoI made some videos introducing Go. They're not important and the view count isn't impressive at all but it interested me that the one with the most hits is about "Go Project Structure". I have to say I'm not at all a fan of how modules get imported in go - and how it works with github. It's an extremely confusing and complicated issue and my bete noir was forking a library. The way things are exported, the paths you need to use to access them.......the whole area is far worse than the problems I've ever had with C/C++ and certainly Java or Python.
- Noe2097 3y agoEvery way I look at it, Go brings tremendous regression when it comes to "modularity & composability" in the general sense of the terms. Package management, package definition, interface definition, exporting, protecting or hiding components, feel like they were an afterthought, and as if specified by people who had absolutely no prior experience in other languages or actively ignored it. There is no nesting of packages in Go. There is no selective visibility protection among packages except on the very first level. Exporting is such an afterthought that it is declared by the change of the first letter to uppercase. Local development of cross-modules was only introduced recently (workspaces) and is extremely primitive (no transitive replacement -- so workspaces depending upon other workspaces is not a thing, workspace-vendoring in the next release but will essentially conflict with mod-vendoring). This probably works with skilled and disciplined teams with strict linters and other tooling, and operating in a large mono-repository or on ultra small codebase. For others, it ends up in a large plate of spaghetti code with no help to untangle, and every single newcomer shedding blood, sweat and tears to wrap their head around a codebase which inexorably became monolithic by the invitation of the very language. All learnings obtained from decades of building very large-scale applications in C++, of managing and publishing packages in Java or C#, was essentially put aside and ignored. The sad but good news is that it's all being progressively rediscovered, but relearning from decades of nuget and maven for example, will take time, effort, exemplary humility and open mindedness.