Readit News logoReadit News
devjab · 9 months ago
This article makes a lot of great points about the shortcomings of Go. I don’t think explicit error handling is one of them however. I’ve previously spoken about my loathing of exception handling because it adds a “magic” layer to things which is way too easy to mess up. From a technical standpoint that isn’t necessarily a good argument, but from a pragmatic standpoint and decades of experience… well I will take explicit error handling which happens exactly where the errors occur every day. You can argue that Rust does it in a more elegant way, and I prefer it for personal projects. For big projects with a lot of developers of various skill level joining and leaving I think Go’s philosophy is one of the sanest approaches to error handling in the modern world.

Staying in that lane. In my part of the world Go is seeing adoption that no other “new” language has exactly because of its simplicity. It’s not the best language, but it’s often the best general purpose language because it has a lot of build in opinions which protect you from yourself.

the_gipsy · 9 months ago
There are several shortcomings with go's error handling. The author heavily lies onto rust, so the alternative is not exceptions but a `Result<T, Error>` sum type.

No stacktraces and error wrapping forces you to not only invent unique error messages. You must also conceive a unique wrapping message at every call-site so that you can grep the error message and approximate a stacktrace.

The weird "return tuple" , which obviously just exists for errors because there is not a single other place where you can use tuples in the language, and the awkward variable initialization rules, make it so that you use the wrong `err` var at some point. E.g. if you want to reassign the result to an existing var, suddenly you have to declare `var err error`, and if `err` already exists then you have to reuse it.

There should be an enum type in go, or instead of the bizarre "return tuple" mechanics exclusive for errors, they should have added a better syntax sugar for errors like rust's `?` sugar. Instead we have something extremely tedious and quite error prone.

> it has a lot of build in opinions which protect you from yourself

It does have opinions, but too often they seem to be there to protect the language from being criticized. Sadly, this works, as marketing (lying) is an important factor towards making a PL popular in today's market.

masklinn · 9 months ago
> The weird "return tuple" , which obviously just exists for errors because there is not a single other place where you can use tuples in the language

MRV, go does not have tuples.

Go is not the only language with MRV (as a special case) and they’re not necessarily bad, iirc Common Lisp uses them as auxiliary data channels and has a whole host of functions to manipulate and refit them.

Go is singularly incompetent at MRVs though, in the sense that only syntax and builtin functions get access to variable arity (e.g. if you access a map entry you can either get one return which is a value, or two which are the value and whether the key is/was in the map). So MRVs mostly end up being worse tuples infecting everything (e.g. iterators needing Iter and Iter2 because you can’t just yield tuples to for loops).

the_gipsy · 9 months ago
I forgot:

The tenet "accept interfaces, return structs" is violated all over by returning the `error` interface.

IMO it's okay to make behaviour-exceptions specifically for error handling. Rust for example doesn't really have builtin behaviour exceptions specifically for errors, they're generic to sumtypes and just happen to work well for errors. But then in practice you must resort to thiserror or anyhow helper crates to deal with errors in anything but tiny programs.

If you do make behaviour exceptions for error handling, be honest and upfront about it. Don't say "errors are just values so just use them like regular vars" in docs, if then there are several huge exceptions (tuple-returns and breaking a core tenet). If you make exceptions then you might as well do them right, instead of half-assing them. I believe zig does it right, but I haven't gotten around to try it.

packetlost · 9 months ago
Rust and Go's lack of stack traces are basically equivalent in that you need to call an additional function to add the stack context to the error result. For go you use fmt.Errorf, in Rust you use .context from anyhow (bad practice in many contexts IMO) or .inspect_err + log. It's rather unfortunate that neither has an easy way of capturing a line number + file easily and appending it to the context. Go could easily do it, I think. Oh well.

I agree that Go should really have an analogue to Rust's `?`, but you can't really do that in a sane way without sum types to represent your conditions. The very multiple-return style error propagation makes it impractical to do.

IMO Go should add really basic tagged unions and rework the stdlib to use them, but such a change would probably necessitate a v2.

dfawcus · 9 months ago
Alef actually has/had real tuples, as does Limbo.

Looking at Alef, apart from using tuples to provide multiple return values in a C-like language, they don't seem to actually add much functionality over what Go has without them. One of the few extra things is the ability to pass a tuple over a channel, however passing a struct is more or less equivalent.

I've not looked in much detail at what Limbo could do with its tuples.

So maybe they don't really add that much, hence why they were not carried over when Go was created?

Alef had enums, Limbo has something like the Go constant scheme and iota. Limbo also had tagged unions / varient-records, in a sort of Pascal like fashion - the "pick adt".

9rx · 9 months ago
> The weird "return tuple" , which obviously just exists for errors because there is not a single other place where you can use tuples in the language

Go functions also accept a tuple on input. While theoretically you could pass an error, or a pointer to an error for assignment, it is a stretch to claim it is for errors.

yegle · 9 months ago
https://github.com/pkg/errors provides stack traces support. This unfortunately did not get included in the Go1.13 release when error wrapping was introduced.
devjab · 9 months ago
I prefer the structure of Rust errors as it’s fully typed, I don’t like that you can chain them though. It’s a cool feature but it leaves you with some of the same issues exception handling does when the freedom is used “wrong”.
KingOfCoders · 9 months ago
Exceptions are sum types, they just have different syntactic sugar.
abtinf · 9 months ago
Having programmed for over 30 years, including nearly a decade of C#, I would say exceptions are one of the worst ideas in all of programming.

They are just horrific gotos that any library can invoke against your code. They are pretty much never, ever handled correctly. And nearly always, after an exception is “handled”, the application is actually in an unknown state and cannot be reasoned about.

Even junior engineers have a trivial time debugging most go errors, while even experienced principles struggle with figuring out the true cause of a Java exception.

mike_hearn · 9 months ago
Well, I've also programmed for over thirty years and I wouldn't use a language without exceptions and even wrote a whole essay defending that position:

https://blog.plan99.net/what-s-wrong-with-exceptions-nothing...

> Even junior engineers have a trivial time debugging most go errors

Not my experience at all. I had to do this once. An HTTP request to a production server was yielding a 400 Bad Request with no useful information for what was bad about it. No problem, I'll check the logs and look at the source code. Useless: the server was written in Go and the logs had no information about where the error was originating. It was just getting propagated up via return codes and not logged properly. It ended up being faster to blackbox reverse engineer the server. In a language with exceptions there'd have been a stack trace that pinpointed exactly where the error originated, the story of how it was handled, and the story of how the program got there.

Diagnosing errors given stack traces is very easy. I've regularly diagnosed subtle bugs given just logs+stack trace and nothing else. I've also had to do the same for platforms that only have error codes that aren't Go (like Windows). It's much, much harder.

