Seems like there's an obvious solution that was avoided or not known about here. It's not even about being clever. Its about being practical.
I'm talking about a more general concept. A kind of type that can be either one thing or another. For example an Int or an Error.
You have Product types which are types that are two things at the same time an (int and an error) and you have sum types (int or an error).
To illustrate say I have two types that consists of a small finite set of values type A and type B.
A = 1 | 2 (cardinality = 2, A can be a 1 or a 2)
and another type that consists of 3 B = '1 | '2 | '3 (cardinality = 3, B can be a '1, '2 or '3)
A product type is like a tuple or a struct containing both A and B: (A, B). The cardinality of (A, B) is the product of the cardinality of the individual types: 2 * 3 = 6 (1,'1) (1,'2), (1,'3) (2,'1) (2,'2) (2,'3)
in other words cardinality is the total amount of possible values that can be represented by the type.A sum type is a type that consists of EITHER A or B: (A | B). The value can be one or the other. The cardinality becomes the sum of the cardinality of the original types 2 + 3 = 5. In this case the sum type of A | B can be one of these values:
1, 2, '1, '2, '3
Go is missing the sum type. It's like the world of math with only multiplication and no addition. You are missing a critical piece of programming.An option type is simply a Sum type with two possible types. (Any | None)
But it goes far beyond just Options.
For example JSON is not definable as a type in Go. Not without some really awkward stuff (aka reflection lol). You can define it in almost every other modern language:
Python:
JSONTYPE = None | float | int | str | List[JSONTYPE] | Dict[str, JSONTYPE]
Haskell: data JSValue
= JSNull
| JSBool Bool
| JSRational Float
| JSString String
| JSArray [JSValue]
| JSObject (JSObject JSValue)
Rust: #[derive(Debug, PartialEq, Clone)]
enum JsonValue {
Null,
Bool(bool),
Number(f64),
String(String),
Array(Vec<JsonValue>),
Object(HashMap<String, JsonValue>),
}
You can define a type completely isomorphic to json in almost every language. You can't do that at all with Go. Literally this popular data format cannot defined in go. How the heck is that suppose to be "practical"?What does go do when it comes to parsing json? I've seen it and it appears to be the ugliest thing I've ever seen. But that's another deep dive.
>But why are you listening to a podcast in the hopes the guest will admit his ignorance and tell you something you already know, instead of to learn new things?
I just got a job that involves golang and its now a big part of my life as it's now my daily driver. I thought due to the popularity of the language it must be great.
What ended up happening was Go feels like a broken language. But maybe I'm wrong. Maybe Rob Pike had a good reason not to include sum types in his language, or maybe he just didn't know about it. Imagine that, my life and the lives of other people defined by the fact Rob Pike didn't know something.
That's what I want to find out. Is the popularity of his language really stemming from him and other people not knowing any better? Or is it me not knowing any better? Have I not seen the light? Or have you not?
Put it this way. If you read my post and you knew about everything I said here and you love golang... Then you know something I don't. If you learned something then maybe you haven't seen the light.
I don't believe in a single "the light" to be seen. I know something you don't (the ability to create your own array DSL gives you none of the advantages of a particular array DSL developed over decades of hard work), you know something I don't. Go's popular because it got stuff right that other languages in the space like Dart and Swift missed.
[0] https://gist.github.com/mlochbaum/a7c0dcd482bd07f39fffc3332f...
They knew about it, they considered it, and they decided not to do it. Sometimes it's just that simple. It has been mentioned in the FAQ since day one: https://go.dev/doc/faq#variant_types