<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<div name="messageBodySection">
<div dir="auto"><span style="font-family:Palatino">Hello,</span><br />
<br />
<span style="font-family:Palatino">I do not have any direct feedback about the details of this proposal, but I did want to chime in to say that this feature would be extremely helpful for simplifying a code base that I am working on.</span></div>
</div>
<div name="messageReplySection">On Jan 13, 2021, 5:56 PM -0800, Peter Wang <novalazy@gmail.com>, wrote:<br />
<blockquote type="cite" style="border-left-color: grey; border-left-width: thin; border-left-style: solid; margin: 5px 5px;padding-left: 10px;">Hi,<br />
<br />
In this proposal, subtypes are distinct d.u. types that share a data<br />
representation with a base type, which is a normal d.u. type.<br />
Subtypes of subtypes are allowed.<br />
Every term of a given subtype must also be valid term in the supertype<br />
(recursively, up to the base type), with the same data representation.<br />
<br />
A subtype can be introduced like this:<br />
<br />
:- type SUBTYPE =< SUPERTYPE<br />
---> BODY.<br />
<br />
The constructor definitions in BODY must be a (non-strict) subset of the<br />
constructors of the supertype. If the supertype t has constructor<br />
f(T1, ..., Tn) then a subtype s =< t may have a constructor<br />
f(S1, ..., Sn) such that Si =< Ti.<br />
<br />
TODO: requires further thought<br />
<br />
- higher order types can have inst constraints now<br />
- existential class constraints must match exactly?<br />
<br />
Any type variable that occurs in SUBTYPE must also occur in SUPERTYPE.<br />
Any universally quantified type variable that occurs in BODY<br />
must also occur in SUBTYPE.<br />
<br />
Examples:<br />
<br />
:- type empty_list =< list(T)<br />
---> [].<br />
<br />
:- type non_empty_list(T) =< list(T)<br />
---> [T | list(T)].<br />
<br />
:- type non_empty_list_of_foo =< list(foo)<br />
---> [foo | list(foo)].<br />
<br />
:- type maybe_univ<br />
---> none<br />
; some [T] univ(T).<br />
<br />
:- type yes_univ =< maybe_univ<br />
---> some [T] univ(T).<br />
<br />
<br />
Type conversions<br />
----------------<br />
<br />
I propose to not introduce any implicit conversion between subtypes and<br />
supertypes, for a few reasons:<br />
<br />
- there are no implicit type conversions anywhere else in the language<br />
- explicit conversions may be easier to understand<br />
- I do not want to set myself up to potentially rewrite the type<br />
checker ;)<br />
<br />
Rather, terms can be coerced between subtype and supertype with an<br />
explicit operation, say, written like a function call:<br />
<br />
Y = coerce(X)<br />
<br />
A coercion from FromType to ToType is type correct if FromType and ToType<br />
are equivalent after replacing any subtypes with their base types.<br />
<br />
For example, if s =< t and non_empty_list(T) =< list(T) then coercions<br />
between these pairs of types should be accepted by the type checker:<br />
<br />
s <-> t<br />
list(s) <-> list(t)<br />
non_empty_list(s) <-> non_empty_list(t)<br />
list(s) <-> non_empty_list(s)<br />
list(s) <-> non_empty_list(t)<br />
<br />
Coercions must be mode correct.<br />
Assume we have a coercion of X:s to Y:t.<br />
If Xi, Xf, Yi, Yf are the initial and final insts of X and Y<br />
then the coercion is mode correct iff:<br />
<br />
- Xi is a ground inst (no partial instantiation, no uniqueness)<br />
<br />
- Xf = Xi<br />
<br />
- Yi is free<br />
<br />
- Yf is the glb of Xi and the instantiatedness tree derived from t<br />
where all nodes are bound.<br />
The glb must exist,<br />
Yf must be be ground,<br />
and Yf must be a valid inst of t.<br />
<br />
Coercing a ground term from subtype to supertype is always allowed.<br />
We use the mode system to ensure that a coercion from supertype to<br />
subtype is safe at compile time.<br />
<br />
It would probably be useful to also provide a semidet coercion operation<br />
that can fail at runtime if the term is not valid for the result type.<br />
<br />
<br />
Interaction with modules<br />
------------------------<br />
<br />
The compiler needs to know the definition of the base type in order to<br />
construct, deconstruct and coerce terms of a subtype.<br />
<br />
If a subtype is defined in the interface section of a module M<br />
then its supertype must either<br />
<br />
- be defined in the interface section of M, or<br />
- be defined in a module imported in the interface section of M.<br />
<br />
If a subtype is defined in the implementation section of a module M,<br />
then its supertype must either<br />
<br />
- be defined in M, or<br />
- be defined in the interface section of a module imported by M.<br />
<br />
A subtype may be abstractly exported, like other d.u. types.<br />
Coercions to/from the subtype cannot be checked in modules without<br />
visibility of the subtype definition (and its supertype),<br />
and will be rejected at compile time.<br />
<br />
<br />
Comparison to previous proposal<br />
-------------------------------<br />
<br />
Compared to Fergus's 1998 proposal<br />
(http://lists.mercurylang.org/pipermail/developers/1998-February/002274.html)<br />
the "subtypes" in this proposal works with polymorphically typed<br />
(but non polymorphically moded) predicates and containers in a<br />
straightforward way, without constrained polymorphic modes.<br />
<br />
I think the declarations of the form<br />
<br />
:- subtype SubType < Type :: Inst.<br />
<br />
would have been most useful to provide an inst for a higher order Type,<br />
but we have a different feature to handle that now.<br />
<br />
<br />
I have attached a copy of a module that demonstrates what code using the<br />
proposed feature might look like. (Not suggesting that it would be<br />
better than the cord representation used in the standard library.)<br />
<br />
Peter<br />
<br />
_______________________________________________<br />
developers mailing list<br />
developers@lists.mercurylang.org<br />
https://lists.mercurylang.org/listinfo/developers<br /></blockquote>
</div>
</body>
</html>