rand_r · 9 months ago
> never handled correctly

I’ve seen this argument, but if you look at real golang code and examples, it’s just a bunch of “if err <> nill” copy pasta on every line. It’s true that handling errors is painstaking, but nothing about golang makes that problem easier. It ends up being a manual, poor-man’s stack-trace with no real advantage over an automatically generated one like in Python.

kaoD · 9 months ago
Many people against Go's error handling do not advocate for exceptions, but for a combination of an Either/Result type (for recoverable errors) and fully aborting (for unrecoverable errors).
pyrale · 9 months ago
Exception and explicit on-the-spot handling are not the only two ways to handle failing processes. Optional/result types wrapping the are a clean way to let devs handle errors, for instance, and chaining operations on them without handling errors at every step is pretty ergonomic.
OtomotO · 9 months ago
But with Exceptions you can easily implement multiple return types in e.g. Java ;)

I shocked my Professor at university with that statement. After I started laughing, he asked me more questions... still went away with a straight A ;D

bazoom42 · 9 months ago
Is “goto” just used to mean “bad and evil” here? Because exceptions are not a goto anymore than a return is a goto. The problem with goto is it can jump to any arbitrary place in your code. Exceptions will only go to catch-blocks up the call stack, which presumably you have written on purpose.
quotemstr · 9 months ago
Hard disagree. Exceptions are actually good. They make code clear and errors hard to ignore. I've written a ton of code over decades in both exceptional and explicit-error languages and I'll take the former every day. There's no function color problem. No syntactic pollution of logic with repetitive error propagation tokens.

Also, exception systems usually come with built in stack trace support, "this error caused by this other error" support, debugger integration ("break the first time something goes wrong"), and tons of other useful features.

(Common Lisp conditions are even better, but you can't have everything.)

You can't just wave the word "goto" around as if it were self-evident that nonlocal flow control is bad. It isn't.

> And nearly always, after an exception is “handled”, the application is actually in an unknown state and cannot be reasoned about.

That's not been my experience at all. Writing exception safe code is a matter of using your language's TWR/disposable/RAII/etc. facility. A programmer who can't get this right is going to bungle explicit error handling too.

Oh, and sum types? Have you read any real world Rust code? Junior developers just add unwrap() until things compile. The result is not only syntactic clutter, but also a program that just panics, which is throwing an exception, the first time something goes wrong.

Many junior developers struggle with error handling in general. They'll ignore error codes. They'll unwrap sum types. They might... well, they'll propagate exceptions non-fat ally, because that's the syntactic default, and that's usually the right thing. We have to design languages with misuse in mind.

Seb-C · 9 months ago
I agree about implicit exceptions, but I think that there is a sweet spot with explicit exceptions like Swift (and maybe Java): where you cannot not-handle one, it is part of a function's signature, and the syntax is still compact enough that it does not hurt readability.
stouset · 9 months ago
Without fail, every single person I’ve seen rave about go’s error handling compares it only to exceptions as if that’s the only alternative.

On the flip side I have yet to find a person who’s familiar with sum types (e.g., Maybe, Option, Result) that finds the golang approach even remotely acceptable.

OtomotO · 9 months ago
Here, you've found me.

I don't LIKE it, but it's acceptable.

I have been working with Rust since 2015 (albeit not professionally, but a lot of side projects) and love it.

But I also dabbled into go the last couple of months and while it has its warts, I see it as another tool in the tool-belt with different trade-offs.

Error handling is weird, but it's working, so shrug

clausecker · 9 months ago
I dislike sum-type based error handling. It is annoying syntactically and only really doable with lots of high-level combinators, which in turn hinder debuggability.
devjab · 9 months ago
I think it’s because Go is an alternative to Java and C# more so than an alternative to Rust. It is for me at least. As I said, Rust isn’t seeing any form of real world adoption in my region while Go is. Go isn’t replacing C/C++ or even Python though, it’s replacing Typescript, C# and Java. Now, there are a lot of good reasons as to why Go shouldn’t be doing that, a lot of them listed in the article, but that’s still what is happening.

As I pointed out I think Rust does it better with its types error handling. That isn’t too relevant for me though as Rust will probably never seem any form of adoption in my part of the world. I think Zig may have a better chance considering how interoperable it is with C, but around here the C++ folks are simply sticking with C++.

DanielHB · 9 months ago
You hit the main gripe I have with Go, its types system is so basic. I get people raving type-correctness of Go when they come from Python but the type system in Go is simply pre-historic by modern day standards.
eska · 9 months ago
That’s to be expected since it is marketed towards beginner and casual programmers.
euroderf · 9 months ago
FWIW... WebAssembly has Option and Result, and adapters for Go.
cowl · 9 months ago
this part of error handling is pure religion. it goes even against one of the most basic go tenents. that code should be easy to read not write. Try reading and understanding the logic of a particular method where 75% of the lines are error noise and only 25% are the ones you need to understand what the method does. yes it's noise because whenever read a codebase for the first time you are never interested on the the error edge case. first glance readability needs to tell you what you are trying to accomplish and only after what you are doing to make sure that is correct.

on this point go's error handling is a massive fail. Notice that I'm not saying explicit error handling is bad. I'm saying the insistence that error handling needs to be implemented inline interleaved with the happy path is the problem. You can have explicit error handling in dedicated error handling sections

majormajor · 9 months ago
> yes it's noise because whenever read a codebase for the first time you are never interested on the the error edge case.

maybe this has something to do with how bug-prone it usually is for a new hire to modify a codebase for the first time in most orgs

you could also just do things fail-fast style and panic everywhere if you REALLY wanted to stop inlining error conditions. or ignore error checks until some sort of guard layer that validates things.

IME you usually don't want to do either of those things, and the go approach at least encourages you to think about it closer to the site than checked exceptions (which you can more easily toss up and up and up and auto-add to signatures of callers). unchecked exceptions are arguably less-bad than "just ignore go return errors" - they'll get seen! - but terrible for a reliability/UX perspective.

optional-esque approaches are nice but just a different flavor of the same overhead IMO.

Yoric · 9 months ago
Do you have examples for the latter?
monksy · 9 months ago
I would certainly argue against the claim that explicit error handling is far overkill.

Where I agree: It forces you to think about all of the possibilities your code might generate. (This is more of a C question than it is with other languages)

However, when abstracting blocks of code away, you don't always need to handle the error immediently or you may want to handle it down the stack.

You're giving up a lot of readability in order for the language to be particular.

madeofpalk · 9 months ago
> It forces you to think about all of the possibilities your code might generate.

Except it doesn't actually. You can totally just ignore it and pretend errors don't exist. Lack of sum types/Result, and pointers as poor mans optional, really hinder's Go's error handling story.

acdha · 9 months ago
> It forces you to think about all of the possibilities your code might generate

I’ve seen way too much Go code which never even tested the err value to believe that until something like errcheck is built in to the compiler.

I do agree that this is a plus for the explicit model but that’s been a better argument for Rust in my experience since there’s better culture and tooling around actually checking errors. I’m sure there are plenty of teams doing a good job here, but it always felt like the one lesson from C they didn’t learn well enough, probably because a language created by experts working at a place with a strong culture of review doesn’t really account for the other 99% of developers.

eru · 9 months ago
Rust handles this much better.

Error handling is still explicit, but it gives you the tools needed to make it less tedious.

XorNot · 9 months ago
When I started trying to teach myself Rust, the error handling story fell apart on me very quick.

Like as soon as I wanted to try and get sensible reporting in their, suddenly we were relieving libraries, adding shims and fighting mismatched types and every article was saying the same thing: haha yeah it's kind of a problem.

I'm very, very unsold on explicit error handling compared to exceptions for practical programming. The number of things which can error in a program is far larger then those that can't.

lkirkwood · 9 months ago
I felt the same but after switching to anyhow and thiserror in pretty much every Rust project I work on I find it quite painless. It's not ideal to rely on crates for a core language feature but I never find myself fighting error types anymore. Have you tried those crates? Do you still hold that opinion?
usrnm · 9 months ago
The problems you're describing don't exist in go. There is exactly one standard type that is used by everyone, at least in public API's, you can always just return the error to the caller, if you don't want to handle it in place. The main difference with exceptions in my practice is the fact that it's a lot easier to mess up, since it requires manual typing. This is probably my main problem with everything being as explicit as possible: it requires people to not make mistakes while performing boring manual tasks. What could possibly go wrong?
Attummm · 9 months ago
For me, the issue with error handling is that while errors are explicitly stated, they are often poorly handled. Rarely have I seen the handling of multiple reasons for why an error might occur, along with tailored approaches to handle each case. This is something very common in older languages like Python or Java
cnity · 9 months ago
As a regular Go user, I agree with this take. Though the tools exist, error wrapping and checking (with errors.Is and so on) is actually pretty rare in my experience.

Positive example of good and appropriate usage here: https://github.com/coder/websocket/blob/master/internal/exam...

Cthulhu_ · 9 months ago
This is down to developer style and agreements though; Go has typed errors and a set of utilities to match them [0]. Not using those is a choice, just like how in Java you can just `catch (Exception e)` after calling a dozen methods that might each throw a different exception.

[0] https://pkg.go.dev/errors

troupo · 9 months ago
It's actually very rare that it should be the caller who has to handle the errors.

Go, however, forces you to spread your error handling over a thousand little pieces with zero overview or control of what's happening.

Rust eventually realised this and introduced try! and ? to simplify this

koito17 · 9 months ago
More importantly, Rust has the notion of a result type and it is designed to be both generic and composable.

A problem I often face in Go and TypeScript code is code that ignores errors, often unintentionally. For instance, many uses of JSON.parse in TypeScript do not check for the SyntaxError that may be thrown. In Go, it is common to see patterns like

  _ := foo.Bar()
  // assume Bar() returns error
This pattern exists to tell the reader "I don't care if this method returns an error". It allows one to avoid returning an error, but it also stops the caller from ever being handle to the error.

Also, the position of the error matters. While the convention in the stdlib is to return errors as the final value, this isn't necessarily followed by third party code.

Similarly, errors are just an interface and there is no requirement to actually handle returned errors. Even if one wants to handle errors, it's quite awkward having to use errors.As or errors.Is to look into a (possibly wrapped) chain of errors.

The benefit of Rust's Result<T, E> is that

- position doesn't matter

- there is strong, static type checking

- the language provides operators like ? to effortlessly pass errors up the call stack, and

- the language provides pattern matching, so it's easy to exhaustively handle errors in a Result

The last two points are extremely important. It's what prevents boilerplate like

  if err != nil {
    return nil, err
  }
and it's what allows one to write type-safe code rather than guess whether errors.As() or errors.Is() should be used to handle a returned error.

Yoric · 9 months ago
> Rust eventually realised this and introduced try! and ? to simplify this

That was prototyped around Rust 0.4, so I wouldn't say "eventually" :)

liotier · 9 months ago
Unsure if this is the right place to ask, but this conversation inspires me this question:

Is there in practice a significant difference between try/catch and Go's "if err" ? Both seem to achieve the same purpose, though try/catch can cover a whole bunch of logic rather than a single function. Is that the only difference ?

flir · 9 months ago
I see a lot of people say this about exceptions, and I don't have that problem. The exception bubbles up the stack until something catches it. Ok it's a different code path, but it's a very simple one (straight up). So you either catch the exception nearby and do something specific with it, or it bubbles up to a generic "I'm sorry there was a problem please try again later" handler.

Honestly makes me wonder what I'm missing. Maybe it's because I don't deal with state much? Do the problems start to mount up when you get into writing transaction locks, rollbacks etc? But I don't see why you wouldn't have the same problems with Go's mechanism.

Hoping to gain enlightenment here.

[copied from a comment below]: They are just horrific gotos that any library can invoke against your code. They are pretty much never, ever handled correctly. And nearly always, after an exception is “handled”, the application is actually in an unknown state and cannot be reasoned about.

Maybe this is it? I prefer a "fail early and often" approach, and I tend to validate my data before I perform operations on it. I don't want to attempt recovery, I want to spew log messages and quit.

uzerfcwn · 9 months ago
Exceptions are difficult to discuss because different languages implement exceptions differently, each with their own downsides. That said, I don't think anyone has an issue with bubbling. Even sum type proponents love Rust's ? shorthand, because it makes it easier to propagate Results up the stack.

The big issue with exceptions in C#, Python and JS is that they're not included in function signatures, which means you have to look up the list of possible exceptions from documentation or source code. This could be amended with checked exceptions like Java, but it allegedly doesn't mesh well with the type system (I haven't personally written Java to confirm this). And then there's the C++ crowd that slaps noexcept on everything for possible performance gains.

Personally, I like the way Koka does exceptions with algebraic effects and type inference. It makes exceptions explicit in function signatures but I don't have to rewrite all the return types (like in Rust) because type inference takes care of all that. It also meshes beautifully with the type system, and the same effect system also generalizes to async, generators, forking and other stuff. Alas, Koka is but a research language, so I still write C# for a living.

acdha · 9 months ago
> They are pretty much never, ever handled correctly. And nearly always, after an exception is “handled”, the application is actually in an unknown state and cannot be reasoned about.

I think that’s misdirected but illustrates the emotional reasons why people develop a negative impression of the concept. Usually it means someone had bad experiences with code written in a poor culture of error handling (e.g. certain Java frameworks) and generalized it to “exceptions are bad” rather than recognizing that error handling isn’t trivial and many programmers don’t take it seriously enough, regardless of the paradigm. As a simple example, C and PHP code have had many, many security and correctness issues caused by _not_ having errors interrupt program execution where the users would have been much better off had the program simply halted on the first unhandled error.

If you write complex programs with lots of mutable shared state, yes, it’s hard to reason about error recovery but that’s misattributing the problem to the mechanism which surfaced the error rather than the fact that their program’s architecture makes it hard to rollback or recover.

pansa2 · 9 months ago
> Go is seeing adoption that no other “new” language has exactly because of its simplicity

Yes - for me, the simplicity is essential. As a part-time programmer, I don't have months to spend learning C++ or Rust.

If my project needs to compile to small(-ish) standalone binaries for multiple platforms (ruling out Python, Ruby, Java, C#, etc) what simple alternative language is there? Plain C?

martindevans · 9 months ago
C# can compile standalone binaries for multiple platforms.
acdha · 9 months ago
Basic Rust doesn’t take months to learn, especially when you’re not trying to do things like distributing crates to other people. I found the compiler to be enough more helpful than Go’s to make them roughly time-equivalent for the subset of common features, especially for a simple CLI tool.
damnever · 9 months ago
Go's error handling is not explicit because error is an interface. So, a nil MyError is not the same as a nil error, and error comparison is inconvenient because the interface constraints are so loose that people often resort to checking errors with strings.Contains.
pif · 9 months ago
> I’ve previously spoken about my loathing of exception handling because it adds a “magic” layer to things which is way too easy to mess up.

I kind of see your point. In this very moment, it doesn't matter whether I agree. What I don't understand, though, is why (typically) people who abhor exceptions are among the fiercest defenders of garbage collection, which does add a “magic” and uncontrollable layer to object destruction.

Personally, having learned to love RAII with C++, I was shocked to discover that other languages discarded it initially and had to add it in later when they realized that their target developers are not as dummy as those choosing Golang.

Mawr · 9 months ago
Different kind of magic. Needing to account for every single line of code being able to throw an exception is very mentally taxing, whereas the existence of a GC removes mental load of needing to account for every single allocation.
bsaul · 9 months ago
How does RAII works in concurrent systems ? It seems to me you need to add compile-time object lifetime evaluation (as in rust) which so far incurs a high toll on language complexity.
sureglymop · 9 months ago
Rust and Go are very different and I feel people want a middle ground that just doesn't exist currently.

A garbage collected relatively simple language that compiles into a statically linked binary but has a type system similar to rust, rest types etc.

Syntactically, Gleam and Kotlin come somewhat close but not really. I like Rust but I do believe it is too complicated for many people who are capable of creating something but are not CS grads nor working as programmers. If you're only gonna use the language every once in a while you won't remember what a vtable is, how and when things are dropped etc. I understand that "the perfect language" doesn't exist but I think both Go and Rust brought amazing things to the table. I can only hope someone takes inspiration from both and creates a widely usable, simple programming language.

iamcalledrob · 9 months ago
Kotlin is interesting as a middle ground, but I still find it much less productive than Go for most tasks, and unsuitable for tasks where you'd reach for Rust.

In practice, Kotlin is extremely complicated, and you end up spending time being clever. There are 1000 ways to do things. Operator overloading. Proxies. Properties. Companion objects. Exceptions AND result types...

The build system (assuming you use Gradle) is tantamount to torture for anyone used to "go build".

The coroutines APIs feel simultaneously more complicated and yet more restrictive than Goroutines. More structured but less flexible and more effort to use.

Access control feels awkward. There's no way to make a type package-private -- it's file-private or available to the whole module. This leads to either a larger API surface than desired, or the inability to break up complexity into multiple files.

Kotlin/Native and Kotlin/JVM really are two different beasts too.

Kotlin/JVM is mature, but then you are running on the JVM, so that cuts out a whole class of use cases you might bust out Rust for.

There is a very weak ecosystem for Kotlin/Native, and it's poorly documented. There are some scary bugs in the bug tracker.

You can't publish source-only libraries for Kotlin/Native either, so you need a complex CI setup to build binaries for every OS and arch under the sun. Or just don't publish libraries at all, which probably feeds in to the weak ecosystem...

the_gipsy · 9 months ago
Don't forget that it's made by someone trying to sell you an IDE!
LinXitoW · 9 months ago
Imho, most features of Rust that people would like to see in Go would still fit into the "concept" of Go. Just like they added generics, they could add just three things: A generic container for errors (Result), one for saner Nil handling (Optional) and a small sprinkling of syntax sugar to make these comfortable to work with (something like an elvis operator equivalent).

Go has the one big advantage that is almost solely responsible for it's success: It was created and directly used by a giant company that could afford to create amazing tooling around it and develop great opensource libraries for it. Already being in use and having libraries feel like the biggest determinants of a languages success.

prmph · 9 months ago
So here is my take on this, once again:

Start with JavaScript. The basic syntax is delightfully direct, it has massive adoption already, the ecosystem is large, the runtimes are getting better all the time, compilation is here with WASM,

Now remove the weird parts (e.g., too much flexibility to redefine things, too much use of the global scope, too much weirdness with numbers, etc.), and add:

- Types (including sum/product types, Result<T>, Maybe<T>, decimals, etc.)

- More functional features (everything-is-an-expression, pattern matching, currying, etc)

- A comprehensive standard library.

Already this starts to yield a language that has the best chance to be what a lot want.

The other major advance in developer tools that I'm wanting to see is revamping HTML to have proper sophisticated controls built-in, controls that can be easily styled with inline CSS. This will reduce the amount of JS needed on the client.

These two things will yield a massive advance in programming productivity, at least as far as web-related development is concerned, IMO

sanderjd · 9 months ago
I think this is a really wise take, and one that I honestly haven't seen before. I would certainly try a language like this.

The one thing I would add: Provide a well-trodden path to easily drop down into Rust/C/C++ for performance critical functionality. I have found this to be a big point in Python's favor over Go; you can write things the slow way (ie. executing in the Python runtime), then profile and figure out where to push things down into an extension. Often you're doing something that already exists in a library like numpy or pandas or polars, but if needed, you can write your own extension.

Does WASM enable FFI on its own?

alper · 9 months ago
I think here you're pointing at something along the lines of Roc/Gleam?
fasterthanlime · 9 months ago
(author here) in which ways does Gleam come short of that? Because I'm also looking for that middle ground and I was very curious to get a look at Gleam.
trissi1996 · 9 months ago
IMHO it's just that it's a beam VM language, which is a fatter runtime/ecosystem than is really needed to achieve the goal stated above can bring it's own bag of problems (but also it's own superpowers).

Also to be productive you have to utilize the rest of the erlang ecosystem, so at least some superficial knowledge in elixir & erlang is helpful for for some use-cases.

Syntactically I actually don't think it's that for off, but I dunno what GP was thinking, maybe that it leans more into functional patterns & sugar for those whereas rust/go can also be used in a procedural style. (Though at least personally I am using way more functional patterns in rust than I expected)

sureglymop · 9 months ago
Trying to come up with a reply made me realize something. I was initially going to write something like "it's just not ready yet" but paused for a moment and reflected on that. That's actually not a real reason why it would come short of that. And instead of talking about how something "is not quite ready yet" we can instead choose to invest into it and use it anyway, with the goal of contributing and helping make it "ready" and more widely used.

Out of everything mentioned, I think Gleam is the most likely to succeed and what I think I will invest in as well. But that's not just because of the language design but rather because of their approach to community and community building! It's a very very nice extra that the language/syntax also happen to be what I like and have described in my previous comment.

neonsunset · 9 months ago
C# and F# will be by far the closest. Other options lack sufficiently good type system or tooling to match either of the two.

Compile to static native binary with 'dotnet publish -p:PublishAot=true' (or add this property to .csproj to not specify on each publish). In the case of F#, you will need to use Console.* methods over 'print*' because print has unbound reflection inside for structural output on "%A" format specifier (it will work most of the time but negatively impacts binary size and causes the compiler to complain).

I can especially recommend F# as "easier more business-focused Rust alternative" because it is expression-oriented, has discriminated unions, full HM type inference and gradual typing is a joy to work with. Data analysis and domain modeling are very pleasant to do in it too.

For systems programming C# is going to be the option to use - it will give you great concurrency primitives, fast (sometimes even zero-cost) native interop, smaller than Go native binaries and a lot of low-level APIs including portable SIMD. Go is often poorly suited for these tasks or can't do them at all (at least without workarounds). There are many new high-performance libraries focused on this domain as .NET gains popularity in non-gaming communities in this area. And of course you benefit from a huge existing ecosystem and won't have to do the all the heavy lifting by yourself unlike in niche languages suggested in sibling comments.

cmrdporcupine · 9 months ago
> A garbage collected relatively simple language that compiles into a statically linked binary but has a type system similar to rust, rest types etc.

So OCaml then (ocamlopt to do native code compilation)

ivell · 9 months ago
There is Crystal and Nim. With especially Nim, there is GC and generates c in the end.
Daegalus · 9 months ago
I love Crystal, but the lack of a proper LSP and tooling makes it hard to just jump in and adopt for bigger projects.
foresto · 9 months ago
Unfortunately, Nim's BDFL is... not known for playing well with others. Perhaps the Nimskull fork will grow into something widely useful?

https://github.com/nim-works/nimskull

tessela · 9 months ago
> A garbage collected relatively simple language that compiles into a statically linked binary but has a type system similar to rust, rest types etc.

Swift.

zapnuk · 9 months ago
If they'd drastically improved their tooling then yes.

But sadly it's not that easy to create a statically liked binary in swift. The last time i did it it also included the whole runtime, and the resulting "hello world" binary was 50mb large. Annoying at least.

For years I wished they got their stuff together, but at this point I'd be very suprised. They probably have too much technical dept already due to the support of XXX edge cases Apple need for iOS/MacOS development.

pansa2 · 9 months ago
> relatively simple
zozbot234 · 9 months ago
> A garbage collected relatively simple language that compiles into a statically linked binary but has a type system similar to rust, rest types etc.

You just described Ocaml and ReasonML (which is Ocaml with Go-like syntax).

glass-z13 · 9 months ago
Last time i tried to install ocaml on windows few months ago i failed to do so, it's a well known thing that it is not 100% supported on windows therefore it wont have the adoption that go/rust has (as it's been the case forever now)
ogogmad · 9 months ago
This doesn't count because the idioms are very different from Go and Rust. And I suspect there's a high learning curve for features like Functors.

