You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This syntax is certainly convenient but I really think that we should consider alternatives. The two main issues are:
The syntax doesn't really make any sense if we think about what T<A, B> usually means;
The syntax strongly relates to the idea of generic traits, which we may possibly want in the future.
Taking inspiration from Scala (and Rust), we could use something along these lines:
fun f<T: Sequence{ Element == Int }>(_ xs: T) { ... }
Admittedly that isn't much shorter than the expanded form, which is <T: Sequence where T.Element == Int> but:
we gain the ability to omit possibly repeated occurrences of T in the where clause;
we gain the ability to name (or omit) any associated type without imposing any declaration order;
we can use the same syntax to mix conformance and equality constraints at any depth, e.g., Sequence{ Element: Sequence{ Element == Int } }
if we really want to elide Element we can borrow Swift's trick to write Sequence{ Element }.
I picked angle brackets because square brackets denote fixed-size arrays or projections and parentheses denote the application of a term constructor.
To expand a little on the first point, the use of <> in Hylo (and Swift for the most part) relates to type applications. For example, Array is a type constructor and Array<Int> applies that constructor to produce a type. A trait is a type parameterized by its conforming type. In fact, here's a relatively accurate description of what happens under the covers when we use traits in Hylo, expressed in C++:
// This is a trait declaration.template<typename T>
structStringConvertible {
virtual std::string describe(T const& receiver) const = 0;
};
// This is a conformance declaration.structIntIsStringConvertible: publicStringConvertible<int> {
std::string describe(intconst& receiver) constoverride { ... }
};
// This is a conformance constraint.template<typename T>
voidprint(T const& item, StringConvertible<T> const& witness) {
std::cout << witness.describe(item) << std::endl;
}
That's a lot to say that when I see Sequence<Int> I think about "a witness of Int's conformance to Sequence" rather than "a sequence of Ints". But more crucially, a witness of T's conformance to Sequence is not a type constructor and so it does not make any sense to apply it.
We believe that constraining primary associated types is a more generally useful feature than generic protocols, and using angle-bracket syntax for constraining primary associated types gives users what they generally expect, with the clear analogy between Array and Collection.
For the reason mentioned above I believe that the analogy does not hold and is in fact misleading.
The text was updated successfully, but these errors were encountered:
In Swift we can write this:
That is assuming
Sequence
is defined as follows:This syntax is certainly convenient but I really think that we should consider alternatives. The two main issues are:
T<A, B>
usually means;Taking inspiration from Scala (and Rust), we could use something along these lines:
Admittedly that isn't much shorter than the expanded form, which is
<T: Sequence where T.Element == Int>
but:T
in thewhere
clause;Sequence{ Element: Sequence{ Element == Int } }
Element
we can borrow Swift's trick to writeSequence{ Element }
.I picked angle brackets because square brackets denote fixed-size arrays or projections and parentheses denote the application of a term constructor.
To expand a little on the first point, the use of
<>
in Hylo (and Swift for the most part) relates to type applications. For example,Array
is a type constructor andArray<Int>
applies that constructor to produce a type. A trait is a type parameterized by its conforming type. In fact, here's a relatively accurate description of what happens under the covers when we use traits in Hylo, expressed in C++:That's a lot to say that when I see
Sequence<Int>
I think about "a witness ofInt
's conformance toSequence
" rather than "a sequence ofInt
s". But more crucially, a witness ofT
's conformance toSequence
is not a type constructor and so it does not make any sense to apply it.SE-0346 does mention generic traits:
For the reason mentioned above I believe that the analogy does not hold and is in fact misleading.
The text was updated successfully, but these errors were encountered: