4 ms·
> Enumerations type myEnum int const ( someValue myEnum = iota anotherValue moreValues ) > Sum types Consider thinking ab
by shhsshs 7y ago
> Enumerations
type myEnum int
const (
someValue myEnum = iota
anotherValue
moreValues
)
> Sum types
Consider thinking about the types in your sum type and what they have in common, and define an interface that they share.
> Recursive types
Not sure what you mean. This is valid Go:
type tree struct {
value int
left *tree
right *tree
}
> Parametric polymorphism
Yes Go sucks in this area. `sort.Interface` is a good example of a workaround, but it isn’t ideal in any way.
> There is no this in GOLANG:
Is this not acceptable?
var x interface{}
json.Unmarshal([]byte(“[1,2,3]”), &x)
And if you don’t like that you get back a `[]interface{}` that happens to hold `int`s that you must type assert, just do it the better way:
var x []int
json.Unmarshal([]byte(“[1,2,3]”), &x)
- crimsonalucard 7y ago> Enumerations - those are integers not enumerations. In Golang they have a type Bool which is either true or false. Can I define my own type using the same convention in GoLang? No. I can't. Ideally I want the ability to do this: type Bool = Enum { True False } or type Tri = Enum { True False QuantumTrueFalseDuality } But in Golang I'm locked in with what the creators provided as primitive types. I can't go deeper. Rust you can. > Sum types. I don't think you know what a sum type is. This is what I mean by lack of knowledge. For sum type (A | B), A and B do not need to have a single thing in common and they do not need to share an interface. Think of a product type (A, B) as A and B and a sum type (A | B) as A or B. The most glaring replacement of sum types in go are done with product types that contain errors from IO functions in GoLang. The Error type does not have anything in common with the Value it usually shadows and therefore both cannot be represented with an interface. > Recursive types. That's somewhat recursive. But that's a pointer. This works and is valid. Ideally though it shouldn't be a pointer but for efficiency during memory allocation this is a viable restriction. Recursive types only with pointer types. > Parametric Polymorphism I agree with you. > Is this not acceptable? No it is not acceptable. Interface is unusable until you make the type concrete with your asserts. Asserts are you executing a guess on a possible JSON permutation. In your second example you are guessing the type to be an array of INTs. What if that string was arriving over the wire as IO and you don't know what configuration it will be in? What if the typing was more complicated? jsonString = "[1,2,True,[1,2,\"hello\"]]" or jsonString = randomJSONFromIO() The assert also leaves an opening for a runtime error which is unacceptable. imagine syntax like this: type JSON :: []JSON | Struct{string: JSON} | bool | int | string | null var x JSON = json.Unmarshal("[[1,2,True,[1,2,\"hello\"]],{}, null]") JSON is a type represented using sums (|), products (Struct) and recursion (JSON). There is no possibility of run time errors here as you don't need to guess a specific permutation of JSON. You don't need to guess because such a type system can fully represent JSON. You see what is missing with go?
- HeyImAlex 7y agoIsn’t that JSON example the same in python, javascript, and ruby? Unmarshalling into an interface is really just a shitty enum; the number of permutations is finite. A type switch here is like a match but less type safe because it won’t check exhaustiveness of the branches.
- crimsonalucard 7y ago>Isn’t that JSON example the same in python, javascript, and ruby? No. Python doesn't have type checking. That example is a made up syntax of golang if golang had all the correct type primitives. In this example I am defining a type in the first line, similar to how you would define a struct in golang. Then using the type in the second line. There is a bit of an error, but it's too late to edit it now. the Struct in the type line should be map[string]JSON. >Unmarshalling into an interface is really just a shitty enum; the number of permutations is finite. The permutations of JSON are infinite. In the real world there are APIs describing deeply hierarchical data that have unpredictable deeply nested data structures. If I had a random JSON string generator, it's not that straightforward how you would save that JSON to a correctly typed variable in a GO program. Unmarshalling you will have to define a new type for every permutation. It makes more sense to traverse the data structure to find it's structure rather then take a wild guess. Either way in golang that "guess" happens at runtime so it will spit out an error at runtime, while with sum types and match you are type safe before the program even runs.
- HeyImAlex 7y agoI mean... that’s the point I was making. Interface is just like using a dynamically typed language. So saying python can do this but golang can’t is wrong. They are effectively the same. RE: Permutation, the unmarshalled value will only ever be float64, bool, string, interface[], or map[string]interface. The nested interfaces are recursively defined. It’s literally just like doing it in rust, except the compiler won’t do exhaustiveness checks for you.
- 7y ago