Skip to content

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

Merged
merged 1 commit into from
May 10, 2017
Merged

Conversation

travissarles
Copy link
Contributor

No description provided.


`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`.
Copy link

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`.
Copy link

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 {
Copy link

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

  1. Makes it look like AnyRef has only three children
  2. Makes it look like Null and Nothing are logically on the same level (they are not)
  3. Does not show the subtyping relationship between List and Seq
  4. 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.

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.

Copy link
Contributor

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.
Copy link

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]`).

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]).

Copy link
Contributor

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”?

Copy link
Contributor

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.

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.

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.

Copy link
Member

@SethTisue SethTisue Feb 23, 2017

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.

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.

Copy link
Contributor

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.

Copy link
Member

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

Copy link

@tpolecat tpolecat Feb 23, 2017

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.

Copy link
Member

@SethTisue SethTisue Feb 23, 2017

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?

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.

Copy link
Member

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.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

me irl

image

Copy link
Member

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`.

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 {

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.

@travissarles
Copy link
Contributor Author

@heathermiller ready to merge

@SethTisue
Copy link
Member

when I build the site locally I see:

screen shot 2017-03-14 at 2 33 45 pm

looks like some malformed Markdown?

@SethTisue
Copy link
Member

otherwise LGTM for merge

@travissarles travissarles mentioned this pull request Mar 17, 2017
33 tasks
@travissarles travissarles merged commit 7ac992c into scala:master May 10, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
5 participants