Perl was also a successful language with significant adoption. At least back then, we didn’t know any better.
In twenty years the industry will look back on golang as an avoidable mistake that hampered software development from maturing into an actual engineering discipline, for the false economy of making novice programmers quickly productive. I’m willing to put money on that belief, given sufficiently agreed upon definitions.
Modern PLT and metaprogramming and more advanced type systems enable the creation of even more complex abstractions and concepts, which are even harder to understand or reason about, let alone maintain. This is the antithesis of whatever software engineering represents. Engineering is almost entirely about process. Wielding maximally expressive code is all science. You don't need to be a computer scientist to be a software engineer.
> Much of the language design was motivated by learnings within Google.
And the main problem Google had at the time was a large pool of bright but green CS graduates who needed to be kept busy without breaking anything important until the mcompany needed to tap into that pool for a bigger initiative.
> What other "modern" language that has more of a focus on software engineering, putting readability and maintainability and stability at the forefront?
This presupposes that golang was designed for readability, maintainability, and stability, and I assert it was not.
We are literally responding to a linked post highlighting how golang engineers are still spending resources trying to avoid runtime nil panics. This was widely known and recognized as a mistake. It was avoidable. And here we are. This is far from the only counterexample to golang being designed for reliability, it’s just the easiest one to hit you over the head with.
Having worked on multiple large, production code bases in go, they are not particularly reliable nor readable. They are somewhat more brittle than other languages I’ve worked with as a rule. The lack of any real ability to actually abstract common components of problems means that details of problems end up needing to be visible to every layer of a solution up and down the stack. I rarely see a PR that doesn’t touch dozens of functions even for small fixes.
Ignoring individual examples, the literal one thing we actually have data on in software engineering is that fewer lines of codes correlates with fewer bugs and that fewer lines of code are easier to read and reason about.
And go makes absolutely indefensible decisions around things like error handling, tuple returns as second class citizens, and limited abstraction ability that inarguably lead to integer multiples more code to solve problems than ought to be necessary. Even if you generally like the model of programming that go presents, even if you think this is the overall right level of abstraction, these flagrant mistakes are in direct contradiction of the few learnings we actually have hard data for in this industry.
Speaking of data, I would love to see convincing data that golang programs are measurably more reliable than their counterparts in other languages.
Instead of ever just actually acknowledging these things as flaws, we are told that Rob Pike designed the language so it must be correct. And we are told that writing three lines of identical error handling around every one line of code is just Being Explicit and that looping over anything not an array or map is Too Much Abstraction and that the plus sign for anything but numbers is Very Confusing but an `add` function is somehow not, as if these are unassailable truths about software engineering.
Instead of actually solving problems around reliability, we’re back to running a dozen linters on every save/commit. And this can’t be part of the language, because Go Doesn’t Have Warnings. Except it does, they’re just provided by a bunch of independent maybe-maintained tools.
> enable the creation of even more complex abstractions and concepts
We’re already working on top of ten thousand and eight layers of abstraction hidden by HTTP and DNS and TLS and IP networking over Ethernet frames processed on machines running garbage-collected runtimes that live-translate code into actual code for a processor that translates that code to actual code it understands, managed by a kernel that convincingly pretends to be able to run thousands of programs at once and pretends to each program that it has access to exabytes of memory, but yeah the ten thousand and ninth layer of abstraction is a problem.
Or maybe the real problem is that the average programmer is terrible at writing good abstractions so we spend eons fighting fires as a result of our collective inability to actually engineer anything. And then we argue that actually it’s abstraction that’s wrong and consign ourselves to never learning how to write good ones. The next day we find a library that cleanly solves some problem we’re dealing with and conveniently forget that Abstractions Are Bad because that’s only something we believe when it’s convenient.
Yes, this is a rant. I am tired of the constant gaslighting from the golang community. It certainly didn’t start with “generics are complicated and unnecessary and the language doesn’t need them”. I don’t know why I’m surprised it hasn’t stopped since them.
- The language has barely changed since inception
- most if not all behavior is localized and explicit meaning changes can be made in isolation nearly anywhere with confidence without understanding the whole
- localized behavior means readable in isolation. There is no metaprogramming macro, no implicit conversion or typing, the context squarely resolves to the bounds containing the glyphs displayed by your text editor of choice.
The goal was not to boil the ocean, the goal was to be better for most purposes than C/C++, Java, Python. Clearly the language has seen some success there.
Yes, abstractions can be useful. Yes, the average engineer should probably be barred from creating abstractions. Go discourages abstractions and reaps some benefits just by doing so.
Go feels like a massive step in the right direction. It doesn't have to be perfect or even remotely perfect. It can still be good or even great. Let's not throw the baby out with the bath water.
I think for the most part I'm in agreement with you, philosophically, but I don't get the hyperfocus on this issue. Most languages you consider better I consider worse, let's leave it at that.
And here is my opinion:
I think in 20 years, Go will still be a mainstream language. As will C and Python. As will Javascript, god help us all.
And while all these languages will still be very much workhorses of the industry, we will have the next-next-next iteration of "Languages that incorporate all that we have learned about programming language design over the last N decades". And they will still be in the same low-single-percentage-points of overall code produced as their predecessors, waiting for their turn to vanish into obscurity when the next-next-next-next iteration of that principle comes along.
And here is why:
Simple tools don't prevent good engineering, and complex tools don't ensure it. There are arcs that were built in ancient Rome, that are still standing TODAY. There are buildings built 10 years ago that are already crumbling.
And yet the mainstream consensus is that C and JavaScript are terrible languages with deep design flaws. These weren’t as obvious pr avoidable at the time, but they’re realities we live with because they’re entrenched.
My assertion is that in twenty years, we’ll still be stuck with go but the honeymoon will be over and its proponents will finally be able to honestly accept and discuss its design flaws. Further, we’ll for the most part collectively accept that—unlike C and JavaScript—the worst of these flaws were own goals that could have and should have been avoided at the time. I further assert that there will never be another mainstream statically-typed language that makes the mistake of nil.
For that matter I think we’ll be stuck with Rust too. But I think the consensus will be that its flaws were a result of its programming model being somewhat novel and that it was a necessary step towards even better things, rather than a complete misstep.
Oh, they all have flaws. But whether these make them "terrible" is a matter of opinion. Because they are certainly all very much usable, useful and up to the tasks they were designed for, or they would have vanished a long time ago.
> and its proponents will finally be able to honestly accept and discuss its design flaws
We are already doing that.
But that doesn't mean we have to share anyones opinion on what is or isn't a terrible language, or their opinions about what languages we should use.
And yes, that is all these are: opinions. The only factually terrible languages are the ones noone uses, and not even all languages that vanished into obscurity are there because people thought them to be "terrible".
Go does a lot of things very well, is very convenient to use, solves a lot of very real problems, and has a lot to offer that is important and useful to us. That's why we use it. Opinions about which languages are supposedly "terrible" and which are not, is not enough to change that.
An new language has to demonstrate to us that its demands on our time are worth it. It doesn't matter if it implements the newest findings about how PLs should be designed according to someones opinion, it doesn't matter if its the bees knees and the shiniest new thing, it doesn't matter if it follows paradigm A and includes feature B...the only thing that matters is: "Are the advantages this new thing confers so important to us, that we have a net benefit from investing the time and effort to switch?"
If the answer to that question is "No", then coders won't switch, because they have no reason to do so. And to be very clear about something: The only person who can answer if that switch is worth for any given programmer, is that programmer.
Lisp, Haskell, OCaml all likely tickle your PL purity needs, but they remain niche languages in the grand scheme of things. Does that make them bad?
I think Go will be the new Java (hopefully without the boilerplate/bloat). It's good enough to do the job in a lot of cases and plenty of problems will be solved with it in a satisfactory manner.
Language wars are only fun to engage with for sport, but it's silly to get upset about them. Most languages have value in different contexts and I believe the real value in this dialog is recognizing when and where a language works and to accept one's preferred choice may not always be "the one".