https://news.ycombinator.com/item?id=13293290
---
About first class variants:
https://lobste.rs/s/77nu3d/oil_s_parser_is_160x_200x_faster_...
https://github.com/rust-lang/rfcs/pull/2593
Another way I think of this is "types vs. tags": https://oilshell.zulipchat.com/#narrow/stream/208950-zephyr-... (Zulip, requires login)
Basically variant can types stand alone, and have a unique tag. Tags are discriminated at RUNTIME with "pattern matching".
But a variant can belong to multiple sum types, and that's checked statically. This is modeled with multiple inheritance in OOP, but there's no implementation inheritance. Related: https://pling.jondgoodwin.com/post/when-sum-types-inherit/
So basically in the ASDL and C++ and Python type system I can model:
- a Token type is a leaf in an arithmetic expression
- a Token type is a leaf in an word expression
But it's not a leaf in say what goes in a[i], or dozens of other sum types. Shell is a big composition of sublanguages, so this is very useful and natural. Another construct that appears in multiple places is ${x}.
So having these invariants modeled by the type system is very useful, and actually C++ and MyPy are surprisingly more expressive than Rust! (due to multiple inheritance)
Search for %Token here, the syntax I made up for including a first class variant into a sum type:
https://www.oilshell.org/release/0.8.pre9/source-code.wwz/fr...
There is a name for the type, and a name for the tag (and multiple names for the same integer tag). Tags (dynamic) and types (static) are decoupled.