Enum variants
Variants currently use the syntax < C_0 : T_0 | C_1 : T_1 | ... | C_n : T_n >. This syntax is a little verbose for constructors that take no arguments, because "no arguments" is represented by the unit type. I'd prefer to write < C | D > instead of < C : () | D : () >, and f C instead of f (C ()).
Right now, C : forall a r. a -> < C : a | r >. I want to keep principle types where possible, so using the simpler syntax I require that C : forall r. < C | r >. If that's the case, then I need a new syntax for multi-argument constructors.
Candidates:
- Tuple style -
C(1, "hi") : forall r. < C(Int, String) | r >An advantage of this syntax is that tuples are currently not defined/implemented, and I'm leaning away from ever doing that. Choosing between "a curried function with anonymous arguments" and "an uncurried function with named arguments" seems like enough options. - Record style -
C{ a = 1, b = "hi" } : forall r. < C{ a : Int, b : String } | r >
Non-candidates:
- Tuple style with braces -
C{1, "hi"} : forall r. < C{Int, String} | r >I reject this because it introduces inconsistency in the meaning of{}, which I am committed to treating as a record.
Potential problems:
-
Tuple and record style might be grammatically or "semantically" ambiguous.
f a b cis a function call.C a b cgives a type error.f (a, b)is a function call (if I implement tuples).C (a, b)is a constructor.f {a, b}is a function call.C {a, b}is a constructor.Exploring this ambiguity:
- before
(\a b -> f Test { a, b }) : ( (x -> < Test : x | r >) -> { a : a, b : b } -> c ) -> a -> b -> c - after
(\f a b -> f Test { a, b }) : ( < Test{ a : a, b : b } | r > -> c ) -> a -> b -> c - before
(\a b -> Test { a, b }) : a -> b -> < Test : { a : a, b : b } | r > - after
(\a b -> Test { a, b }) : a -> b -> < Test{ a : a, b : b } | r >
- before
-
Constructors are no longer functions.
-
I probably can't reuse the
Rowkind between records and variants.
I'm leaning towards tuple-style right now. Also, embedding: (\x -> < C(Int, String) | x >) : forall r. r -> < C(Int, String) | r >.