Open masak opened 5 years ago
A separate question is: should infix:<~~>
follow suit? (And return true
for 3 ~~ Real
.)
I think it's separate question, and not an obvious one, but I'm leaning towards "yes". The meaning of infix:<~~>
then becomes "assignable to", not "instance of".
This seems relevant: conversions.
Especially "a type may not both conform and convert to another".
Coming back to this one a few years later. I think the archetype for type conversion ought to be ALGOL 68. Both in terms of its limitless ambition to get things right (as something to emulate), and its quite astonishing complexity (as something to avoid).
I already said it in the OP:
I'm usually in the camp of "leave well enough alone; don't mess with subtyping"
What's the biggest possible intersection of "have a numeric tower" and "don't mess with subtyping"?
Drive-by-commenting just to mention Typing the Numeric Tower, which seems to get most of its mileage out of (a) union types, (b) ordered intersection types, and (c) refinement types.
À la many Lisps and Smalltalk.
There are many aspects to this, but here's one thing I'd expect would work, by Least Surprise:
Perl 6 famously breaks the Least Surprise here, mumbling something about incompatible representations. That's how you don't get a numeric tower.
But let's think about what's needed. On the face of it,
Real
(presumably a core library type) is indeed not a supertype of Int (a primitive/backed built-in). The type checker is about to signal an error.But let's say before it does, it checks if the
3
value can be sent to a methodReal.cast(3)
(name negotiable). Or rather, since we're at compile time and don't want to run code, it checks if such a call against the typeInt
will signature-bind.Is this a good idea? (I'm usually in the camp of "leave well enough alone; don't mess with subtyping", so I'm not super-comfortable with this solution.) Is there prior art? Are there better solutions out there? (Maybe being explicit is better?) All I have is questions.
In this case, the
Real.cast
method will likely take aRational
, and so we recurse andRational.cast
gets called (and succeeds). In a world where #490 applies, there can be severalcast
candidates. Uh. I think we'll require statically that there be a single most specific one. (Inside, that one may still defer to the next candidate if it wants. But the static check needs there to be a frontrunner.)ISTR there was something in A12 or S12 about this. Going to go look for it now.