logoalt Hacker News

samatman11/08/20241 replyview on HN

Pascal enums are not sum types, because they are not the sum of multiple types. They are an enumeration of discrete values, which is why they're called enums.

Sum types in Pascal are called variant records:

  type
    FooKind = (Foo, Bar, Baz); (* An enum *)

    FooOrBaz = record (* This is the sum type *)
      case foo: FooKind of
        Foo: (quux: Double);
        Bar: (zot, zap: Double);
        Baz: (xyzzy: String);
      end
Rust conflates the 'enum' keyword with sum types. Pascal does not do this. One of us is confused about what a sum type is. It isn't me.

As for Go, my full opinion on that subject may be found here. If you're... curious. Let's say.

https://news.ycombinator.com/item?id=40224485


Replies

randomdata11/08/2024

> This is the sum type

This is the exact same thing, except in addition to the tag there is also a data component. Yes, this is the more traditional representation of sum types, but having an "undefined" data component is still identifiable as a sum type. It is the tag that makes the union a sum type.

In Typescript terms, which I think illustrates this well, it is conceptually the difference between:

   { kind: 0 } | { kind: 1 }
and

   { kind: 0; data: T } | { kind: 1; data: U }
Which is to say that there is no difference with respect to the discussion here.

> They are an enumeration of discrete values

Yes, the "tag" is populated with an enumerator. There is an enumerator involved, that it is certain, but it is outside of the type system as the user sees it. It's just an integer generated to serve as an identifier – an identifier like seen in the above examples – but provided automatically. The additional information you can gain from it, like exhaustive matching, comes at the type level, not the number itself.

> Rust conflates the 'enum' keyword with sum types.

Right, because it too uses an enumerator to generate the tag value. Like Ord(foo) before, you can access the enumerated in Rust with something like

    mem::discriminant(&foo)
The spoken usage of 'enum' in Rust is ultimately misplaced, I agree. An enumerator is not a type! But it is not wrong in identifying that an enumerator is involved. It conflates 'enum' only in the very same way you have here.
show 1 reply