Hacker News new | ask | show | jobs
by pid-1 641 days ago
Python has sum types

optional_int: int | None = None

2 comments

This is semantically not the same as a sum type (as understood in the sense of Rust, which is afaik the academically accepted way)!

Python's `A | B` is a union operation, but in Rust a sum type is always a disjoint union. In Python, if `A = B = None`, then `A | B` has one possible instance.

In Rust, this sum type has two possible instances. This might not sound like a big deal, but the semantics are quite different.

Sorry, I could not grok the difference, even after reading a few Rust examples.

def foo(int | None = None) ...

... just means the variable's default value is None in a function definition. But it could be either in an actual function call.

There's no difference there because the types are already disjoint.

Say you wanted to define some function taking `YYMMDD | MMDDYY`. If both YYMMDD and MMDDYY are just aliases to `str`, then you gain no information, you cannot discriminate on which one it is, since the union `str | str` just reduces to `str`.

Sum types are disjointed unions, you can't just say `str | str`, the terms are wrapped in unique nominal data constructors, like:

enum Date { MMDDYY(String), YYMMDD(String) }

Then when accepting a `Date` you can discriminate which format it's in. You could do the same in Python by defining two unique types and using `MMDDYY | YYMMDD`.

Every dynamically typed language effectively has one big Sum type that holds all of the other types. IMO this is one reason why dynamic languages have been so popular (because Sum types are incredibly useful, and mainstream statically typed languages have historically had very poor support for them).
I like this observation! It explains a lot.