diff --git a/scala.html.markdown b/scala.html.markdown
index 5a0cc0ff..a55e1f0e 100644
--- a/scala.html.markdown
+++ b/scala.html.markdown
@@ -4,6 +4,7 @@ filename: learnscala.scala
contributors:
- ["George Petrov", "http://github.com/petrovg"]
- ["Dominic Bou-Samra", "http://dbousamra.github.com"]
+ - ["Geoff Liu", "http://geoffliu.me"]
filename: learn.scala
---
@@ -20,16 +21,16 @@ Scala - the scalable language
scala>
- This is the so called REPL. You can run commands in the REPL. Let's do just
- that:
+ This is the so called REPL (Read-Eval-Print Loop). You may type any valid
+ Scala expression into it, and the result will be printed. We will explain what
+ Scala files look like further into this tutorial, but for now, let's start
+ with some basics.
*/
-println(10) // prints the integer 10
-println("Boo!") // printlns the string Boo!
-
-
-// Some basics
+#################################################
+## 1. Basics
+#################################################
// Printing, and forcing a new line on the next print
println("Hello world!")
@@ -37,15 +38,15 @@ println("Hello world!")
print("Hello world")
// Declaring values is done using either var or val
-// val declarations are immutable, whereas var's are mutable. Immutability is
+// val declarations are immutable, whereas var's are mutable. Immutability is
// a good thing.
val x = 10 // x is now 10
x = 20 // error: reassignment to val
-var x = 10
+var x = 10
x = 20 // x is now 20
// Single line comments start with two forward slashes
-/*
+/*
Multi line comments look like this.
*/
@@ -82,262 +83,6 @@ true == false // false
*/
-// Everything is an object, including a function. Type these in the REPL:
-
-7 // results in res30: Int = 7 (res30 is just a generated var name for the result)
-
-// The next line gives you a function that takes an Int and returns it squared
-(x:Int) => x * x
-
-// You can assign this function to an identifier, like this:
-val sq = (x:Int) => x * x
-
-/* The above says this
-
- sq: Int => Int =
-
- Which means that this time we gave an explicit name to the value - sq is a
- function that take an Int and returns Int.
-
- sq can be executed as follows:
-*/
-
-sq(10) // Gives you this: res33: Int = 100.
-
-// The colon explicitly defines the type of a value, in this case a function
-// taking an Int and returning an Int.
-val add10: Int => Int = _ + 10
-
-// Scala allows methods and functions to return, or take as parameters, other
-// functions or methods.
-
-List(1, 2, 3) map add10 // List(11, 12, 13) - add10 is applied to each element
-
-// Anonymous functions can be used instead of named functions:
-List(1, 2, 3) map (x => x + 10)
-
-// And the underscore symbol, can be used if there is just one argument to the
-// anonymous function. It gets bound as the variable
-List(1, 2, 3) map (_ + 10)
-
-// If the anonymous block AND the function you are applying both take one
-// argument, you can even omit the underscore
-List("Dom", "Bob", "Natalia") foreach println
-
-
-
-// Data structures
-
-val a = Array(1, 2, 3, 5, 8, 13)
-a(0)
-a(3)
-a(21) // Throws an exception
-
-val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo")
-m("fork")
-m("spoon")
-m("bottle") // Throws an exception
-
-val safeM = m.withDefaultValue("no lo se")
-safeM("bottle")
-
-val s = Set(1, 3, 7)
-s(0)
-s(1)
-
-/* Look up the documentation of map here -
- * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map
- * and make sure you can read it
- */
-
-
-// Tuples
-
-(1, 2)
-
-(4, 3, 2)
-
-(1, 2, "three")
-
-(a, 2, "three")
-
-// Why have this?
-val divideInts = (x:Int, y:Int) => (x / y, x % y)
-
-divideInts(10,3) // The function divideInts gives you the result and the remainder
-
-// To access the elements of a tuple, use _._n where n is the 1-based index of
-// the element
-val d = divideInts(10,3)
-
-d._1
-
-d._2
-
-
-
-// Combinators
-
-s.map(sq)
-
-val sSquared = s. map(sq)
-
-sSquared.filter(_ < 10)
-
-sSquared.reduce (_+_)
-
-// The filter function takes a predicate (a function from A -> Boolean) and
-// selects all elements which satisfy the predicate
-List(1, 2, 3) filter (_ > 2) // List(3)
-List(
- Person(name = "Dom", age = 23),
- Person(name = "Bob", age = 30)
-).filter(_.age > 25) // List(Person("Bob", 30))
-
-
-// Scala a foreach method defined on certain collections that takes a type
-// returning Unit (a void method)
-aListOfNumbers foreach (x => println(x))
-aListOfNumbers foreach println
-
-
-
-
-// For comprehensions
-
-for { n <- s } yield sq(n)
-
-val nSquared2 = for { n <- s } yield sq(n)
-
-for { n <- nSquared2 if n < 10 } yield n
-
-for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared
-
-/* NB Those were not for loops. The semantics of a for loop is 'repeat', whereas
- a for-comprehension defines a relationship between two sets of data. */
-
-
-
-// Loops and iteration
-
-1 to 5
-val r = 1 to 5
-r.foreach( println )
-
-r foreach println
-// NB: Scala is quite lenient when it comes to dots and brackets - study the
-// rules separately. This helps write DSLs and APIs that read like English
-
-(5 to 1 by -1) foreach ( println )
-
-// A while loops
-var i = 0
-while (i < 10) { println("i " + i); i+=1 }
-
-while (i < 10) { println("i " + i); i+=1 } // Yes, again. What happened? Why?
-
-i // Show the value of i. Note that while is a loop in the classical sense -
- // it executes sequentially while changing the loop variable. while is very
- // fast, faster that Java // loops, but using the combinators and
- // comprehensions above is easier to understand and parallelize
-
-// A do while loop
-do {
- println("x is still less than 10");
- x += 1
-} while (x < 10)
-
-// Tail recursion is an idiomatic way of doing recurring things in Scala.
-// Recursive functions need an explicit return type, the compiler can't infer it.
-// Here it's Unit.
-def showNumbersInRange(a:Int, b:Int):Unit = {
- print(a)
- if (a < b)
- showNumbersInRange(a + 1, b)
-}
-
-
-
-// Conditionals
-
-val x = 10
-
-if (x == 1) println("yeah")
-if (x == 10) println("yeah")
-if (x == 11) println("yeah")
-if (x == 11) println ("yeah") else println("nay")
-
-println(if (x == 10) "yeah" else "nope")
-val text = if (x == 10) "yeah" else "nope"
-
-var i = 0
-while (i < 10) { println("i " + i); i+=1 }
-
-
-
-// Object oriented features
-
-// Classname is Dog
-class Dog {
- //A method called bark, returning a String
- def bark: String = {
- // the body of the method
- "Woof, woof!"
- }
-}
-
-// Classes can contain nearly any other construct, including other classes,
-// functions, methods, objects, case classes, traits etc.
-
-
-
-// Case classes
-
-case class Person(name:String, phoneNumber:String)
-
-Person("George", "1234") == Person("Kate", "1236")
-
-
-
-// Pattern matching
-
-val me = Person("George", "1234")
-
-me match { case Person(name, number) => {
- "We matched someone : " + name + ", phone : " + number }}
-
-me match { case Person(name, number) => "Match : " + name; case _ => "Hm..." }
-
-me match { case Person("George", number) => "Match"; case _ => "Hm..." }
-
-me match { case Person("Kate", number) => "Match"; case _ => "Hm..." }
-
-me match { case Person("Kate", _) => "Girl"; case Person("George", _) => "Boy" }
-
-val kate = Person("Kate", "1234")
-
-kate match { case Person("Kate", _) => "Girl"; case Person("George", _) => "Boy" }
-
-
-
-// Regular expressions
-val email = "(.*)@(.*)".r // Invoking r on String makes it a Regex
-val serialKey = """(\d{5})-(\d{5})-(\d{5})-(\d{5})""".r // Using verbatim (multiline) syntax
-
-val matcher = (value: String) => {
- println(value match {
- case email(name, domain) => s"It was an email: $name"
- case serialKey(p1, p2, p3, p4) => s"Serial key: $p1, $p2, $p3, $p4"
- case _ => s"No match on '$value'" // default if no match found
- })
-}
-
-matcher("mrbean@pyahoo.com") // => "It was an email: mrbean"
-matcher("nope..") // => "No match on 'nope..'"
-matcher("52917") // => "No match on '52917'"
-matcher("52752-16432-22178-47917") // => "Serial key: 52752, 16432, 22178, 47917"
-
-
// Strings
"Scala strings are surrounded by double quotes" //
@@ -379,8 +124,291 @@ val html = """"""
+#################################################
+## 2. Functions
+#################################################
-// Application structure and organization
+// The next line gives you a function that takes an Int and returns it squared
+(x:Int) => x * x
+
+// You can assign this function to an identifier, like this:
+val sq = (x:Int) => x * x
+
+/* The above says this
+
+ sq: Int => Int =
+
+ Which means that this time we gave an explicit name to the value - sq is a
+ function that take an Int and returns Int.
+
+ sq can be executed as follows:
+*/
+
+sq(10) // Gives you this: res33: Int = 100.
+
+// The colon explicitly defines the type of a value, in this case a function
+// taking an Int and returning an Int.
+val add10: Int => Int = _ + 10
+
+
+#################################################
+## 3. Flow Control
+#################################################
+
+1 to 5
+val r = 1 to 5
+r.foreach( println )
+
+r foreach println
+// NB: Scala is quite lenient when it comes to dots and brackets - study the
+// rules separately. This helps write DSLs and APIs that read like English
+
+(5 to 1 by -1) foreach ( println )
+
+// A while loops
+var i = 0
+while (i < 10) { println("i " + i); i+=1 }
+
+while (i < 10) { println("i " + i); i+=1 } // Yes, again. What happened? Why?
+
+i // Show the value of i. Note that while is a loop in the classical sense -
+ // it executes sequentially while changing the loop variable. while is very
+ // fast, faster that Java // loops, but using the combinators and
+ // comprehensions above is easier to understand and parallelize
+
+// A do while loop
+do {
+ println("x is still less than 10");
+ x += 1
+} while (x < 10)
+
+// Tail recursion is an idiomatic way of doing recurring things in Scala.
+// Recursive functions need an explicit return type, the compiler can't infer it.
+// Here it's Unit.
+def showNumbersInRange(a:Int, b:Int):Unit = {
+ print(a)
+ if (a < b)
+ showNumbersInRange(a + 1, b)
+}
+
+
+// Conditionals
+
+val x = 10
+
+if (x == 1) println("yeah")
+if (x == 10) println("yeah")
+if (x == 11) println("yeah")
+if (x == 11) println ("yeah") else println("nay")
+
+println(if (x == 10) "yeah" else "nope")
+val text = if (x == 10) "yeah" else "nope"
+
+var i = 0
+while (i < 10) { println("i " + i); i+=1 }
+
+
+#################################################
+## 4. Data Structures
+#################################################
+
+val a = Array(1, 2, 3, 5, 8, 13)
+a(0)
+a(3)
+a(21) // Throws an exception
+
+val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo")
+m("fork")
+m("spoon")
+m("bottle") // Throws an exception
+
+val safeM = m.withDefaultValue("no lo se")
+safeM("bottle")
+
+val s = Set(1, 3, 7)
+s(0)
+s(1)
+
+/* Look up the documentation of map here -
+ * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map
+ * and make sure you can read it
+ */
+
+
+// Tuples
+
+(1, 2)
+
+(4, 3, 2)
+
+(1, 2, "three")
+
+(a, 2, "three")
+
+// Why have this?
+val divideInts = (x:Int, y:Int) => (x / y, x % y)
+
+divideInts(10,3) // The function divideInts gives you the result and the remainder
+
+// To access the elements of a tuple, use _._n where n is the 1-based index of
+// the element
+val d = divideInts(10,3)
+
+d._1
+
+d._2
+
+
+#################################################
+## 5. Object Oriented Programming
+#################################################
+
+/*
+ Aside: Everything we've done so far in this tutorial has been simple
+ expressions (values, functions, etc). These expressions are fine to type into
+ the command-line interpreter for quick tests, but they cannot exist by
+ themselves in a Scala file. For example, you cannot have just "val x = 5" in
+ a Scala file. Instead, the only top-level constructs allowed in Scala are:
+
+ - objects
+ - classes
+ - case classes
+ - traits
+
+ And now we will explain what these are.
+*/
+
+class Dog {
+ //A method called bark, returning a String
+ def bark: String = {
+ // the body of the method
+ "Woof, woof!"
+ }
+}
+
+// Classes can contain nearly any other construct, including other classes,
+// functions, methods, objects, case classes, traits etc.
+
+// Case classes
+
+case class Person(name:String, phoneNumber:String)
+
+Person("George", "1234") == Person("Kate", "1236")
+
+
+// Objects and traits coming soon!
+
+
+#################################################
+## 6. Pattern Matching
+#################################################
+
+val me = Person("George", "1234")
+
+me match { case Person(name, number) => {
+ "We matched someone : " + name + ", phone : " + number }}
+
+me match { case Person(name, number) => "Match : " + name; case _ => "Hm..." }
+
+me match { case Person("George", number) => "Match"; case _ => "Hm..." }
+
+me match { case Person("Kate", number) => "Match"; case _ => "Hm..." }
+
+me match { case Person("Kate", _) => "Girl"; case Person("George", _) => "Boy" }
+
+val kate = Person("Kate", "1234")
+
+kate match { case Person("Kate", _) => "Girl"; case Person("George", _) => "Boy" }
+
+
+
+// Regular expressions
+val email = "(.*)@(.*)".r // Invoking r on String makes it a Regex
+val serialKey = """(\d{5})-(\d{5})-(\d{5})-(\d{5})""".r // Using verbatim (multiline) syntax
+
+val matcher = (value: String) => {
+ println(value match {
+ case email(name, domain) => s"It was an email: $name"
+ case serialKey(p1, p2, p3, p4) => s"Serial key: $p1, $p2, $p3, $p4"
+ case _ => s"No match on '$value'" // default if no match found
+ })
+}
+
+matcher("mrbean@pyahoo.com") // => "It was an email: mrbean"
+matcher("nope..") // => "No match on 'nope..'"
+matcher("52917") // => "No match on '52917'"
+matcher("52752-16432-22178-47917") // => "Serial key: 52752, 16432, 22178, 47917"
+
+
+#################################################
+## 7. Functional Programming
+#################################################
+
+// Scala allows methods and functions to return, or take as parameters, other
+// functions or methods.
+
+List(1, 2, 3) map add10 // List(11, 12, 13) - add10 is applied to each element
+
+// Anonymous functions can be used instead of named functions:
+List(1, 2, 3) map (x => x + 10)
+
+// And the underscore symbol, can be used if there is just one argument to the
+// anonymous function. It gets bound as the variable
+List(1, 2, 3) map (_ + 10)
+
+// If the anonymous block AND the function you are applying both take one
+// argument, you can even omit the underscore
+List("Dom", "Bob", "Natalia") foreach println
+
+
+// Combinators
+
+s.map(sq)
+
+val sSquared = s. map(sq)
+
+sSquared.filter(_ < 10)
+
+sSquared.reduce (_+_)
+
+// The filter function takes a predicate (a function from A -> Boolean) and
+// selects all elements which satisfy the predicate
+List(1, 2, 3) filter (_ > 2) // List(3)
+List(
+ Person(name = "Dom", age = 23),
+ Person(name = "Bob", age = 30)
+).filter(_.age > 25) // List(Person("Bob", 30))
+
+
+// Scala a foreach method defined on certain collections that takes a type
+// returning Unit (a void method)
+aListOfNumbers foreach (x => println(x))
+aListOfNumbers foreach println
+
+// For comprehensions
+
+for { n <- s } yield sq(n)
+
+val nSquared2 = for { n <- s } yield sq(n)
+
+for { n <- nSquared2 if n < 10 } yield n
+
+for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared
+
+/* NB Those were not for loops. The semantics of a for loop is 'repeat', whereas
+ a for-comprehension defines a relationship between two sets of data. */
+
+
+#################################################
+## 8. Implicits
+#################################################
+
+Coming soon!
+
+
+#################################################
+## 9. Misc
+#################################################
// Importing things
import scala.collection.immutable.List