Skip to content

Commit 43e2dd1

Browse files
authored
Merge pull request #2599 from smarter/codetabs1
Add code tabs for _overviews/scala3-book/types-{introduction,generics}.md
2 parents 4ad1037 + 5096fd9 commit 43e2dd1

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

_overviews/scala3-book/types-generics.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,30 @@ Generic classes (or traits) take a type as _a parameter_ within square brackets
1313
The Scala convention is to use a single letter (like `A`) to name those type parameters.
1414
The type can then be used inside the class as needed for method instance parameters, or on return types:
1515

16+
{% tabs stack class=tabs-scala-version %}
17+
18+
{% tab 'Scala 2' %}
19+
```scala
20+
// here we declare the type parameter A
21+
// v
22+
class Stack[A] {
23+
private var elements: List[A] = Nil
24+
// ^
25+
// Here we refer to the type parameter
26+
// v
27+
def push(x: A): Unit =
28+
elements = elements.prepended(x)
29+
def peek: A = elements.head
30+
def pop(): A = {
31+
val currentTop = peek
32+
elements = elements.tail
33+
currentTop
34+
}
35+
}
36+
```
37+
{% endtab %}
38+
39+
{% tab 'Scala 3' %}
1640
```scala
1741
// here we declare the type parameter A
1842
// v
@@ -21,26 +45,42 @@ class Stack[A]:
2145
// ^
2246
// Here we refer to the type parameter
2347
// v
24-
def push(x: A): Unit = { elements = elements.prepended(x) }
48+
def push(x: A): Unit =
49+
elements = elements.prepended(x)
2550
def peek: A = elements.head
2651
def pop(): A =
2752
val currentTop = peek
2853
elements = elements.tail
2954
currentTop
3055
```
56+
{% endtab %}
57+
{% endtabs %}
3158

3259
This implementation of a `Stack` class takes any type as a parameter.
3360
The beauty of generics is that you can now create a `Stack[Int]`, `Stack[String]`, and so on, allowing you to reuse your implementation of a `Stack` for arbitrary element types.
3461

3562
This is how you create and use a `Stack[Int]`:
3663

64+
{% tabs stack-usage class=tabs-scala-version %}
65+
{% tab 'Scala 2' %}
66+
```
67+
val stack = new Stack[Int]
68+
stack.push(1)
69+
stack.push(2)
70+
println(stack.pop()) // prints 2
71+
println(stack.pop()) // prints 1
72+
```
73+
{% endtab %}
74+
{% tab 'Scala 3' %}
3775
```
3876
val stack = Stack[Int]
3977
stack.push(1)
4078
stack.push(2)
4179
println(stack.pop()) // prints 2
4280
println(stack.pop()) // prints 1
4381
```
82+
{% endtab %}
83+
{% endtabs %}
4484

4585
> See the [Variance section][variance] for details on how to express variance with generic types.
4686

_overviews/scala3-book/types-inferred.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,32 @@ next-page: types-generics
1111

1212
As with other statically typed programming languages, in Scala you can _declare_ a type when creating a new variable:
1313

14+
{% tabs xy %}
15+
{% tab 'Scala 2 and 3' %}
1416
```scala
1517
val x: Int = 1
1618
val y: Double = 1
1719
```
20+
{% endtab %}
21+
{% endtabs %}
1822

1923
In those examples the types are _explicitly_ declared to be `Int` and `Double`, respectively.
2024
However, in Scala you generally don’t have to declare the type when defining value binders:
2125

26+
{% tabs abm %}
27+
{% tab 'Scala 2 and 3' %}
2228
```scala
2329
val a = 1
2430
val b = List(1, 2, 3)
2531
val m = Map(1 -> "one", 2 -> "two")
2632
```
33+
{% endtab %}
34+
{% endtabs %}
2735

2836
When you do this, Scala _infers_ the types, as shown in the following REPL interaction:
2937

38+
{% tabs abm2 %}
39+
{% tab 'Scala 2 and 3' %}
3040
```scala
3141
scala> val a = 1
3242
val a: Int = 1
@@ -37,5 +47,7 @@ val b: List[Int] = List(1, 2, 3)
3747
scala> val m = Map(1 -> "one", 2 -> "two")
3848
val m: Map[Int, String] = Map(1 -> one, 2 -> two)
3949
```
50+
{% endtab %}
51+
{% endtabs %}
4052

4153
Indeed, most variables are defined this way, and Scala’s ability to automatically infer types is one feature that makes it _feel_ like a dynamically typed language.

_overviews/scala3-book/types-introduction.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,27 @@ next-page: types-inferred
1212
Scala is a unique language in that it’s statically typed, but often _feels_ flexible and dynamic.
1313
For instance, thanks to type inference you can write code like this without explicitly specifying the variable types:
1414

15+
{% tabs hi %}
16+
{% tab 'Scala 2 and 3' %}
1517
```scala
1618
val a = 1
1719
val b = 2.0
1820
val c = "Hi!"
1921
```
22+
{% endtab %}
23+
{% endtabs %}
2024

2125
That makes the code feel dynamically typed.
2226
And thanks to new features, like [union types][union-types] in Scala 3, you can also write code like the following that expresses very concisely which values are expected as arguments and which types are returned:
2327

28+
{% tabs union-example %}
29+
{% tab 'Scala 3 Only' %}
2430
```scala
2531
def isTruthy(a: Boolean | Int | String): Boolean = ???
2632
def dogCatOrWhatever(): Dog | Plant | Car | Sun = ???
2733
```
34+
{% endtab %}
35+
{% endtabs %}
2836

2937
As the example suggests, when using union types, the types don’t have to share a common hierarchy, and you can still accept them as arguments or return them from a method.
3038

0 commit comments

Comments
 (0)