Hacker News new | ask | show | jobs
by didibus 2405 days ago
A product type is just a closed group of values where you know in advance what will be grouped and what type the values are going to have that are part of the group.

A class in Java for example is a product type. As it describes a group of fields and their types. Same for a struct in C++.

Where I disagree with the article is that JavaScript does not have product types, because you do not have a definition of such a group of values in advance. A JS object does not list what values it groups and what type they each will have. A JS class comes closer in listing what values it will group, but not their types. Also, product types must be closed, and a JS class defines an open group, at runtime the object could group more then what it specified, unless explicitly frozen. You could say a frozen class defines a product of types where all types are the Object type and thus can be of any value, but that's a stretch, because product types are only as useful as they define a constrained product of possible values for the type.

A sum type is just a known list of possible types a value can take. That's the one people aren't as familiar with as most popular languages don't have a construct like it. It let's you say, this variable can be a String or an Int, but not both.

Often people say product type is AND while sum type is XOR. This variable contains a String AND an Int. They will both be there. So it contains both. That's a product type. This variable can contain a String XOR an Int, they can't be both contained, it is only one or the other. That's a sum type.

You can think in Java that all types are a sum type, they are either null or of their defined type. But null isn't a real type, more that it is an allowable value of all types. So it's a bit of a stretch.

Like the article said, best way to mimic them in popular languages is by extending an abstract class. Each type the variable can be will be a child of the parent. Thus a variable of type parent can be one and only one of its children. It's not full featured, you can't make existing types extend from the parent, so you can't arbitrarily define sum types using any available type. You also often can't list what are all the possible types of parent, depending on the reflection capabilities, knowing what all extend a type isn't always feasible. Also, the static type checkers don't consider these like sum types, so it won't tell you that you forgot to handle cases where parent is of one of its child type. Etc.