-
Notifications
You must be signed in to change notification settings - Fork 5
Abstract types
Every specific Pipefish value has a concrete type: int, bool, string, a user-defined struct type, etc. We can instantiate any concrete type with literals (42, "foo", false) or with constructors as with structs, enums, and clone types. Concrete types never have subtypes.
An abstract type is just a union of concrete types, e.g int/float. Such types clearly do have subtypes, in this case int and float, but they can never be instantiated: no value can be of type int/float, it has to be one or the other.
While we can create and use abstract types "on the fly" by using the / operator, we can also give them names in the newtype section, which is to be preferred if you're going to use the same abstract type more than once.
Note that by default, variables are given the type of the value they're initialized with, so if we just wrote myNumber = 42, then myNumber could only ever contain an int.
As syntactic sugar, you can write e.g. int? for int/null, etc.
Note that you can't compare a non-null value with NULL, because you can't compare values of different types. So if you want to know if a variable foo of type int? is equal to NULL, you can't write foo == NULL (because that would cause an error at runtime if foo wasn't NULL) but instead must use the expression foo in null to test its type membership.
The abstract type any contains all types that aren't null or tuple. struct contains all struct values, enum contains all enum values, and label contains all field labels of structs.
For any clonable type, e.g. rune, the abstract type clones{rune} contains the parent type and all its clones.
There are abstract types defined my interfaces, such as Addable, which will be discussed in the next section of this wiki.
While concrete types are nominal, abstract types are structural: two abstract types are equal just if they are the union of the same concrete types. So in our example above, Number is equal to int/float and float/int. Or for example if you haven't defined any clones of rune, then clones{rune} is equal to rune.
🧿 Pipefish is distributed under the MIT license. Please steal my code and ideas.