Type variables can't be introduced in the body of a function
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Mars |
Triaged
|
Wishlist
|
Matt Giuca |
Bug Description
Mars doesn't allow a new type variable to be mentioned in the body of a function. I believe this was by design, but it needs more thought.
Assuming a function id :: a -> a, run this code:
# Define id for ints in a roundabout way
def int_id(x :: Int) :: Int:
var f :: a -> a
# f is the id function (works on any type)
f = id
return f(x)
Syntax error: Undefined type variable "a".
It should be happy to introduce a local variable f :: a -> a.
This rule was introduced to prevent something like "var x :: a" (because it is "meaningless" to have a variable of an unspecified type). However, it's conceivable to have a variable of such a type (e.g., we could introduce a primitive 'default :: a', which always returns the "default" value for any type). In this case, x could be used several times, each time producing a different default value, given different types.
The only thing we want to prevent is code which explicitly assigns a concrete type to such a variable. But that's already prevented (e.g., "Type error in statement 'x = 4'; Term: 4; Type: Int; Expected: a).
So it *should* be possible to introduce type variables in a function's body. The only problem is that currently, all type variables in a function's body are (from the internal viewpoint) existentially quantified (there exists a type for x; we don't know what it is). Type vars introduced in the function's body would be universally quantified, like globals (for all types, x has a value; we can pick any we like). Not sure how easy this would be to implement.
Changed in mars: | |
milestone: | none → 0.3 |
Changed in mars: | |
milestone: | 0.3 → none |
Currently, the strategy for ensuring that the type variables in function arguments/return are suitable for *all* values (universal quantification) is to bind them to dummy atoms. All that should be required is to *not* bind the type variables introduced in the body of the function, and then they should be existentially quantified (if they get bound, they get bound).