This is part of updating the implementation to have a single number type.
I have to admit, doing this, I'm hesitant again. I would really like len
functions to return Int, or to clarify in the types that std.range
accepts only integers. But let's experiment, implement this, and get a
feel for it before I make a call.
I thought I was close to having a finished design, but re-reading what
I wrote before ... there are still some loose ends, like the comparison
operator now behaving very unexpectedly. Maybe I should ban cross-value
comparisons after all, and move that to a different function?
I was thinking about this, with my subtype relation. If I really want
"not (T < U)" to mean "every possible value of T is not an instance of
U", then "List[Int]" and "List[String]" might actually be compatible,
and I need a runtime check. But that misses the point of the type
system!
Also add one of these as a golden. I want the other one too, but I first
need to implement reporting nested type errors.
After going through the lattice exercise, and clarifying to myself what
that means, "dynamic" is now no longer a special type that gets treated
differently from the others (like it is, or at least looked to me, in C#
where I took the name from). It is just the type that describes all
possible values, and "Any" is a very good name for that. Also, the long
"Dynamic" was starting to annoy me because it's too long, and also, this
makes it consistent with Mypy.
It was an internal representation only, but there is no technical
reason to not let users refer to it, and in fact I already documented
it.
There is some room for bikeshed. Should it be written "Dynamic", or
"Dyn", or maybe even "_"? But for now I'll go with "Dynamic".
This is also running ahead to the static type checks that I already
implemented on top of this branch, so the documentation does not reflect
so much the work preceding this commit, as the plans for how the type
system will work.