-
Notifications
You must be signed in to change notification settings - Fork 1k
Rewrote unified types tour #708
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
||
`scala.AnyVal` represents value classes. All value classes are non-nullable and predefined; they correspond to the primitive types of Java-like languages. Note that the diagram above also shows implicit conversions between the value classes. | ||
`scala.AnyVal` represents value classes. All value classes are non-nullable and predefined; they correspond to the primitive types of Java-like languages: `Byte`, `Short`, `Char`, `Int`, `Long`, `Float`, `Double`, and `Boolean`. Scala adds the `Unit` type which is similar to Java's `void`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The automatic conversions between primitives is really important to know about and shouldn't be left out. Unit
is not similar to void
in a very important way which is that it is a value that you can return, unlike void
which is a special case of not returning anything; if that isn't part of the tour by this point, you must explain it or "similar to void" is more misleading than helpful.
|
||
## Scala Class Hierarchy ## | ||
|
||
The superclass of all classes `scala.Any` has two direct subclasses: `scala.AnyVal` and `scala.AnyRef`. | ||
`scala.Any` is the base type of all types. It defines certain universal methods: `==`, `!=`, `equals`, `hashCode`, `toString`. `scala.Any` has two direct subclasses: `scala.AnyVal` and `scala.AnyRef`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The list isn't complete. (See http://www.scala-lang.org/api/2.12.1/scala/Any.html). Either be complete, or give examples (and say they're examples).
@@ -0,0 +1,13 @@ | |||
digraph UnifiedTypes { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This graph is misleading or incomplete in numerous ways, including
- Makes it look like AnyRef has only three children
- Makes it look like Null and Nothing are logically on the same level (they are not)
- Does not show the subtyping relationship between List and Seq
- Doesn't show conversions between primitives
As it stands the graph is worse than nothing. It's really important to get this stuff right to start people off with an accurate mental model instead of a bunch of misconceptions that have to be unlearned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the graph is misleading; some ellipses or other indication of what's missing would be helpful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the graph is still useful to give users a global picture of what is written in this page. But I agree with point 1. of @Ichoran.
@@ -11,15 +11,15 @@ next-page: classes | |||
previous-page: basics | |||
--- | |||
|
|||
In Scala, all values are instances of a class, including numerical values and functions. The diagram below illustrates the class hierarchy. | |||
In Scala, all values are instances of a class, including numerical values and functions. The diagram below illustrates a subset the class hierarchy. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a subset of
|
||
## Nothing and Null | ||
`Nothing` is a subtype of all types. There is no value that has type `Nothing`. There are two uses: The first is to signal abnormal termination such as an exception (i.e. it doesn't return). The second type usage is an element type of empty collections (e.g. `Set[Nothing]`). | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few suggested edits:
Nothing
is a subtype of all types, also called the bottom type. There is no value that has type Nothing
. There are two common uses: the first is to signal non-termination such as a thrown exception, program exit, or an infinite loop (i.e., it is the type of an expression which does not evaluate to a value, or a method that does not return normally); the second common usage is as the element type of empty collections (e.g. Set[Nothing]
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about using “that does not terminate” instead of “that does not return”?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think Set[Nothing]
is probably not a good example because it happens that (even immutable) Set
is invariant in Scala. You could use Nil
(which has type List[Nothing]
), alternatively.
I’m not sure we should mention this use case of Nothing
here, though… You can not really explain it without explaining how does variance work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could say something like "we can conclude from the type List[Nothing]
that Nil
must be empty" which gets the point across while glossing over variance. This is also the case for Set[Nothing]
of course, but as you noted it ends up not being useful due to invariance.
## Nothing and Null | ||
`Nothing` is a subtype of all types. There is no value that has type `Nothing`. There are two uses: The first is to signal abnormal termination such as an exception (i.e. it doesn't return). The second type usage is an element type of empty collections (e.g. `Set[Nothing]`). | ||
|
||
`Null` is a subtype of all subtypes of `AnyRef`. The class name is `Null` but the literal identifier is `null`. You can assign any reference type to null. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few suggested edits:
Null
is a subtype of all reference types (i.e., subtypes of AnyRef
). It has a single value identified by the keyword literal null
. You can assign any reference type to null.
It might also be helpful to note that null is provided mostly for interoperability with other JVM languages and is not commonly used in Scala code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would even be comfortable with a stronger wording like "is never used in normal Scala code".
@@ -11,15 +11,15 @@ next-page: classes | |||
previous-page: basics | |||
--- | |||
|
|||
In Scala, all values are instances of a class, including numerical values and functions. The diagram below illustrates the class hierarchy. | |||
In Scala, all values are instances of a class, including numerical values and functions. The diagram below illustrates a subset the class hierarchy. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's useful to talk about classes here. I suggest
All Scala types inhabit a unified lattice with Any
at the top and Nothing
at the bottom.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After our discussion on gitter I think that indeed, talking about the type hierarchy is probably better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
already settled I guess, but I agree that it's better to say "type" instead of "class" in this (and many other) contexts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related, the eventual diagram shouldn't include Seq
for instance because that's not a type. Seq[Int]
would be ok though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seq
[...] that's not a type.
really? is that not just a pedantic objection? perhaps I misunderstand; can you justify how a beginner might actually be led astray, there?
what about Seq[_]
? would that get rid of the bathwater without losing the baby?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's pedantic … Seq
is a type constructor, not a type. You can't have a variable of type Seq
. You're right of course that we could say Seq[_]
but that's shorthand for Seq[A] forSome { type A }
which I think raises more questions than it answers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
meh... I don't agree this is sufficient reason to leave it out of the diagram. the distinction between type constructors and types isn't important here. I wouldn't object to a footnote with a link to a later section where the issue you raise is addressed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fellow old man yells at other old man
|
||
## Scala Class Hierarchy ## | ||
|
||
The superclass of all classes `scala.Any` has two direct subclasses: `scala.AnyVal` and `scala.AnyRef`. | ||
`scala.Any` is the base type of all types. It defines certain universal methods: `==`, `!=`, `equals`, `hashCode`, `toString`. `scala.Any` has two direct subclasses: `scala.AnyVal` and `scala.AnyRef`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the first sentence I suggest
Any
is the supertype of all types, also called the top type.
@@ -0,0 +1,13 @@ | |||
digraph UnifiedTypes { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the graph is misleading; some ellipses or other indication of what's missing would be helpful.
97288f2
to
d5975e4
Compare
@heathermiller ready to merge |
otherwise LGTM for merge |
No description provided.