Conversions #1165
kyouko-taiga
started this conversation in
Language design
Conversions
#1165
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
We had a discussion with @dabrahams on the topic of conversions in Hylo. Here are some of our observations:
What does "zero-cost" mean?
What we call a "zero-cost" conversion is one that doesn't cost more than what it would take to build the resulting type anyway. For example, converting
Int
toOptional<Int>
is "zero-cost" because it doesn't cost more than the allocation necessary to store anOptional<Int>
. In contrast, convertngArray<Int>
toArray<Any>
is not zero-cost because it requires a linear pass over the contents of the source.I think this definition leaves a conversion from
{Int, Int}
to{Any, Any}
in some kind of gray area. Maybe @dabrahams can weigh in. I personally think we shouldn't consider tuple conversions to be "zero-cost", but I find difficult to justify this position with the above definition. Converting{a: Int}
to{a: Any}
is as expensive as convertingA
toAny
. Even if the tuple has more than one element, the cost of the conversion will remain constant.The semantics of compiler-known conversions
Implicit conversion from
A
toB
, if allowed, can only occur if the compiler can prove thatA
is subtype ofB
. Hylo's subtype relation is pretty small and almost entirely about structural types, so it is reasonable to expect the compiler to know how it can build an instance ofA
in-place in the storage of aB
(e.g., anInt
in the storage of anOptional<Int>
).In practice, that means we can guarantee that
x as T
costs at most a move ofx
.Explicit conversions?
As an experiment, we think we can try to ban implicit conversions completely. The subtyping relationship would still exist but only serve to tell the compiler how to build an instance of
A
in the storage of a supertype (see above).We would use
x as T
to convert a value to one of its supertypes:We could leverage inference to avoid having to spell long type expressions. For example, all of these calls would be allowed:
f(42 as Optional<_>)
f(42 as Optional)
f(42 as _)
The cost of
as
It is desirable to provide some efficiency guarantees on
x as T
. If we restrict this syntax to compiler-known conversions and literal coercion, we can ensure thatx as T
is "zero-cost". However, providing such a guarantee means that we have to give up on user-defined literal conversions viaExpressibleBy***Literal
.The issue is that writing a conformance to
ExpressibleBy***Literal
typically involves the construction of a type that is then consumed in some specific way. For instance, in Swift:This kind of conformance would not uphold the efficiency guarantees we'd like for
x as T
.If initializing a type from a literal is a privilege of the standard library, we can guarantee that all non "zero-cost" conversions will be expressed with constructor syntax. An additional side benefit is that it would help us optimize type inference for literal expressions more aggressively, which is a known problem in
hc
and evenswiftc
.Beta Was this translation helpful? Give feedback.
All reactions