If you check the Wikipedia page for OCaml to find out where it gets used, you'll see why it's ocaML. That is, you'll notice that it's mostly a MetaLanguage, or a language for writing other languages. The same observation applies to other languages in the ML family.

Daegalus · 9 months ago
I think Inko (https://inko-lang.org/) has the potential to be that language with some tooling/adoption/maturation
MrBuddyCasino · 9 months ago
> people want a middle ground that just doesn't exist currently

https://borgo-lang.github.io/

Rust syntax, compiles to Go.

ForceBru · 9 months ago
> A garbage collected relatively simple language that compiles into a statically linked binary and has a [good] type system

Yeah! Pattern matching too. What are currently available languages closest to this? AFAIK, Gleam relies on a virtual machine, but otherwise seems promising.

blue_pants · 9 months ago
Stretching 'currently available' a little, there's Roc lang [1]. Though still in development, you can use it for small personal projects. Another caveat is that it's a functional language, which could potentially hinder its wide adoption

[1] https://www.roc-lang.org/

fire_lake · 9 months ago
Try F# with the new AoT compilation option and publish single file switch.
KingOfCoders · 9 months ago

  Go: "I'm a simple language!"
  User uses Go for some time.
  User: "I hate you, you're a simple language!"
Perhaps it's because I'm 50+, I love a simple language.

I feel the "critique" is not very balanced, and I view judgements that are not balanced as weak, as everything in technology is about tradeoffs.

I of course come to a different conclusion: https://www.inkmi.com/blog/why-we-chose-go-over-rust-for-our...

serial_dev · 9 months ago
Very common misrepresentation of any critique of Go. "You just don't get simplicity, you got them Java brainwormz"...

There are many examples in the article that point out the annoying inconsistencies in the language, those are the opposite of simplicity.

I love Rob Pike's presentations on Go, some of them were eye-opening to me. However, I just wish that the Go I see in practice would be much closer to the Go language that Go-fans describe in abstract.

richbell · 9 months ago
I wish the discourse that Go is a "simple" language would die.

Despite its veneer, once you start writing Go it quickly becomes apparent that it isn't simple. Hidden complexity and footguns are abundant (e.g., https://archive.ph/WcyF4).

It's nevertheless a useful language, and I use it quite a bit, but it's not "simple".

jonathanstrange · 9 months ago
I have no idea why anyone would say it's not simple, it's super-simple. Learning how duck typing works with interfaces and how to use it is perhaps the only hurdle. In my experience, only certain BASIC dialects like VisualBasic are simpler.
nulld3v · 9 months ago
This 100%, I was just about to type a long rant up about this. There are so many weird parts of the language that took me forever to grasp, and in many cases, I still don't have an intuitive grasp of things.

And plenty of other examples that aren't in that article:

- You have a struct with an embedded interface. Does the outer struct satisfy the embedded interface? And can I type assert the outer struct into whatever embedded struct is fulfilling the inner interface?

- When should I pass by value and when should I pass by reference? Like I generally know when to choose which, but do I really know without performing a benchmark? And what about arrays? Should I store pointers in them? But it also seems that people just don't care and just randomly roll the dice on when to return a pointer or a value?

- Shorthand variable declaration. How does it work when you shorthand declare two variables but one of them already exists?

Don't both answering the questions, that's not the problem. The problem is that it's just not intuitive enough such that I'm confident I know the correct answer.

LandR · 9 months ago
It's easy not simple, but the consequence is that any complexity that other languages handles for you, in go gets forced onto the developer.

There's more stuff to think about, because the language is doing less for you.

KingOfCoders · 9 months ago
Yes, like "Opening Brace Can't Be Placed on a Separate Line" (from your link).

Everyone can read Go code and understand what happens. There are some minor difficulties like func (*A) vs func (A).,

Seb-C · 9 months ago
The problem is that Go is not designed to be a simple language for it's users, it's designed to be a simple language to implement for it's maintainers.

In my opinion, a simple language should be highly consistent (have a few rules, but which are universal and consistent everywhere). Instead we have a language with weirdnesses, inconsistencies and workarounds all over the place.

A good example is type elision: it's available when declaring arrays, slices and maps, but not for structs. Allowing that would have several benefits in terms of readability, and also allow named parameters via anonymous struct arguments (which would greatly improve the design compared to the ugly workarounds that are currently used).

Deleted Comment

zozbot234 · 9 months ago
Scheme is a simple language, Go just hides complexity until it blows up in the worst possible way. (Of course, most reasonable alternatives to Go are even worse from that POV. See Python, Ruby, JS etc.)
GaryNumanVevo · 9 months ago
Go is "simple" insofar as you're doing simple things. If you've tried writing a KV store or database (as I have) you'll quickly find yourself wanting slightly more modern language features.
KingOfCoders · 9 months ago
"quickly find yourself wanting slightly more modern language features."

Use the tool that works for you.

heresie-dabord · 9 months ago
> Perhaps it's because I have experience, I love a simple language.

(fixed the statement to focus on your value, not age per se)

I love language ergonomics above all. Python wins. But for runtime bang-for-the-buck, Go wins.

LinXitoW · 9 months ago
Go is not simple, it's easy.

The difference, for example is: Go invents an abstraction just for one use case, and just for the standard library/runtime itself, instead of taking the time to create a universal version of that abstraction. Generics for maps and lists, and tuples for error handling.

spirit-sparrow · 9 months ago
I wonder what makes someone go such a great length to bash a language, any language. I say bashing, because even the few valid points in the post are not written in a constructive style. After all is there a language that can't be criticised?

Is the post written to make one feel better having a failed a project the language? (It's not me, it's the language) Or is it the failure to understand that not everyone thinks / works the same and what one finds unacceptably bothersome, others barely notice? Languages that do not cater for a real need would likely vanish on their own, they rarely need help.

As for Go, despite the differences compared to "more sophisticated" languages it works brilliantly for the projects I've encountered. I hope the author is not forced to work with Go though. For the rest of the community, we keep churning out services, giving our feedback to the Go team and seeing the slow evolution of the language without breaking our stuff in production.

pas · 9 months ago
> what makes someone go such a great length to bash ...

"""

Inherent complexity does not go away if you close your eyes.

When you choose not to care about complexity, you're merely pushing it onto other developers in your org, ops people, your customers, someone. Now they have to work around your assumptions to make sure everything keeps running smoothly.

And nowadays, I'm often that someone, and I'm tired of it.

"""

> [Go] works brilliantly for the projects I've encountered.

Of course, C, C++, PHP and JavaScript works too! Of course many many many things "work" in our world. Of course just adding one more lane works too, of course police states work too!

Yet something else would work even more brilliantly?

eikenberry · 9 months ago
That quote sounds like an argument against Rust, not GO. Rust is a complex language and that complexity doesn't go away if you close your eyes to it either. All complexity adds to project complexity.
madeofpalk · 9 months ago
It's just some person's blog and they're having a rant. It's okay, it doesn't have to be that deep.

I would guess the 'why' is because OP feels like they have an opinion that they don't feel is sufficiently represented 'out there'. Indeed, as a not-a-fan-of-go, in 2022 I was confused at go's popularity because it always felt to me to have some pretty glaring shortcomings that were seemingly ignored.

Note that people don't really write big blog posts about PHP being a bad language (anymore?) because that's been done to death.

dingnuts · 9 months ago
Speaking a someone who has written Go full time since 2014:

Go is used in a lot of places for unglamorous things where the most important thing is explicitness, and where all these features that the PL nerds want, do nothing but make things more implicit.

It's not perfect, but it's a great language. People who like it, though, like me, are pragmatists. The shortcomings of the language that are apparent in complex code are strengths when writing the simple straightforward code that makes up most Go projects, because all of THAT becomes much simpler than it would be in a fancier language.

The reason I've never bothered to write a response to these kinds of screeds against Go is that usually I'm too busy getting shit done with it.

lexicality · 9 months ago
Perhaps not everyone likes boring clinical reviews and some people like ones that have a bit of passion and humour in them?

Just because this blog post isn't written in a way you like doesn't mean it doesn't have value to others.

LinXitoW · 9 months ago
One very subjective, very irrational factor for my borderline hate for Go is that for years the Go zealots gaslighted everyone about every single part of Go.

Anything that Go did, no matter if it was the most basic implementation or if other languages already did it (better), was essential, the best and only way to solve that issue.

Anything Go did not do was superfluous and downright a conspiracy by Big Complexity to keep us unenlightened Non-Goers addicted to the Syntax Sugar: Things like sane null handling, sane error handling, less boilerplate, generics, or not creating special cases for everything (generics and tuples) instead of developing one cohesive solution.

Even now, in this thread, the strawmanning continues: Error handling is brought up, and instead of admitting the unmistakable truth that Gos error handling could be much better (s. Rust), people bring up things like JavaScript. As if anyone criticizing Go that JavaScript was the pinnacle of error handling.

stouset · 9 months ago
Dear christ yes.

“Go is designed as a systems programming language” has been retconned so that “systems” is redefined to mean programs talking over a network?

“Real programs won’t use repetitive error handling, but build on top of it.” I don’t think this one needs further explanation.

“Go doesn’t need xyz.” This is just the slow and painful process of the golang community realizing one at a time why other languages have the features they do.

“Explicit is good.” Explicit and verbose are not the same thing. You can have explicit and terse.

“Golang is simple.” Golang is primitive, not simple. There are tons of footguns and gotchas, not all of which are chronicled in the linked essay, which would have been so easy to avoid. And everyone just collectively internalizes these issues as if “just avoid writing those bugs” is a sane mindset any different than the languages that came before.

“Go doesn’t need a package managers.” Oops, it did. Now we’re like three attempts deep.

Over and over and over I feel like we’ve been gaslit and told we’re crazy, only to later on have the community act like (for example) golang always intended to add generics and of course they’re a good idea.

Seb-C · 9 months ago
Yes, I've also grown tired of this toxic mindset, as well as the whole "idiomatic Go" dogma that is very often an excuse for poor engineering practices.
Groxx · 9 months ago
Yeah, this was/is a part big part of my frustration with the ecosystem too. It set a LOT of very problematic patterns in place in the beginning, and many of them are still not unwound.

Stuff like "Go doesn't need dependency injection because it's simple". I heard that literally dozens of times. The opposite is true! It's an even bigger pain without DI because the language is so simple! DI everything or make your users suffer!

Or a personal favorite: "Go doesn't need a package manager". We see where that went, and how much insanely better it is now that we have it.

Or errors. Without wrapping. Oh boy we're gonna pay for that for decades.

There's stuff to like in the language, but the zealots (especially early ones) really did not know which parts they were.

Deleted Comment

coffeebeqn · 9 months ago
Bjarne said it best; There are only two kinds of languages: the ones people complain about and the ones nobody uses.
linhns · 9 months ago
Yet somehow his language meets both criteria somewhat and is only saved by legacy code. Not to say that C++20 or above is not good, I personally think it's one of the best but sadly not every org can afford to upgrade easily.

Deleted Comment

Dead Comment

impulser_ · 9 months ago
Every time I work in a different language I'm always wanting to go back to Go even if it's not the perfect language.

I just love the fact that it literally just works. You install Go, you download code, and write code that's it.

No figuring out what version, runtimes, configurations, build tools, package managers to use. Just install and Go.

I think maybe Rust is the only other programming language that provides the same experience.

Maybe these are just lies I'm telling myself, but every time I use Python, Typescript, or Java I dread programming because I just want to write code and I'm often debugging things or figuring out related to configurations, package managers, build tools and versioning.

Cthulhu_ · 9 months ago
This is the power of Go, its integrated toolchain. It makes interop more difficult like the article says, but in my personal and limited experience that's not a frequent use case.
linhns · 9 months ago
This should be the most celebrated aspect of Go, which Rust adopted, along with channels.
jchw · 9 months ago
Every time I read a critique of Go, I feel the same way: I'm still going to continue to use it anyways. The reason why I am going to continue to use it anyways is because while I understand that it has plenty of easily documented issues in theory (and that people regularly do actually run into in practice), I still find that it is one of the better programming languages in practice anyways. Some of the things that people commonly list as shortcomings I don't agree with (I like the explicit error handling everywhere) and for other things... I often agree, but it doesn't bother me much more than the shortcomings of other programming languages, of which there is certainly no shortage.

I guess I feel bad for people who are particularly sensitive to the areas that Go does not succeed in, because they are probably going to be complaining about it for the rest of their lives. The truth is though, I don't use a bunch of rationale about what is the best programming language to choose which one to work on for a project, I choose a language that I feel works well for me, that I feel I can consistently write good software in, that feels, well, nice to work in. Being a person that values correctness, I do sort of wish that language could be something more like Rust, but for now, it's just not, though it's not like I hate Rust, it's just not what I reach for in a pinch.

Enough has been written about how terrible Go is by this point. At least now I know what it's like to have been a fan of PHP a few years ago! (That's an exaggeration, but it's not that big of one in my opinion.)

wokwokwok · 9 months ago
> I guess I feel bad for people who are particularly sensitive to the areas that Go does not succeed in, because they are probably going to be complaining about it for the rest of their lives.

Well, that’s a stellar endorsement of the article, because that’s literally the point they’re making.

You’ll use go.

…and then regret it.

…but by then it’ll be too late, and you’re stuck with it.

I think the author makes a compelling argument, which is very difficult to counter, that it is a bad choice and you will regret having it in production in many of the explicitly listed cases, and in many professional situations where companies that are not technically competent use unsuitable tech.

Companies should stick to boring tools.

…but, for personal projects? Sure, go for it.

jchw · 9 months ago
There's no tool boring enough to prevent any chance of regret. At the end of the day, it's really, really difficult to anticipate where your pain points will actually wind up in the real world. In practice, I've had lots of really good production success with Go and not too much heartache about the choice. Since adopting it personally (in around 2014) almost every company I've gone to work since has used Go in some capacity and that capacity was usually growing because it was working for them.

Will you regret choosing Go? Maybe. Or, maybe not.

dgellow · 9 months ago
Go is as boring of a tool as it gets. Which is why I will happily use it
grey-area · 9 months ago
No, because it's an example of someone who chose Go and didn't regret it, and continues to choose Go, because the objections of the article are in practice just not very important or compelling.
mort96 · 9 months ago
There's plenty of software I work on from time to time that's written in Go which I'm happy are written in Go. Some of those were even projects which I started and chose the language for.

Then there's software I've been involved in where I believe Go was the wrong choice. And software not written in Go where I believe Go would have been the wrong choice.

My point is, Go is just another programming language, with a unique set of strengths and weaknesses, and there are plenty of cases which i have experienced myself where there are genuinely no regrets around picking Go. Not because there aren't shortcomings in Go, but because there are plenty of cases where those shortcomings don't matter.

In my professional life, I have seen significantly more regret associated with choosing JavaScript on the back-end than with choosing Go. But then again, there are services in production written in JavaScript where that just never has been an issue and there are no regrets.

guappa · 9 months ago
In my personal experience your average go developer that likes go, likes it because he doesn't really know anything else.

As a result most things written in go are, in my own experience, of lower quality compared to things written in other languages.

So using things written in go is usually my last resort, because I expect they won't be high quality before even downloading them.

underdeserver · 9 months ago
Uhh, maybe.

Where is the tradeoff analysis? Yeah, you might regret using Go when some zero value you forget to fill in somewhere pops up later and ruins your pipeline. But are you considering all the issues that didn't pop up because you chose Go?

Java's boilerplate code? Rust and C++'s lifetime analysis and memory management? C's lack of tooling? Python/Typescript's runtime errors? Functional languages' tiny employee pool? How much did trouble did you save by avoiding these?

surgical_fire · 9 months ago
I sort of like Go. The explicit error handling is a little obnoxious sometimes, but it's just a way to get things done. Otherwise I see its simplicity as a strength. It is very ergonomic, easy to pick up, and generally performs pretty well. I perhaps wouldn't pick it for every scenario, but there are plenty of scenarios where it would be a good tool.

Then again, I sort of like Java and Python too, two languages I am proficient enough at. All of those are good tools for what they intend to be.

I don't understand why people get so passionate about programming languages. They are tools. You may like soke more than others, but that doesn't invalidate the ones you don't like.

coldtea · 9 months ago
>I don't understand why people get so passionate about programming languages. They are tools.

Because when you're a professional programmer, tools are a huge part of what you do and how you do it, same like a race driver would need to be passionate about cars.

It's just that for an e.g. carpenter, tools are more or less standadized and simple enough to evaluate.

If saws and hammers and routers had as much variety as programming language tooling, and were as multi-faceted to evalute, carpenters would be absolutely obsessed with using the good ones - even more so than they already are.

pif · 9 months ago
> I choose a language that I feel works well for me

Which is the wisest choice for everyone. Golang is only a problem when a manager imposes it on you.

vasco · 9 months ago
"Manager imposes it on you" just means you work in a team rather than alone. You can pick whatever you like for side projects, of course you're going to use whatever your team uses otherwise.
imjonse · 9 months ago
More generally, when it's not well suited for the problem to be solved. Eager coworkers anticipating Google level traffic may want to write the system in Go and multiple microservices when a simple FastAPI server would do.
AnimalMuppet · 9 months ago
Only a problem when a manager imposes it on you for a program where it doesn't fit well.
guappa · 9 months ago
Plenty of software engineers don't know any better themselves
lenkite · 9 months ago
I like Go, but after writing/reading so much Go code, I get nightmares from `if err != nil` demons punching me in the face. There were so many nice suggestions made to fix this, but there are some extremely conservative and extremely loud-spoken community members who killed all the proposals with vitriolic feedback. Now, the Go team has given up the battle for improving error handling since they are psychologically afraid of these folks.

Every Go developer survey has results where the community overwhelmingly votes to improve error handling, but a few extremists have derailed all progress.

monksy · 9 months ago
> Go does not succeed in, because they are probably going to be complaining about it for the rest of their lives.

A lot of people really don't like Go because they have experienced other language features. Go has taken an arrogant stance at trying to make the decision about what features you might need and has given you a very small amount of things to work with.

Cthulhu_ · 9 months ago
Counterpoint, other languages - notably Javascript, Scala, PHP, maybe Java - have taken the stance that they adopt other languages' features, not because the language needs it, but because developers were clamoring for it. Which led to added complexity, because they kept adding more and more ways to solve a problem or structure an application, which led to every codebase being so different from the next that the amount of transferable skills and knowledge became less and less. Scala is the worst offender for that IMO.

One frequent praise one hears of Go is that a developer can open any codebase and immediately understand what's happening. Go is readable and stable, which are critical for code for the long term.

theshrike79 · 9 months ago
I love the fact that I can pick up a Go project from 5+ years ago and it still compiles with the current toolchain. I might need to do a 'go mod init' first.

It didn't get 67 new features that start shooting deprecation warnings on old functions in the meantime. I don't have to learn new paradigms or switch integral parts of my code to something new.

Generics has been in Go for dunno how long, haven't used it once. Didn't need to.

pmezard · 9 months ago
And a lot of people using Go have experienced other language features as well and either decided against them or that the whole tradeoff was not worth it.

I will keep very fast compilation times and decade long backward compatibility over a lot of your features. Because those are features too.

coldtea · 9 months ago
>I like the explicit error handling everywhere

Then you're doing yourself a disfavor by using Go. In other languages it would be even more explicit, mandatory, and automatically checked whether it's handled!

tonfreed · 9 months ago
Exactly. Every programming language is a tool in your toolbox, and you should choose the appropriate one for the job at hand. For me, that's Go around 95% of the time.

I have no need to worry about a 24 byte overhead for a slice allocation, if I did have to worry about that, I'd probably use C or Rust.

Cthulhu_ · 9 months ago
And since Go is so readable, theoretically getting the core functionality out and rewriting it in a more specialized language would be fairly straightforward. And while it's an investment in time and effort to rewrite a chunk, at least you know what you're writing already.

But that's a point made in the article, that Go is also good for prototyping. But there's a few languages good for that, e.g. Ruby which powered a lot of the HN startups in their early days until parts needed to be rewritten for performance / scalability.

But writing a new, unproven product in a high performance, high difficulty language from the get-go is cargo cult; you hope you will need the performance and correctness offered by the language. Meanwhile, halfbaked hack jobs like Facebook and Twitter exploded in popularity and revenue, and while their performance issues gave their developers headaches, at least they knew what problems they had and had to solve instead of guessing and hoping.

gnabgib · 9 months ago
(2022) Discussions at the time:

(130 points, 148 comments) https://news.ycombinator.com/item?id=34188528

(748 points, 544 comments) https://news.ycombinator.com/item?id=31205072

elcritch · 9 months ago
> I've started caring about semantics a lot more than syntax, which is why I also haven't looked at Zig, Nim, Odin, etc: I am no longer interested in "a better C".

Well the post rambles a fair bit, IMHO. The whole bit about Go being “accidental” is BS given that Rust is just as much “accidental” in its origin and design.

One thing stuck out to me is that Nim certainly isn’t a “better C”. It has a GC or you can use reference counting. You can use it as a better C if you really want.

Nim’s type system avoids many of the problems that Go has, though it’s not nearly as pedantic as Rust.

At the end of the day lots of software has been written and shipped in Go which runs fast, has minimal downtime, generally seems effective, and has minimal security issues. I’d argue (much) fewer software projects have been shipped in Rust. Firefox is still 95%+ C++.

RMPR · 9 months ago
> I’d argue (much) fewer software projects have been shipped in Rust. Firefox is still 95%+ C++.

It's funny but this comment reminded me of this tweet[0] from 2022 (!). I don't have a horse in this race as I am happily using Python and C++ at $DAYJOB. I'd argue that even if much less software has been written in Rust (source?), it still qualifies as "lots of software has been written and shipped" with it. Not to mention all the investments by $BIGCORPS in the language.

0: https://x.com/m_ou_se/status/1599173341117435905