Live data from Hacker News

Just Use Go

blainsmith.com

211–220 of 238 posts

Re: Just Use Go

#211
post #209

Earlier quoted context omitted.

I suspect that this is breaking type systems out onto separate axes: strong/weak and static/dynamic. Many consider Python to be strong/dynamic.

depending on the definition of static and dynamic, go could arguably be described as static (personally, i prefer declarative, as static is generally defined as something that i understand to be true for C but not for go), but that still does not make it weak.

I'm saying Go has a weak type system. This was apparently an intentional choice by the authors. Go doesn't even have sum types, which are an extremely basic, foundational feature of type systems. Even C had an equivalent in its union types.

"Weak type system" means that there are many restrictions on what constitutes a valid program that can't be expressed in Go, that can be expressed in languages with stronger type systems, like Rust, Haskell, or even Java and C#.

Re: Just Use Go

#212

> if err != nil is the feature, not the bug. It forces you to look at every place something can go wrong and decide what to do about it. No it really doesn't. It litters your code with if statements that are all just about the same, except that one that needs to be different, and you go blind looking at them all and can't spot the difference. And these days people probably just type "tab" and their LLM assistant fill…

> No it really doesn't. It litters your code with if statements that are all just about the same, except that one that needs to be different, and you go blind looking at them all and can't spot the difference.

If most of your error handling is just bubbling the error up, you are doing something wrong.

  if err != nil { return err; }
is an antipattern. Not because it's verbose, but because you are supposed to handle the error, not pass it right through, in most cases.

Re: Just Use Go

#213
post #101

Earlier quoted context omitted.

It sets primitives to 0, "", false etc. Which is almost always but not always fine. And if they're complex objects you still get NPEs To get true nullable fields you need to use pointers. That's a whole topic in itself but they're awkward. It's much worse than true nullable objects that your compiler can check for NPEs. It throws fewer NPEs but at the expense of data integrity where you don't know if your 0 is actual…

What if Go went all the way? Referencing a zero pointer (nil) gives you the zero value of the pointed to type. If you try to access a zero map, it tries to deference the zero pointer to the underlying buffer. The zero pointer gives you the zero slice with zero length. The presence check fails without crashing and you get some pretension of reasonable behaviour.

Really bad idea.

Silently returning some (the wrong) value is always worse than catching the error right then and their and panicking. A panic is a noticeable symptom of something just having go wrong that is easy to chase after and debug. A silently returned wrong value just causes data corruption down the line, at great pain. It is very annoying to debug, in particular if people start to some times rely on this behaviour as an intentional part of their data flow.

Re: Just Use Go

#214
post #176

Earlier quoted context omitted.

I recently vibe coded a large app in Go, it’s so mind-numbing to read. Like half the code base is error handling.

The anti-exception mind virus of the 2010s did a lot of damage. Go designers finally caved and added panic & recover, but jeez, the damage was done. The whole ecosystem has exception derangement syndrome.

Go had panic/recover right from the get go. Nobody “caved.” And indeed, you are free to use panic/recover for error handling in your code. That was always allowed.

That said, the key insight of the exception craze is that error returns are a normal part of a functions behaviour and as such should not use extraordinary control flow to take place.

Exceptions (panics) are used for things that should never happen or are indicative of a programmer error, like nil dereferences or out-of-bounds array accesses. That is, things where the programmer is not expected to provide reasonable behaviour on the API level if it happens (but perhaps there is a whole-program fault handler to shut down cleanly).

Opening a file that does not exist? Database record not found? Invalid credentials? These should be anticipated by the programmer and can occur at any time. Not exceptions, normal return values. Go requests that you think about these possibilities instead of pretending they can be ignored.

Re: Just Use Go

#215

Earlier quoted context omitted.

The .net sdk is like 1gb, go is like 60mb or something. It's annoying when that matters. More so, nothing happens quickly with it's tooling, and the tooling isn't friendly. All of a sudden I can't build my project in vsstudio(also bloated but admittedly optional but may be required depending on where you work). Clean build also fails. So I have to go to the command line and type in dotnet restore, dotnet build, magic…

That's quite a rant, but it seems like it's from experience with the old times. For the last decade or so it's been a completely different story. System.Text.Json is part of the core standard library, the only reason to use Newtonsoft is developing on legacy applications. Visual Studio isn't necessary or even much recommended any more. VSCode or any LSP editor works fine. You don't need to install nuget, any more tha…

I disagree as someone who was using dotnet within the last 2 years.

Also we are comparing go to .net not to rust. Go is much easier and faster tooling wise. It doesn't require an IL and doesn't have 2 decades of enterprise cruft with vendor lock in strategies baked into it.

I asked to read between the lines.

The experience behind each of these things really stinks compared to go. If you haven't tried it, I recommend it just to feel the ergonomics. I don't care for go as a language. The funny thing is, I find the tooling so much easier, better, faster than .net that even though I like c# more than go as a language, I would prefer to start a new project in go instead of say c# instead. It's that annoying for me. I've met several other people who are language ambivalent who feel the same way.

I could write a huge blog post about it with facts. I'd rather not though. People do what they like and I am not here to change what someone likes.

Re: Just Use Go

#216
post #209

Earlier quoted context omitted.

depending on the definition of static and dynamic, go could arguably be described as static (personally, i prefer declarative, as static is generally defined as something that i understand to be true for C but not for go), but that still does not make it weak.

I'm saying Go has a weak type system. This was apparently an intentional choice by the authors. Go doesn't even have sum types, which are an extremely basic, foundational feature of type systems. Even C had an equivalent in its union types. "Weak type system" means that there are many restrictions on what constitutes a valid program that can't be expressed in Go, that can be expressed in languages with stronger type…

ok, fair enough, what actually interests me is why in your opinion it is weak.

in my understanding, weak typing comes from values being interpreted differently or are silently converted based on how they are used. php taking strings with numeric values when used in a math operation is a form of weak typing.

if that is not what you mean then you are using a different definition for weak typing. that's ok, i don't want to argue about what is the right definition, but i am interested in the definition you are using.

Re: Just Use Go

#217
post #216

Earlier quoted context omitted.

I'm saying Go has a weak type system. This was apparently an intentional choice by the authors. Go doesn't even have sum types, which are an extremely basic, foundational feature of type systems. Even C had an equivalent in its union types. "Weak type system" means that there are many restrictions on what constitutes a valid program that can't be expressed in Go, that can be expressed in languages with stronger type…

ok, fair enough, what actually interests me is why in your opinion it is weak. in my understanding, weak typing comes from values being interpreted differently or are silently converted based on how they are used. php taking strings with numeric values when used in a math operation is a form of weak typing. if that is not what you mean then you are using a different definition for weak typing. that's ok, i don't want…

I was just using "weak" in the ordinary English sense, as in "not powerful". But you're right, that's confusing because of existing terminology.

I should have said that Go has a less expressive type system, i.e. the expressivity of its type system is weak.

It has no sum types, no algebraic data types, no real pattern matching, and limited generic constraints. And of course if we compare it to much more expressive type systems, which is a bit unfair because none of them are mainstream, it has no higher-kinded types, no dependent types, and no refinement types.

As for "true" weak typing, the idiomatic use of `any` (`interface{}`) in Go comes pretty close. While languages with more expressive type systems will often have some way to express that general concept, it's typically more constrained, more friendly to static checks, and less unsafe, because of the some of the other properties I mentioned, such as pattern matching where the compiler will warn you if you're not properly checking a value before unsafely accessing it.

The reason for my comment about Python and PHP is because to me, programming in Go feels little different in programming in those languages along with one of the bolted-on static checkers they have - you don't get anywhere close to the same level of static guarantee of correctness of programs. It's difficult to implement Yaron Minsky's adage "make invalid states unrepresentable" in Go's type system, and that's unfortunate.

Re: Just Use Go

#218

Earlier quoted context omitted.

The .net sdk is like 1gb, go is like 60mb or something. It's annoying when that matters. More so, nothing happens quickly with it's tooling, and the tooling isn't friendly. All of a sudden I can't build my project in vsstudio(also bloated but admittedly optional but may be required depending on where you work). Clean build also fails. So I have to go to the command line and type in dotnet restore, dotnet build, magic…

That's quite a rant, but it seems like it's from experience with the old times. For the last decade or so it's been a completely different story. System.Text.Json is part of the core standard library, the only reason to use Newtonsoft is developing on legacy applications. Visual Studio isn't necessary or even much recommended any more. VSCode or any LSP editor works fine. You don't need to install nuget, any more tha…

.NET is too slow to use in my pc

Re: Just Use Go

#219
post #176

Earlier quoted context omitted.

The anti-exception mind virus of the 2010s did a lot of damage. Go designers finally caved and added panic & recover, but jeez, the damage was done. The whole ecosystem has exception derangement syndrome.

Go had panic/recover right from the get go. Nobody “caved.” And indeed, you are free to use panic/recover for error handling in your code. That was always allowed. That said, the key insight of the exception craze is that error returns are a normal part of a functions behaviour and as such should not use extraordinary control flow to take place. Exceptions (panics) are used for things that should never happen or are…

You're right about recover being in 1.0 of golang.

I definitely fully understand the trade-offs of returning result/error unions vs handling thrown exceptions. Exception handling is clearly superior to me. That said, the typical performance complaints made against the most common implementations of exceptions are valid.

Re: Just Use Go

#220

> if err != nil is the feature, not the bug. It forces you to look at every place something can go wrong and decide what to do about it. No it really doesn't. It litters your code with if statements that are all just about the same, except that one that needs to be different, and you go blind looking at them all and can't spot the difference. And these days people probably just type "tab" and their LLM assistant fill…

> No it really doesn't. It litters your code with if statements that are all just about the same Wrong thing to be bothered with. This allows static analysis of every possible path the code can take. Try to do that with throw/catch. There is a reason many industry guidelines like misra, jsf, etc just outright ban hidden paths. They have been literally catastrophic. There is a reason why many modern languages like go,…

> Wrong thing to be bothered with. This allows static analysis of every possible path the code can take. Try to do that with throw/catch. There is a reason many industry guidelines like misra, jsf, etc just outright ban hidden paths. They have been literally catastrophic. There is a reason why many modern languages like go, rust, etc, want errors to be explicitly handled.

I mean I'm explicitly supporting how rust does it over go, so I don't understand how this is any kind of rebuttal. In your last sentence you admit that rust enforces that errors are explicitly handled, and I think it does it much better than go does, and does it without littering the codebase with boilerplate if statements. The fact that you're launching into an explanation of the insufficiencies of throw/catch exception handling when that has absolutely nothing to do with what I was arguing... Well, I don't feel the need to argue with you any further. Rust also has errors-as-values and doesn't throw (at least not the common case, just like go), so the go FAQ on exceptions isn't relevant to the discussion.

And I'm just going to end the argument with that, since you seem to be a waste of time to deal with.

Post reply on HN