-
-
Save shelby3/6639849 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The Union Type Quiz | |
=================== | |
0. Please give your typing approach an intuitive name: | |
Consistent, Unified Subsumption | |
1. Please describe the guiding principle of your typing approach in one sentence: | |
Union is chosen over widening only when all types participating in the subsumption would be widened[1]. | |
[1] https://groups.google.com/d/msg/scala-language/B6f-iubR9Mk/XFjQFsiQbpYJ | |
2. Should there be predefined implicit widening conversions between numbers? | |
( ) Yes, even if they are lossy | |
( ) Yes, but only non-lossy ones | |
(X) No | |
( ) Other: ______________________________ | |
3. What should be the inferred type of the expression | |
List(1, 1.0)? | |
( ) List[Double] | |
( ) List[AnyVal] | |
(X) List[Int|Double] | |
( ) Other: ______________________________ | |
4. What should be the inferred type of the expression | |
List(1: java.lang.Integer, 1.0: java.lang.Double)? | |
( ) List[Number with Comparable[_ >: Double with Integer <: Number with Comparable[_ >: Double with Integer <: Number ...]]] | |
(X) List[java.lang.Integer|java.lang.Double] | |
( ) Other: ______________________________ | |
5. Do you prefer a union type A|B to Either[A, B]? | |
( ) Always | |
( ) Never | |
( ) Sometimes: ______________________________ | |
(X) Other: Need both. | |
6. Do prefer a nullable type T? to e. g. Option[T]? | |
( ) Always | |
( ) Never | |
( ) Sometimes: ______________________________ | |
(X) Other: For GC and runtime performance yes, but it must have same semantics as Option[T] | |
in that it was be logically unboxed before use, c.f. the plans to make extractors nearly as | |
performant as case classes. | |
8. Given the following declarations ... | |
trait T | |
object A extends T | |
object B extends T | |
... what should be the inferred type of | |
if (true) A else B | |
( ) T | |
(X) A|B, to get T then use a cast. Note if this expression is the result type of a function | |
declared to return T, then the subsumption is to T as the result type, per my rule in question 1. | |
( ) Other: ______________________________ | |
9. Does your answer change if | |
- trait T is sealed? | |
( ) Yes, because: __________________________________________________ | |
(X) No, because: of my rule in question 1 | |
- A and/or B are classes? | |
( ) Yes, because: __________________________________________________ | |
(X) No, because: of my rule in question 1 | |
- A/B/T are type constructors? | |
( ) Yes, because: __________________________________________________ | |
(X) No, because: of my rule in question 1 | |
10. What should be the inferred type of | |
if (true) Some(1) else None? | |
( ) Option[Int] | |
(X) Some[Int]|None, ditto question 8. Note that once we have unions, it would make sense to deprecate | |
Option and instead write the Option[Int] type as Some[Int]|None. Thus casts won't be necessary. | |
( ) Other: ______________________________ | |
11. What should be the inferred type of | |
if (true) Nil else List(1).asInstanceOf[::[Int]]? | |
( ) List[Int] | |
(X) Nil|::[Int] | |
( ) Other: ______________________________ | |
12. When should a nominal type be preferred to a more precise union type? | |
( ) Always | |
( ) Never | |
( ) Only if the element types enumerate all subclasses/subobjects of a sealed supertype | |
(X) Other: my rule in question 1 | |
13. When should a more precise structural type be preferred to a union type? | |
( ) Always | |
(X) Never, except where my rule in question 1 allows it. | |
( ) Only if the structural type is specified explicitly | |
( ) Other: ______________________________ | |
14. Given the following declarations ... | |
trait T { def foo: Int } | |
class A extends T { def foo: Int = ???; def bar: Int = ??? } | |
class B extends T { def foo: Int = ???; def bar: Int = ???; def bippy: Int = ??? } | |
... which members are allowed to be called on an instance aOrB of type A|B? | |
[X] aOrB.toString | |
[X] aOrB.foo | |
[ ] aOrB.bar | |
[ ] aOrB.bippy | |
15. How will inference of union types interact with structural types? | |
Structural types subsume to any nominal (i.e. named) types they are conjuncted `with`, | |
else to AnyRef. | |
We can't extract unnamed types from the union in a pattern match. Unions of nominal types | |
is ambitious enough for current Scala type system. There is talk about a future Scala type | |
system that would be more ambitious. | |
16. Given the following definitions ... | |
val x: AnyRef { def foo: Int } = null | |
val y: AnyRef { def foo: Int } = null | |
... should it be allowed to call xOrY.foo? | |
( ) Yes | |
(X) No | |
( ) Other: ______________________________ | |
17. Given the following definitions ... | |
val x = new AnyRef { def foo: Int = 23} | |
val y = new AnyRef { def foo: Int = 42} | |
... should it be allowed to call xOrY.foo? | |
( ) Yes | |
(X) No | |
( ) Other: ______________________________ | |
18. Will your design break existing, valid code? | |
( ) Yes | |
(X) Yes, but it doesn't matter because: as far as I can see, it is the only way we | |
can have a consistent, unified rule for subsumption. Unfortunate it wasn't done earlier, | |
yet hopefully there orders-of-magnitude more Scala code to be written especially if we | |
closing gaping holes such as the lack of unions. | |
( ) No, because: ______________________________ | |
( ) Maybe? | |
19. Describe how null will work with union types: | |
A union may have a null value. | |
20. Will your design make a difference whether a type has been inferred and has been specified explicitly? | |
No, always adhere to the rule I provided in question 1. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment