Skip to content

Commit 6b41ad8

Browse files
committed
week 3
1 parent 39144cf commit 6b41ad8

5 files changed

Lines changed: 190 additions & 0 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ project/plugins/project/
1111

1212
# Scala-IDE specific
1313
.scala_dependencies
14+
.cache
1415

1516
# Eclipse
1617
.metadata
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
###Packages
2+
3+
Generally in Scala, as in Java, classes are organized into packages; using a package clause at the top of your source file.
4+
5+
###Traits
6+
7+
In Java, as well as in Scala, a class can only have one superclass - it's a single inheritance language. In practice this can be quite constraining; often times a type would naturally have several super types, or you want to inherit behavior from several super entities that all contribute to the final code of the class.
8+
9+
To do that we can use a concept called *traits*; they're essentially declared like an abstract class, but with `trait` instead of `abstract`
10+
11+
```scala
12+
def height: Int
13+
def width: Int
14+
def surface = height * width
15+
```
16+
17+
Classes, objects, and traits can inherit from at most one class but arbitrarily many traits:
18+
19+
```scala
20+
class Square Shape with Planar with Movable
21+
```
22+
23+
Traits resemble interfaces in Java but are more powerful - they can contain fields and concrete methods. These implementations can be overridden in subclasses. On the other hand, traits cannot have (value) parameters - only classes can (like the numerator and denominator of class `Rational`).
24+
25+
###Top Types
26+
At the top of the scala type hierarchy we find:
27+
28+
* `Any` the base type of all types. It defines methods like '==', '!=', 'hashCode', and 'toString'
29+
* `AnyRef` the base type of all reference types; an alias of `java.lang.Object`
30+
* `AnyVal` the base type of all primitive types; for now these are just the primitives that scala inherits from java
31+
32+
###The Nothing Type
33+
34+
`Nothing` is at the bottom of scala's type hierarchy - it is a subtype of every other type.
35+
36+
There is no value of type `Nothing` - why is that useful?
37+
38+
* to signal abnormal termination; sometimes a function would not return, but instead throw an exception or terminate the program. What would the return type of that function be? The best possible type is nothing - it doesn't return anything.
39+
* as an element type of empty collections (like Set[Nothing])
40+
41+
###Exceptions
42+
Scala's exception handling is similar to Java:
43+
44+
```scala
45+
throw Exc
46+
```
47+
48+
aborts evaluation with the exception Exc - the type of this expression is `Nothing`.
49+
50+
###Null
51+
Every reference class type also has `null` as a value - when somebody expects a string, you could pass it null. The type of `null` is `Null`.
52+
53+
`Null` is a subtype of every class that inherits from `Object` - it is incompatible with subtypes of `AnyVal`
54+
55+
```scala
56+
val x = null
57+
val y: String = x
58+
val z: Int = null //Throws a type mismatch error
59+
```

notes/week 3/003-polymorphism.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
###Polymorphism
2+
3+
As a motivating example, let's look at a datastructure that's been fundamental in many functional languages from the beginnings - the Cons-List
4+
5+
It is an immutable linked list, constructed from two building blocks:
6+
7+
* the empty list, which we call `Nil`
8+
* a cell containg an element and a pointer to the remainder of the list, called `Cons`
9+
10+
Here's what `List(1,2,3)` would look like:
11+
![img](http://i.imgur.com/Cbla4yn.png)
12+
13+
We'd have a reference to a `Cons` cell that contains the 1, and a reference to a `Cons` cell that contains 2, which has a reference to a `Cons` cell that contains 3, which has a reference to `Nil`
14+
15+
A nested list like `List(List(true, false), List(3))` would look like:
16+
![img](http://i.imgur.com/XYcKqde.png)
17+
18+
###Cons-Lists in scala
19+
How would we write this as a class hierarchy in scala?
20+
21+
Here's an outline that would represent lists of integers in this fashion:
22+
23+
```scala
24+
trait IntList ...
25+
class Cons(val head: Int, val tail: IntList) extends IntList ...
26+
class Nil extends IntList ...
27+
```
28+
29+
Notice there's a bit of new syntax in the `Cons` declaration - `val head: Int` defines a parameter and a field definition in the class itself. It's equivalent to:
30+
31+
```scala
32+
class Cons(_head: Int, _tail:IntList) extends IntList {
33+
val head = _head
34+
val tail = _tail
35+
}
36+
```
37+
38+
A list is either
39+
40+
* an empty list `new Nil`, or
41+
* a list `Cons(x, xs) consisting of a `head` element x and a `tail` list xs
42+
43+
###Type Parameters
44+
There's one problem with our type hierarchy - it's way too narrow to only define lists with `Int` elements. If we did it that way, we'd need a type hierarchy for `Double`, `Boolean`, and so on...
45+
46+
What we need to do is generalize the definition - we can do that using the `type` parameter
47+
48+
```scala
49+
trait List[T]
50+
class Cons[T](val: head T, val tail: List[T]) extends List[T]
51+
class Nil[T] extends List[T]
52+
```
53+
54+
So, we're going to define a base trait, List, which takes a type parameter `T`. That base trait List[T] will have two subclasses, `Cons[T]` and `Nil[T]`. `Cons[T]` will now have a head element of type `T`, and a tail element of type `List[T]`
55+
56+
###Generic Functions
57+
Like classes, functions can have type parameters. For instance, here's a function that creates a list consisting of a single element:
58+
59+
```scala
60+
def singleton[T](elem: T) = new Cons[T](elem, new Nil[T])
61+
```
62+
63+
We can then write:
64+
65+
```scala
66+
singleton[Int](1)
67+
singleton[Boolean](true)
68+
```
69+
70+
###Type Inference
71+
The scala compiler can usually deduce the correct type parameters from the value arguments of a function call - so in most cases the type parameters can be left out. The above could just be written as:
72+
73+
```scala
74+
singleton(1)
75+
singleton(true)
76+
```
77+
78+
###Types and Evaluation
79+
80+
Type parameters do not affect evaluation in scala at all - we can assume that all type parameters and type arguments are removed before evaluation of the program. This is called *type erasure*. Types are only important for the compiler to verify that the program satisfies certain correctness properties, but they're not relevant for the actual execution.
81+
82+
###Polymorphism
83+
Polymorphism means that a function type comes "in many forms" - basically, the function can be applied to arguments of many types, or the type can have instances of many types.
84+
85+
We have seen two principle forms of polymorphism - subtyping, and generics.
86+
87+
Subtyping means that instances of a subclass can be passed to a base class - ie, given our `List` hierarchy, anywhere we have a parameter that accepts type `List`, we can pass either a `Nil` or a `Cons`.
88+
89+
Generics means that we can create many instances of a function or class by type parameterization. By using generics, we could create a `List[Int]`, or a `List[List[Boolean]]`, whatever dawg.

notes/week 3/src/Cons/List.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package Cons
2+
3+
trait List[T] {
4+
def isEmpty: Boolean
5+
def head: T
6+
def tail: List[T]
7+
}
8+
9+
class Cons[T](val head: T, val tail: List[T]) extends List[T] {
10+
def isEmpty = false
11+
}
12+
13+
class Nil[T] extends List[T] {
14+
def isEmpty = true
15+
def head = throw new NoSuchElementException("Nil.head")
16+
def tail = throw new NoSuchElementException("Nil.tail")
17+
}

notes/week 3/src/Cons/nth.sc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package Cons
2+
3+
object nth {
4+
def nth[T](n: Int, xs: List[T]): T =
5+
if (xs.isEmpty) throw new IndexOutOfBoundsException
6+
else if (n == 0) xs.head
7+
else nth(n - 1, xs.tail) //> nth: [T](n: Int, xs: Cons.List[T])T
8+
9+
val list = new Cons(1, new Cons(2, new Cons(3, new Nil)))
10+
//> list : Cons.Cons[Int] = Cons.Cons@418c56d
11+
12+
nth(2, list) //> res0: Int = 3
13+
nth(-1, list) //> java.lang.IndexOutOfBoundsException
14+
//| at Cons.nth$$anonfun$main$1.nth$1(Cons.nth.scala:5)
15+
//| at Cons.nth$$anonfun$main$1.apply$mcV$sp(Cons.nth.scala:12)
16+
//| at org.scalaide.worksheet.runtime.library.WorksheetSupport$$anonfun$$exe
17+
//| cute$1.apply$mcV$sp(WorksheetSupport.scala:76)
18+
//| at org.scalaide.worksheet.runtime.library.WorksheetSupport$.redirected(W
19+
//| orksheetSupport.scala:65)
20+
//| at org.scalaide.worksheet.runtime.library.WorksheetSupport$.$execute(Wor
21+
//| ksheetSupport.scala:75)
22+
//| at Cons.nth$.main(Cons.nth.scala:3)
23+
//| at Cons.nth.main(Cons.nth.scala)
24+
}

0 commit comments

Comments
 (0)