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
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Rewrote unified types tour
  • Loading branch information
travissarles committed Feb 24, 2017
commit d5975e4ef9e2e4a83e706d969ff9c1aa619feaae
4 changes: 4 additions & 0 deletions tutorials/tour/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
unified-types:
dot -Tsvg unified-types-diagram.dot -o unified-types-diagram.svg
type-casting:
dot -Tsvg type-casting-diagram.dot -o type-casting-diagram.svg
38 changes: 31 additions & 7 deletions tutorials/tour/_posts/2017-02-13-unified-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,20 @@ categories: tour
num: 3
next-page: classes
previous-page: basics
prerequisite-knowledge: classes, 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 have a type, including numerical values and functions. The diagram below illustrates a subset of the type hierarchy.

![Scala Type Hierarchy]({{ site.baseurl }}/resources/images/classhierarchy.img_assist_custom.png)
![Scala Type Hierarchy]({{ site.baseurl }}/tutorial/tour/unified-types-diagram.svg)

## Scala Class Hierarchy ##
## Scala Type Hierarchy ##

The superclass of all classes `scala.Any` has two direct subclasses: `scala.AnyVal` and `scala.AnyRef`.
[`Any`](http://www.scala-lang.org/api/2.12.1/scala/Any.html) is the supertype of all types, also called the top type. It defines certain universal methods such as `equals`, `hashCode`, and `toString`. `Any` has two direct subclasses: `AnyVal` and `AnyRef`.

`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.
`AnyVal` represents value types. There are nine predefined value types and they are non-nullable: `Double`, `Float`, `Long`, `Int`, `Short`, `Byte`, `Char`, `Unit`, and `Boolean`. `Unit` is a value type which carries no meaningful information. There is exactly one instance of `Unit` which can be declared literally like so: `()`. All functions must return something so sometimes `Unit` is a useful return type.

`scala.AnyRef` represents reference classes. All non-value classes are defined as reference class. Every user-defined class in Scala implicitly extends `scala.AnyRef`. If Scala is used in the context of a Java runtime environment, `scala.AnyRef` corresponds to `java.lang.Object`.
`AnyRef` represents reference types. All non-value types are defined as reference types. Anywhere an `AnyRef` Every user-defined type in Scala is a subtype of `AnyRef`. If Scala is used in the context of a Java runtime environment, `AnyRef` corresponds to `java.lang.Object`.

Here is an example that demonstrates that strings, integers, characters, boolean values, and functions are all objects just like every other object:

Expand All @@ -35,7 +36,7 @@ val list: List[Any] = List(
)

list.foreach(element => println(element))
````
```

It defines a variable `list` of type `List[Any]`. The list is initialized with elements of various types, but they all are instance of `scala.Any`, so you can add them to the list.

Expand All @@ -48,3 +49,26 @@ c
true
<function>
```
## Type Casting
Value types can be cast in the following way:
![Scala Type Hierarchy]({{ site.baseurl }}/tutorial/tour/type-casting-diagram.svg)
For example:
```tut
val x: Long = 987654321
val y: Float = x // 9.8765434E8 (note that some precision is lost in this case)

val face: Char = '☺'
val number: Int = face // 9786
```
Casting is unidirectional. This will not compile:
```
val x: Long = 987654321
val y: Float = x // 9.8765434E8
val z: Long = y // Does not conform
```
You can also cast a reference type to a subtype. This will be covered later in the tour.

## Nothing and Null
`Nothing` is a subtype of all types, also called the bottom type. There is no value that has type `Nothing`. A common use 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).

`Null` is a subtype of all reference types (i.e. any subtype of AnyRef). It has a single value identified by the keyword literal `null`. `Null` is provided mostly for interoperability with other JVM languages and should almost never be used in Scala code. We'll cover alternatives to `null` later in the tour.
1 change: 1 addition & 0 deletions tutorials/tour/dot-hot-reload.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ls *.dot | entr make $1 # Choose either unified-types or type-casting (see Makefile)
14 changes: 14 additions & 0 deletions tutorials/tour/type-casting-diagram.dot
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
digraph UnifiedTypes {
node [fontname = "Courier"];
rankdir="BT"


Byte -> Short;
Short -> Int;
Int -> Long;
Long -> Float;
Float -> Double;
Char -> Int;

{rank = same; Double; Float; Long; Int; Short; Byte; }
}
91 changes: 91 additions & 0 deletions tutorials/tour/type-casting-diagram.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions tutorials/tour/unified-types-diagram.dot
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
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.

node [fontname = "Courier"];
rankdir="BT"
AnyVal -> Any;
"AnyRef (java.lang.Object)" -> Any;

Double, Float, Long, Int, Short, Byte, Unit, Boolean, Char -> AnyVal;
List, Option, YourClass -> "AnyRef (java.lang.Object)"

Null -> {List Option YourClass}
"Nothing" -> {Double, Float, Long, Int, Short, Byte, Char, Unit, Boolean, Null}

{rank = min; "Nothing"}
{rank = same; Double; Float; Long; Int; Short; Byte; Char; Unit; Boolean; List; Option; YourClass}
{rank = same; "AnyRef (java.lang.Object)"; AnyVal}
}
Loading