From 04e21799d7cccd5d35063326657928ef068fd108 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Wed, 21 Dec 2011 22:16:38 +0100 Subject: [PATCH 01/36] Update cheatsheets/index.md --- cheatsheets/index.md | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 437df5099c..1d7d537bb0 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -9,10 +9,23 @@ about: Thanks to Brendan O'Connor, this cheat | | | | ------ | ------ | -|

variables

| | -| `var x = 5` | variable | -| Good `val x = 5`
Bad `x=6` | constant | -| `var x: Double = 5` | explicit type | +|

declarations

| | +| `var x = 5`
`x = 6` | mutable variable, value can be changed later | +| Good `val x = 5`
Bad `x=6` | immutable, cannot be changed | +| `var x: Double = 5` | explicit type. if not provided, compiler will pick one (more later) | +| `var x: Double = 5;val y = 42` | semicolons are optional if a statement is the last one in a line | +| `var x = {5}`
`var x = {1+2}` | results of expressions can be assigned, too | +| `def x:String = return "hello world"` | method declaration | +| `def x(foo:String):String = return foo+"hello world"` | method declaration with simple parameter | +| `def x(foo:String, bar:String):String = return foo+"hello world"+bar` | method declaration with two parameters | +| `def x:String = {val x = 1;return "hello world"+1}` | multiple statements need {} around the code | +| `def x = "hello world"`|return keyword and return type declaration are optional. default return value = last value in code block +| `def x {print("hello world")}` | method without "=" means the method has no return type/return type is void (this is a lie to keep things simple, more later) | +| `def x = {def y = 7;y}` | nested declarations are possible| +| `class Foo`| class declaration - nested declaration also possible| +| `class Foo(var x:String, val y:Int)`| class declaration with 2 public fields, one mutable, one immutable. constructor is automatically generated. only new Foo("1",2) is possible| +| `class Foo {var x = 5;val y = 6}`|class like above, but with default constructor, only new Foo() is possible| +| `class Foo {def x = 5}`|class with default constructor and one method| |

functions

| | | Good `def f(x: Int) = { x*x }`
Bad `def f(x: Int) { x*x }` | define function
hidden error: without = it's a Unit-returning procedure; causes havoc | | Good `def f(x: Any) = println(x)`
Bad `def f(x) = println(x)` | define function
syntax error: need types for every arg. | From fa3249fbc958e68801801272f7dfb2c7ab0ef08a Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Thu, 22 Dec 2011 20:17:37 +0100 Subject: [PATCH 02/36] Update cheatsheets/index.md --- cheatsheets/index.md | 52 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 1d7d537bb0..7fb8a57c89 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -1,15 +1,15 @@ --- layout: cheatsheet title: Scalacheat -by: Brendan O'Connor +by: (initial version: Brendan O'Connor) HamsterofDea about: Thanks to Brendan O'Connor, this cheatsheet aims to be a quick reference of Scala syntactic constructions. Licensed by Brendan O'Connor under a CC-BY-SA 3.0 license. --- ###### Contributed by {{ page.by }} -| | | +|note: "this is a lie" means i gave a simplified explanation and left out details which will be covered later | | | ------ | ------ | -|

declarations

| | +|

Basic declarations

| | | `var x = 5`
`x = 6` | mutable variable, value can be changed later | | Good `val x = 5`
Bad `x=6` | immutable, cannot be changed | | `var x: Double = 5` | explicit type. if not provided, compiler will pick one (more later) | @@ -19,13 +19,53 @@ about: Thanks to Brendan O'Connor, this cheat | `def x(foo:String):String = return foo+"hello world"` | method declaration with simple parameter | | `def x(foo:String, bar:String):String = return foo+"hello world"+bar` | method declaration with two parameters | | `def x:String = {val x = 1;return "hello world"+1}` | multiple statements need {} around the code | -| `def x = "hello world"`|return keyword and return type declaration are optional. default return value = last value in code block -| `def x {print("hello world")}` | method without "=" means the method has no return type/return type is void (this is a lie to keep things simple, more later) | +| `def x = "hello world"`|return keyword and return type declaration are optional, but if a method contains return, the return type *must* be specified explicitly. default return value = last value in code block. | `def x = {def y = 7;y}` | nested declarations are possible| | `class Foo`| class declaration - nested declaration also possible| | `class Foo(var x:String, val y:Int)`| class declaration with 2 public fields, one mutable, one immutable. constructor is automatically generated. only new Foo("1",2) is possible| | `class Foo {var x = 5;val y = 6}`|class like above, but with default constructor, only new Foo() is possible| | `class Foo {def x = 5}`|class with default constructor and one method| +| `val x = {class y(val z: String); new y("hello").z}`
Bad`val foo = new y("does not work outside the block above")`| everything can be nested in anything, but everything can only be accessed in its scope| +|

Declaring functions

| | +| `(i:Int) => i+1`|creates a function.| +| `var func = (i:Int) => i+1`|creates a function and stores it in a variable| +| `func(5)`|executing the function above| +| `def func = (i:Int) => i+1`|creates a function each time the method is called and returns that function, not i+1| +| `lazy val x = expensiveOperation()`|the expensive operation is executed once as soon as the value of x is needed, not before| +|

Return types and type inference

| | +| `val x = "hello"`|the compiler always picks the most specific type possible, in this case java.lang.String| +| `val x:Serializable = "hello"`|you can always specify a more general one| +| `def x {print("hello world")}` | method without "=" means the method has no return type/return type is void (this is a lie) | +| `def x:Unit = {...}`
`def x() {...}`|leaving out the "=" at a method declaration is the same as specifying "Unit"| +| `val blocks = {{{{5}}}}`|every block has a return type that is passed back to the next outer block| +| `val block = if (a) foo else bar`|almost everything is an expression and thus, has a return type. this includes if-else-structures| +|`def x = if (System.currentTimeMillis() % 2 == 0) Integer.valueOf(1) else java.lang.Double.valueOf(2)`|here, the compiler picks the most specific supertype of both Integer and Double which is java.lang.Number (this is a lie)| +|`def x(i:Int):Int = if (i==0) 1 else i*x(i-1)`|recursive methods need an explicit return type. fail.| +|`val func:(Int) => String = (i:Int) => i.toString`|just so you know the syntax of a type of a function :)| +|`def takesFunction(f:(Int) => String) = f(5)`| method that takes the function above as a parameter and calls it. compiler figures out the return type "string" for you.| +|`def method(i:Int) = t.toString;val func = method _`|appending an "_" converts any method into a function| +|`takesFunction(method)`|is also possible, the compiler does the conversion for you in obvious cases| +|

Scala Collections

| | +|`Set(1,2,3), Buffer(1,2,3), ArrayBuffer(1,2,3), ListBuffer(1,2,3), List(1,2,3), Array(1,2,3),Vector(1,2,3), Map(1 -> "a", 2 -> "b")`|simple collection creations. scala has mutable and immutable collections.| +|`mutableColl += elem`|add element to a collection| +|`mutableColl -= elem`|remove element| +|`mutableColl ++= elems`|add elements| +|`mutableColl --= elems`|remove elements| +|`elem +=: mutableColl`|adds element at the beginning of a collection| +|`mutableColl :+= elem`|adds element at the end of a collection| +|`mutableColl(0)`|read access by index| +|`mutableColl(0) = 1`|write access by index| +|`coll + elem`|create new collection that has all elements of coll and elem| +|`coll - elem`|create new collection that has all elements of coll except elem| +|`coll ++ elems`|create new collection that has all elements of coll and elems| +|`coll -- elems`|create new collection that has all elements of coll except elems| +|`coll :+ elem`|create new collection that has all elements of coll and elem at the end| +|`elem +: coll`|create new collection that has all elements of coll and elem at the beginning| +|`immutableColl += elem`
`immutableColl -= elem`
`immutableColl ++= elems`
`immutableColl --= elems`
`elem +=: immutableColl`
`immutableColl :+= elem|same as the operations without "=", but works only if "immutableColl is a var, not a val. the created collection is assigned to "immutableColl".| +|`def isEven(i:Int= if (i%2==0) true else false`
`val evenNumbers:List[Int] = List(1,2,3,4).filter(isEven)`|scala collections are a major epic win. they have ~100 methods which operate on the data of a collection and there is *absolutely nothing* you cannot do with them.| +|`val evenNumbers:List[Int] = List(1,2,3,4).filter((i:Int)=> i%2==0)`|same as above, just shorter| +|`val evenNumbers = List(1,2,3,4).filter(i => i%2==0)`|same as above, just shorter. you can skip the () if there is only one parameter| +|`val evenNumbers = List(1,2,3,4).filter(_ % 2 == 0)`|same as above, just shorter. you can skip part before "=>" if you use a parameter only once and replace the parameter usage by "_"| |

functions

| | | Good `def f(x: Int) = { x*x }`
Bad `def f(x: Int) { x*x }` | define function
hidden error: without = it's a Unit-returning procedure; causes havoc | | Good `def f(x: Any) = println(x)`
Bad `def f(x) = println(x)` | define function
syntax error: need types for every arg. | @@ -85,7 +125,7 @@ about: Thanks to Brendan O'Connor, this cheat | `object O extends D { ... }` | define a singleton. (module-like) | | `trait T { ... }`
`class C extends T { ... }`
`class C extends D with T { ... }` | traits.
interfaces-with-implementation. no constructor params. [mixin-able]({{ site.baseurl }}/tutorials/tour/mixin-class-composition.html). | `trait T1; trait T2`
`class C extends T1 with T2`
`class C extends D with T1 with T2` | multiple traits. | -| `class C extends D { override def f = ...}` | must declare method overrides. | +| `class C extends D { override def f = ...}` | must declare method overrides. | | `new java.io.File("f")` | create object. | | Bad `new List[Int]`
Good `List(1,2,3)` | type error: abstract type
instead, convention: callable factory shadowing the type | | `classOf[String]` | class literal. | From e6ed5172421e09328ee13919d7807c687ba64006 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Thu, 22 Dec 2011 20:29:42 +0100 Subject: [PATCH 03/36] Update cheatsheets/index.md --- cheatsheets/index.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 7fb8a57c89..e899ffcf2b 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -2,7 +2,7 @@ layout: cheatsheet title: Scalacheat by: (initial version: Brendan O'Connor) HamsterofDea -about: Thanks to Brendan O'Connor, this cheatsheet aims to be a quick reference of Scala syntactic constructions. Licensed by Brendan O'Connor under a CC-BY-SA 3.0 license. +about: Thanks to Brendan O'Connor, this cheatsheet aims to be a quick reference of Scala syntactic constructions. Licensed by Brendan O'Connor under a CC-BY-SA 3.0 license. Pimped by HamsterofDeath who doesn't care about the license and just wants to help scala to spread :) --- ###### Contributed by {{ page.by }} @@ -25,13 +25,17 @@ about: Thanks to Brendan O'Connor, this cheat | `class Foo(var x:String, val y:Int)`| class declaration with 2 public fields, one mutable, one immutable. constructor is automatically generated. only new Foo("1",2) is possible| | `class Foo {var x = 5;val y = 6}`|class like above, but with default constructor, only new Foo() is possible| | `class Foo {def x = 5}`|class with default constructor and one method| +|

Not so basic declarations

| | | `val x = {class y(val z: String); new y("hello").z}`
Bad`val foo = new y("does not work outside the block above")`| everything can be nested in anything, but everything can only be accessed in its scope| -|

Declaring functions

| | +| `lazy val x = expensiveOperation()`|the expensive operation is executed once as soon as the value of x is needed, not before| +| `def method(a:String = "hello", b:String = "world") = a+" "+b`|method will default values| +| `method("goodbye")`|call to method above, unspecificed parameters will get default values. returns "goodbye world"| +| `method(b = "friend")`|call to method above, explicitly passes a string to b. a defaults to "hello". returns "hello friend"| +|

Declaring functions

| | | `(i:Int) => i+1`|creates a function.| | `var func = (i:Int) => i+1`|creates a function and stores it in a variable| | `func(5)`|executing the function above| | `def func = (i:Int) => i+1`|creates a function each time the method is called and returns that function, not i+1| -| `lazy val x = expensiveOperation()`|the expensive operation is executed once as soon as the value of x is needed, not before| |

Return types and type inference

| | | `val x = "hello"`|the compiler always picks the most specific type possible, in this case java.lang.String| | `val x:Serializable = "hello"`|you can always specify a more general one| @@ -46,7 +50,7 @@ about: Thanks to Brendan O'Connor, this cheat |`def method(i:Int) = t.toString;val func = method _`|appending an "_" converts any method into a function| |`takesFunction(method)`|is also possible, the compiler does the conversion for you in obvious cases| |

Scala Collections

| | -|`Set(1,2,3), Buffer(1,2,3), ArrayBuffer(1,2,3), ListBuffer(1,2,3), List(1,2,3), Array(1,2,3),Vector(1,2,3), Map(1 -> "a", 2 -> "b")`|simple collection creations. scala has mutable and immutable collections.| +|`1 to 3, Set(1,2,3), Buffer(1,2,3), ArrayBuffer(1,2,3), ListBuffer(1,2,3), List(1,2,3), Array(1,2,3),Vector(1,2,3), Map(1 -> "a", 2 -> "b")`|simple collection creations. scala has mutable and immutable collections.| |`mutableColl += elem`|add element to a collection| |`mutableColl -= elem`|remove element| |`mutableColl ++= elems`|add elements| @@ -62,6 +66,7 @@ about: Thanks to Brendan O'Connor, this cheat |`coll :+ elem`|create new collection that has all elements of coll and elem at the end| |`elem +: coll`|create new collection that has all elements of coll and elem at the beginning| |`immutableColl += elem`
`immutableColl -= elem`
`immutableColl ++= elems`
`immutableColl --= elems`
`elem +=: immutableColl`
`immutableColl :+= elem|same as the operations without "=", but works only if "immutableColl is a var, not a val. the created collection is assigned to "immutableColl".| +|method name rules:
"+" means add
"-" means remove
"++" or "--" mean many elements, not just one
"=" means modifiy mutable collection or assign new immutable collection to var
":" goes on the side of the collection
if method contains ":" it is and ordered add, either at the beginning or the end of the collection| |`def isEven(i:Int= if (i%2==0) true else false`
`val evenNumbers:List[Int] = List(1,2,3,4).filter(isEven)`|scala collections are a major epic win. they have ~100 methods which operate on the data of a collection and there is *absolutely nothing* you cannot do with them.| |`val evenNumbers:List[Int] = List(1,2,3,4).filter((i:Int)=> i%2==0)`|same as above, just shorter| |`val evenNumbers = List(1,2,3,4).filter(i => i%2==0)`|same as above, just shorter. you can skip the () if there is only one parameter| From 7e31941789e74902a2e0dcd25f312a64d47f5a39 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Thu, 22 Dec 2011 21:19:22 +0100 Subject: [PATCH 04/36] Update cheatsheets/index.md --- cheatsheets/index.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index e899ffcf2b..33dff8ec44 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -51,26 +51,34 @@ about: Thanks to Brendan O'Connor, this cheat |`takesFunction(method)`|is also possible, the compiler does the conversion for you in obvious cases| |

Scala Collections

| | |`1 to 3, Set(1,2,3), Buffer(1,2,3), ArrayBuffer(1,2,3), ListBuffer(1,2,3), List(1,2,3), Array(1,2,3),Vector(1,2,3), Map(1 -> "a", 2 -> "b")`|simple collection creations. scala has mutable and immutable collections.| +|scary but concise operators, need some practice to get them right:
+,++,++=,++:=-,--,--=,:+,:++,:=+,+=:,:++=,++:=, ++=:|method name rules:
"+" means add
"-" means remove
"++" or "--" mean add/remove many elements, not just one
"=" means modify mutable collection xor assign new immutable collection to var. in the reassign case, "=" is appended to the actual method name, just like "int i=0;i+=1" in java.
":" goes on the side of the target collection and is always the first or last character of a method name. if a method end with :=, the method actually ends with : and = means it's a reassignment
if method contains ":" it is an add to an ordered collection, either at the beginning or the end of the collection| |`mutableColl += elem`|add element to a collection| |`mutableColl -= elem`|remove element| |`mutableColl ++= elems`|add elements| |`mutableColl --= elems`|remove elements| |`elem +=: mutableColl`|adds element at the beginning of a collection| |`mutableColl :+= elem`|adds element at the end of a collection| -|`mutableColl(0)`|read access by index| -|`mutableColl(0) = 1`|write access by index| -|`coll + elem`|create new collection that has all elements of coll and elem| +|`mutableColl(0) = 1`|write access by index on mutable collections| +|`coll(0)`|read access by index| |`coll - elem`|create new collection that has all elements of coll except elem| |`coll ++ elems`|create new collection that has all elements of coll and elems| |`coll -- elems`|create new collection that has all elements of coll except elems| |`coll :+ elem`|create new collection that has all elements of coll and elem at the end| |`elem +: coll`|create new collection that has all elements of coll and elem at the beginning| -|`immutableColl += elem`
`immutableColl -= elem`
`immutableColl ++= elems`
`immutableColl --= elems`
`elem +=: immutableColl`
`immutableColl :+= elem|same as the operations without "=", but works only if "immutableColl is a var, not a val. the created collection is assigned to "immutableColl".| -|method name rules:
"+" means add
"-" means remove
"++" or "--" mean many elements, not just one
"=" means modifiy mutable collection or assign new immutable collection to var
":" goes on the side of the collection
if method contains ":" it is and ordered add, either at the beginning or the end of the collection| +|`immutableColl += elem`
`immutableColl -= elem`
`immutableColl ++= elems`
`immutableColl --= elems`
`elem +=: immutableColl`
`immutableColl :+= elem`|same as the operations without "=", but works only if "immutableColl is a var, not a val. the created collection is assigned to "immutableColl".| +|prepend, append, union, remove, insertAll... for every cryptic add/remove operation, there is also a well named one that is totally obvious and easy to understand :)| |`def isEven(i:Int= if (i%2==0) true else false`
`val evenNumbers:List[Int] = List(1,2,3,4).filter(isEven)`|scala collections are a major epic win. they have ~100 methods which operate on the data of a collection and there is *absolutely nothing* you cannot do with them.| |`val evenNumbers:List[Int] = List(1,2,3,4).filter((i:Int)=> i%2==0)`|same as above, just shorter| |`val evenNumbers = List(1,2,3,4).filter(i => i%2==0)`|same as above, just shorter. you can skip the () if there is only one parameter| |`val evenNumbers = List(1,2,3,4).filter(_ % 2 == 0)`|same as above, just shorter. you can skip part before "=>" if you use a parameter only once and replace the parameter usage by "_"| +|`val doubleNumbers = List(1,2,3,4).map(_ * 2)`|for the non functional programmers: map means convert| +|`listOfManyPersons.filter(_.hasChildren).map(_.getChildren)`|collection operations can be chained. you can do anything without loops and conditions which makes your code very easy to read| +|`List(1,2,3,4,5).foreach(println)`|do something with every element| +|`List(1,2,3,4,5).par.filter(_ % 2 == 0)`|is executed in parallel just like that| +|`List(1).toSet.toArray.toBuffer.iterator.toStream.toSeq`|conversions are easy| +|`Iterator.continually(randomNumber)`|collections and iterators can also be created from functions and methods| +|`Iterator.continually(randomNumber).take(100).max`|highest of 100 random numbers. again: there are methods for everything you can possibly imagine. many are taking functions so the flexibility is epic :)| +|`Iterator.continually(randomThings).take(100).maxBy(comparisonFunction)`|highest of 100 random things. as above, but can be used for anything.| |

functions

| | | Good `def f(x: Int) = { x*x }`
Bad `def f(x: Int) { x*x }` | define function
hidden error: without = it's a Unit-returning procedure; causes havoc | | Good `def f(x: Any) = println(x)`
Bad `def f(x) = println(x)` | define function
syntax error: need types for every arg. | From 435c2ee0dc835b10d627927fffdf3e14401064a9 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Thu, 22 Dec 2011 21:21:47 +0100 Subject: [PATCH 05/36] Update cheatsheets/index.md --- cheatsheets/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 33dff8ec44..ce5067d749 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -51,6 +51,7 @@ about: Thanks to Brendan O'Connor, this cheat |`takesFunction(method)`|is also possible, the compiler does the conversion for you in obvious cases| |

Scala Collections

| | |`1 to 3, Set(1,2,3), Buffer(1,2,3), ArrayBuffer(1,2,3), ListBuffer(1,2,3), List(1,2,3), Array(1,2,3),Vector(1,2,3), Map(1 -> "a", 2 -> "b")`|simple collection creations. scala has mutable and immutable collections.| +|prepend, append, union, remove, insertAll... for every cryptic add/remove operation, there is also a well named one that is totally obvious and easy to understand :)| |scary but concise operators, need some practice to get them right:
+,++,++=,++:=-,--,--=,:+,:++,:=+,+=:,:++=,++:=, ++=:|method name rules:
"+" means add
"-" means remove
"++" or "--" mean add/remove many elements, not just one
"=" means modify mutable collection xor assign new immutable collection to var. in the reassign case, "=" is appended to the actual method name, just like "int i=0;i+=1" in java.
":" goes on the side of the target collection and is always the first or last character of a method name. if a method end with :=, the method actually ends with : and = means it's a reassignment
if method contains ":" it is an add to an ordered collection, either at the beginning or the end of the collection| |`mutableColl += elem`|add element to a collection| |`mutableColl -= elem`|remove element| @@ -66,7 +67,6 @@ about: Thanks to Brendan O'Connor, this cheat |`coll :+ elem`|create new collection that has all elements of coll and elem at the end| |`elem +: coll`|create new collection that has all elements of coll and elem at the beginning| |`immutableColl += elem`
`immutableColl -= elem`
`immutableColl ++= elems`
`immutableColl --= elems`
`elem +=: immutableColl`
`immutableColl :+= elem`|same as the operations without "=", but works only if "immutableColl is a var, not a val. the created collection is assigned to "immutableColl".| -|prepend, append, union, remove, insertAll... for every cryptic add/remove operation, there is also a well named one that is totally obvious and easy to understand :)| |`def isEven(i:Int= if (i%2==0) true else false`
`val evenNumbers:List[Int] = List(1,2,3,4).filter(isEven)`|scala collections are a major epic win. they have ~100 methods which operate on the data of a collection and there is *absolutely nothing* you cannot do with them.| |`val evenNumbers:List[Int] = List(1,2,3,4).filter((i:Int)=> i%2==0)`|same as above, just shorter| |`val evenNumbers = List(1,2,3,4).filter(i => i%2==0)`|same as above, just shorter. you can skip the () if there is only one parameter| From b65e5a8292f28a27ccd6e473489bb5ce132f5f78 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Thu, 22 Dec 2011 21:23:00 +0100 Subject: [PATCH 06/36] Update cheatsheets/index.md --- cheatsheets/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index ce5067d749..016351379f 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -51,7 +51,7 @@ about: Thanks to Brendan O'Connor, this cheat |`takesFunction(method)`|is also possible, the compiler does the conversion for you in obvious cases| |

Scala Collections

| | |`1 to 3, Set(1,2,3), Buffer(1,2,3), ArrayBuffer(1,2,3), ListBuffer(1,2,3), List(1,2,3), Array(1,2,3),Vector(1,2,3), Map(1 -> "a", 2 -> "b")`|simple collection creations. scala has mutable and immutable collections.| -|prepend, append, union, remove, insertAll... for every cryptic add/remove operation, there is also a well named one that is totally obvious and easy to understand :)| +|prepend, append, union, remove, insertAll... |the usual methods every collection framework offers| |scary but concise operators, need some practice to get them right:
+,++,++=,++:=-,--,--=,:+,:++,:=+,+=:,:++=,++:=, ++=:|method name rules:
"+" means add
"-" means remove
"++" or "--" mean add/remove many elements, not just one
"=" means modify mutable collection xor assign new immutable collection to var. in the reassign case, "=" is appended to the actual method name, just like "int i=0;i+=1" in java.
":" goes on the side of the target collection and is always the first or last character of a method name. if a method end with :=, the method actually ends with : and = means it's a reassignment
if method contains ":" it is an add to an ordered collection, either at the beginning or the end of the collection| |`mutableColl += elem`|add element to a collection| |`mutableColl -= elem`|remove element| From 64e3a1ac396517876d5691eb3be2963a9ca828e8 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Thu, 22 Dec 2011 21:31:45 +0100 Subject: [PATCH 07/36] Update cheatsheets/index.md --- cheatsheets/index.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 016351379f..e28b759e22 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -36,6 +36,11 @@ about: Thanks to Brendan O'Connor, this cheat | `var func = (i:Int) => i+1`|creates a function and stores it in a variable| | `func(5)`|executing the function above| | `def func = (i:Int) => i+1`|creates a function each time the method is called and returns that function, not i+1| +|`val func:(Int) => String = (i:Int) => i.toString`|just so you know the syntax of a type of a function :)| +|`def takesFunction(f:(Int) => String) = f(5)`| method that takes the function above as a parameter and calls it. compiler figures out the return type "string" for you.| +|`def method(i:Int) = t.toString;val func = method _`|appending an "_" converts any method into a function| +|`takesFunction(method)`|is also possible, the compiler does the conversion for you in obvious cases| +|`def method(param: => String)`|"=>" means that when the method is called, the parameter is wrapped in a function which is executed when accessed. the string is evaluated every time when needed (see Iterator.continually), but not before. the value is not cached, but you can pass a lazy val to make it cached.| |

Return types and type inference

| | | `val x = "hello"`|the compiler always picks the most specific type possible, in this case java.lang.String| | `val x:Serializable = "hello"`|you can always specify a more general one| @@ -45,10 +50,6 @@ about: Thanks to Brendan O'Connor, this cheat | `val block = if (a) foo else bar`|almost everything is an expression and thus, has a return type. this includes if-else-structures| |`def x = if (System.currentTimeMillis() % 2 == 0) Integer.valueOf(1) else java.lang.Double.valueOf(2)`|here, the compiler picks the most specific supertype of both Integer and Double which is java.lang.Number (this is a lie)| |`def x(i:Int):Int = if (i==0) 1 else i*x(i-1)`|recursive methods need an explicit return type. fail.| -|`val func:(Int) => String = (i:Int) => i.toString`|just so you know the syntax of a type of a function :)| -|`def takesFunction(f:(Int) => String) = f(5)`| method that takes the function above as a parameter and calls it. compiler figures out the return type "string" for you.| -|`def method(i:Int) = t.toString;val func = method _`|appending an "_" converts any method into a function| -|`takesFunction(method)`|is also possible, the compiler does the conversion for you in obvious cases| |

Scala Collections

| | |`1 to 3, Set(1,2,3), Buffer(1,2,3), ArrayBuffer(1,2,3), ListBuffer(1,2,3), List(1,2,3), Array(1,2,3),Vector(1,2,3), Map(1 -> "a", 2 -> "b")`|simple collection creations. scala has mutable and immutable collections.| |prepend, append, union, remove, insertAll... |the usual methods every collection framework offers| From e0a9e64554aef6cad9261d436aa2eab4a1634b70 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Thu, 22 Dec 2011 21:33:22 +0100 Subject: [PATCH 08/36] Update cheatsheets/index.md --- cheatsheets/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index e28b759e22..3e4aa7ac12 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -31,6 +31,7 @@ about: Thanks to Brendan O'Connor, this cheat | `def method(a:String = "hello", b:String = "world") = a+" "+b`|method will default values| | `method("goodbye")`|call to method above, unspecificed parameters will get default values. returns "goodbye world"| | `method(b = "friend")`|call to method above, explicitly passes a string to b. a defaults to "hello". returns "hello friend"| +|`def method(param: => String)`|"=>" means that when the method is called, the parameter is wrapped in a function which is executed when accessed. the string is evaluated every time when needed (see Iterator.continually), but not before. the value is not cached, but you can pass a lazy val to make it cached.| |

Declaring functions

| | | `(i:Int) => i+1`|creates a function.| | `var func = (i:Int) => i+1`|creates a function and stores it in a variable| @@ -40,7 +41,6 @@ about: Thanks to Brendan O'Connor, this cheat |`def takesFunction(f:(Int) => String) = f(5)`| method that takes the function above as a parameter and calls it. compiler figures out the return type "string" for you.| |`def method(i:Int) = t.toString;val func = method _`|appending an "_" converts any method into a function| |`takesFunction(method)`|is also possible, the compiler does the conversion for you in obvious cases| -|`def method(param: => String)`|"=>" means that when the method is called, the parameter is wrapped in a function which is executed when accessed. the string is evaluated every time when needed (see Iterator.continually), but not before. the value is not cached, but you can pass a lazy val to make it cached.| |

Return types and type inference

| | | `val x = "hello"`|the compiler always picks the most specific type possible, in this case java.lang.String| | `val x:Serializable = "hello"`|you can always specify a more general one| From 62c807908bd6feb5f86707972acdebd6301df906 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Fri, 23 Dec 2011 19:40:24 +0100 Subject: [PATCH 09/36] Update cheatsheets/index.md --- cheatsheets/index.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 3e4aa7ac12..72e5c6e6a8 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -32,6 +32,8 @@ about: Thanks to Brendan O'Connor, this cheat | `method("goodbye")`|call to method above, unspecificed parameters will get default values. returns "goodbye world"| | `method(b = "friend")`|call to method above, explicitly passes a string to b. a defaults to "hello". returns "hello friend"| |`def method(param: => String)`|"=>" means that when the method is called, the parameter is wrapped in a function which is executed when accessed. the string is evaluated every time when needed (see Iterator.continually), but not before. the value is not cached, but you can pass a lazy val to make it cached.| +|`def method(s:String)(i:Int)`|method with multiple parameter lists| +|`val intermediate = method("hello")`
`intermediate(5)`|why? because you can apply one parameter list at once and the next ones later and pass "the incomplete call" around. in java, you would use a builder for this.| |

Declaring functions

| | | `(i:Int) => i+1`|creates a function.| | `var func = (i:Int) => i+1`|creates a function and stores it in a variable| @@ -41,6 +43,7 @@ about: Thanks to Brendan O'Connor, this cheat |`def takesFunction(f:(Int) => String) = f(5)`| method that takes the function above as a parameter and calls it. compiler figures out the return type "string" for you.| |`def method(i:Int) = t.toString;val func = method _`|appending an "_" converts any method into a function| |`takesFunction(method)`|is also possible, the compiler does the conversion for you in obvious cases| +|`def method(s:String)(s2:String) = s+" "+s2)`
`val intermediate:(String)=>String = method("hello")`
`intermediate("world")`|parameter lists revisited: the intermediate, "incomplete method calls" are functions. the result of the last call is "hello world"| |

Return types and type inference

| | | `val x = "hello"`|the compiler always picks the most specific type possible, in this case java.lang.String| | `val x:Serializable = "hello"`|you can always specify a more general one| @@ -52,8 +55,8 @@ about: Thanks to Brendan O'Connor, this cheat |`def x(i:Int):Int = if (i==0) 1 else i*x(i-1)`|recursive methods need an explicit return type. fail.| |

Scala Collections

| | |`1 to 3, Set(1,2,3), Buffer(1,2,3), ArrayBuffer(1,2,3), ListBuffer(1,2,3), List(1,2,3), Array(1,2,3),Vector(1,2,3), Map(1 -> "a", 2 -> "b")`|simple collection creations. scala has mutable and immutable collections.| -|prepend, append, union, remove, insertAll... |the usual methods every collection framework offers| -|scary but concise operators, need some practice to get them right:
+,++,++=,++:=-,--,--=,:+,:++,:=+,+=:,:++=,++:=, ++=:|method name rules:
"+" means add
"-" means remove
"++" or "--" mean add/remove many elements, not just one
"=" means modify mutable collection xor assign new immutable collection to var. in the reassign case, "=" is appended to the actual method name, just like "int i=0;i+=1" in java.
":" goes on the side of the target collection and is always the first or last character of a method name. if a method end with :=, the method actually ends with : and = means it's a reassignment
if method contains ":" it is an add to an ordered collection, either at the beginning or the end of the collection| +|prepend, append, union, remove, insertAll... |the usual methods every collection framework offers are present in scala as well| +|if you like to use operators instead, there are some scary but concise ones. you'll need some practice to get them right:
+,++,++=,++:=-,--,--=,:+,:++,:=+,+=:,:++=,++:=, ++=:|method name rules:
"+" means add
"-" means remove
"++" or "--" mean add/remove many elements, not just one
"=" means modify mutable collection xor assign new immutable collection to var. in the reassign case, "=" is appended to the actual method name, just like "int i=0;i+=1" in java.
":" goes on the side of the target collection and is always the first or last character of a method name. if a method end with :=, the method actually ends with : and = means it's a reassignment
if method contains ":" it is an add to an ordered collection, either at the beginning or the end of the collection| |`mutableColl += elem`|add element to a collection| |`mutableColl -= elem`|remove element| |`mutableColl ++= elems`|add elements| @@ -70,7 +73,7 @@ about: Thanks to Brendan O'Connor, this cheat |`immutableColl += elem`
`immutableColl -= elem`
`immutableColl ++= elems`
`immutableColl --= elems`
`elem +=: immutableColl`
`immutableColl :+= elem`|same as the operations without "=", but works only if "immutableColl is a var, not a val. the created collection is assigned to "immutableColl".| |`def isEven(i:Int= if (i%2==0) true else false`
`val evenNumbers:List[Int] = List(1,2,3,4).filter(isEven)`|scala collections are a major epic win. they have ~100 methods which operate on the data of a collection and there is *absolutely nothing* you cannot do with them.| |`val evenNumbers:List[Int] = List(1,2,3,4).filter((i:Int)=> i%2==0)`|same as above, just shorter| -|`val evenNumbers = List(1,2,3,4).filter(i => i%2==0)`|same as above, just shorter. you can skip the () if there is only one parameter| +|`val evenNumbers = List(1,2,3,4).filter(i => i%2==0)`|same as above, just shorter. you can skip the () if there is only one parameter. you can also skip the type of the parameter(s) because it can be inferred from the usage| |`val evenNumbers = List(1,2,3,4).filter(_ % 2 == 0)`|same as above, just shorter. you can skip part before "=>" if you use a parameter only once and replace the parameter usage by "_"| |`val doubleNumbers = List(1,2,3,4).map(_ * 2)`|for the non functional programmers: map means convert| |`listOfManyPersons.filter(_.hasChildren).map(_.getChildren)`|collection operations can be chained. you can do anything without loops and conditions which makes your code very easy to read| @@ -80,6 +83,15 @@ about: Thanks to Brendan O'Connor, this cheat |`Iterator.continually(randomNumber)`|collections and iterators can also be created from functions and methods| |`Iterator.continually(randomNumber).take(100).max`|highest of 100 random numbers. again: there are methods for everything you can possibly imagine. many are taking functions so the flexibility is epic :)| |`Iterator.continually(randomThings).take(100).maxBy(comparisonFunction)`|highest of 100 random things. as above, but can be used for anything.| +|

The power of collections and functions

| +| using closures, it is possible to avoid repetitions of boilerplate - instead you pass a function to a method that hides the boilerplate. apart from filter and map, two other epic wins are reduce and fold.| +|`List(1,2,3,4,5).reduce((i,i2) => i+i2)`|result: ((((1+2)+3)+4)+5). in human speech, it takes 2 elements and merges them into one. imagine the collection turning from 1,2,3,4,5 into 3,3,4,5. then repeat:6,4,5 -> 10,5 -> 15| +|`List(1,2,3,4,5).reduce(_ + _)`|same as above, using "_" for the first and second parameter| +|`List(1,2,3,4,5).fold(0)((sumSoFar,element) => sumSoFar+element)`|same as above, but fold uses an explicit start value| +|`List(1,2,3,4,5).fold(0)(_ + _)`|same as the fold above, just shorter| +|`"comma separated numbers: " + List(1, 2, 3, 4, 5).fold("0")(_ + ", " + _)`|finally, you won't have to fiddle around with the last "," anymore!| +|in java this would all look like:
`Acc acc = ?;`
` for (T t: coll) {if (acc==null) {acc = t;} else {acc = doStuff(acc,t);}}`|this is boilerplate code you can avoid *every single time!*. write only what (doStuff) should happen, not "what and how" (boilerplate code + doStuff).| +|where else could you save boilerplate? think about it!
try-catch-finally |

functions

| | | Good `def f(x: Int) = { x*x }`
Bad `def f(x: Int) { x*x }` | define function
hidden error: without = it's a Unit-returning procedure; causes havoc | | Good `def f(x: Any) = println(x)`
Bad `def f(x) = println(x)` | define function
syntax error: need types for every arg. | From 18a86ac93a08ea398970f795da3d310406ec7dc8 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Fri, 23 Dec 2011 21:26:07 +0100 Subject: [PATCH 10/36] Update cheatsheets/index.md --- cheatsheets/index.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 72e5c6e6a8..4495b84ec3 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -92,6 +92,24 @@ about: Thanks to Brendan O'Connor, this cheat |`"comma separated numbers: " + List(1, 2, 3, 4, 5).fold("0")(_ + ", " + _)`|finally, you won't have to fiddle around with the last "," anymore!| |in java this would all look like:
`Acc acc = ?;`
` for (T t: coll) {if (acc==null) {acc = t;} else {acc = doStuff(acc,t);}}`|this is boilerplate code you can avoid *every single time!*. write only what (doStuff) should happen, not "what and how" (boilerplate code + doStuff).| |where else could you save boilerplate? think about it!
try-catch-finally +|

Generics

| +| `def foo[BAR](bar:BAR):BAR = bar`|simple type parameter, can be anything| +| `def foo[BAR <: java.lang.Number](bar: BAR) = bar.doubleValue() + 5`|upper bound, BAR must be a java.lang.Number or a subclass of it| +| `def foo[BAR >: java.lang.Number](bar: BAR) = bar`|lower bound, type must be java.lang.Number or a superclass of it, but not a subclass of java.lang.Number. note that you can still pass a double, but the type parameter and therefore the return type will be java.lang.Number. the bound applies to the type parameter itself, not the type of the parameter that is passed to the function| +|`val strings:List[String] = List("hello","generics")`
`val objects:List[java.lang.Object] = strings`|in scala, type parameters of collections are covariant. this means they "inherit" the inhertance relations of their type parameters. in java, have to do an ugly cast:
`List ints = new ArrayList()`;
`List numbers = ((List`val func:(String) => java.lang.Number`|the return type is +, the parameter is -, so the function can be replaced by one declared like
`val func2:(java.lang.Object) => java.lang.Integer`
Think about it. a function that can take any object can also take a string. a function that returns an integer automatically returns a number, so the second one can replace the first one in every possible case.| +|`def foo[A, B[A]] (nested: B[A])`|nested type parameters are possible. nested must be of a type that has a type parameter. for example, you could pass a List[Int]| +|`def foo[A, B, C <: B[A]](nested: C))`|same as above, using an alias for B[A] named C| +|`def foo[C <: Traversable[_]] (nested: C) = nested.head`|if there is no need to access the inner type explicitly, it can be replaced by an _. in this example, the compiler infers that the return type must be whatever _ is, so the actual return type depends on the call site.| +|`foo(List(5))`|call to the method above, returns an Int| +|`def foo[A: Manifest] {val classAtRuntime = manifest[A].erasure; println(classAtRuntime);}`|Adding ":Manifest" will make the compiler add magic so you can get the type parameter at runtime via `manifest[TYPEPARAM]`| +|`foo[String]`|call to method above, prints "class java.lang.String"| + +not yet pimped part of the cheat sheet: + |

functions

| | | Good `def f(x: Int) = { x*x }`
Bad `def f(x: Int) { x*x }` | define function
hidden error: without = it's a Unit-returning procedure; causes havoc | | Good `def f(x: Any) = println(x)`
Bad `def f(x) = println(x)` | define function
syntax error: need types for every arg. | From 91699eda55d3c2af5e5676be56318da24a2e29b2 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Sat, 24 Dec 2011 10:51:13 +0100 Subject: [PATCH 11/36] Update cheatsheets/index.md --- cheatsheets/index.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 4495b84ec3..88e3e80800 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -43,7 +43,7 @@ about: Thanks to Brendan O'Connor, this cheat |`def takesFunction(f:(Int) => String) = f(5)`| method that takes the function above as a parameter and calls it. compiler figures out the return type "string" for you.| |`def method(i:Int) = t.toString;val func = method _`|appending an "_" converts any method into a function| |`takesFunction(method)`|is also possible, the compiler does the conversion for you in obvious cases| -|`def method(s:String)(s2:String) = s+" "+s2)`
`val intermediate:(String)=>String = method("hello")`
`intermediate("world")`|parameter lists revisited: the intermediate, "incomplete method calls" are functions. the result of the last call is "hello world"| +|`def method(s:String)(s2:String) = s+" "+s2`
`val intermediate:(String)=>String = method("hello")`
`intermediate("world")`|parameter lists revisited: the intermediate, "incomplete method calls" are functions. the result of the last call is "hello world"| |

Return types and type inference

| | | `val x = "hello"`|the compiler always picks the most specific type possible, in this case java.lang.String| | `val x:Serializable = "hello"`|you can always specify a more general one| @@ -56,7 +56,7 @@ about: Thanks to Brendan O'Connor, this cheat |

Scala Collections

| | |`1 to 3, Set(1,2,3), Buffer(1,2,3), ArrayBuffer(1,2,3), ListBuffer(1,2,3), List(1,2,3), Array(1,2,3),Vector(1,2,3), Map(1 -> "a", 2 -> "b")`|simple collection creations. scala has mutable and immutable collections.| |prepend, append, union, remove, insertAll... |the usual methods every collection framework offers are present in scala as well| -|if you like to use operators instead, there are some scary but concise ones. you'll need some practice to get them right:
+,++,++=,++:=-,--,--=,:+,:++,:=+,+=:,:++=,++:=, ++=:|method name rules:
"+" means add
"-" means remove
"++" or "--" mean add/remove many elements, not just one
"=" means modify mutable collection xor assign new immutable collection to var. in the reassign case, "=" is appended to the actual method name, just like "int i=0;i+=1" in java.
":" goes on the side of the target collection and is always the first or last character of a method name. if a method end with :=, the method actually ends with : and = means it's a reassignment
if method contains ":" it is an add to an ordered collection, either at the beginning or the end of the collection| +|if you like to use operators instead, there are some scary but concise ones. you'll need some practice to get them right:
+,++,++=,++:=-,--,--=,:+,:++,:=+,+=:,:++=,++:=, ++=:|method name rules:
"+" means add
"-" means remove
"++" or "--" mean add/remove many elements, not just one
"=" means modify mutable collection or (never both) assign new immutable collection to var. in the reassign case, "=" is appended to the actual method name, just like "int i=0;i+=1" in java.
":" goes on the side of the target collection and is always the first or last character of a method name. if a method end with :=, the method actually ends with : and = means it's a reassignment
if method contains ":" it is an add to an ordered collection, either at the beginning or the end of the collection| |`mutableColl += elem`|add element to a collection| |`mutableColl -= elem`|remove element| |`mutableColl ++= elems`|add elements| @@ -72,6 +72,7 @@ about: Thanks to Brendan O'Connor, this cheat |`elem +: coll`|create new collection that has all elements of coll and elem at the beginning| |`immutableColl += elem`
`immutableColl -= elem`
`immutableColl ++= elems`
`immutableColl --= elems`
`elem +=: immutableColl`
`immutableColl :+= elem`|same as the operations without "=", but works only if "immutableColl is a var, not a val. the created collection is assigned to "immutableColl".| |`def isEven(i:Int= if (i%2==0) true else false`
`val evenNumbers:List[Int] = List(1,2,3,4).filter(isEven)`|scala collections are a major epic win. they have ~100 methods which operate on the data of a collection and there is *absolutely nothing* you cannot do with them.| +|`hashmap.getOrElseUpdate(key, methodThatCreatesTheValueInCaseItDoesNotExist)`|admit it, you wanted to do this in java for at least a decade| |`val evenNumbers:List[Int] = List(1,2,3,4).filter((i:Int)=> i%2==0)`|same as above, just shorter| |`val evenNumbers = List(1,2,3,4).filter(i => i%2==0)`|same as above, just shorter. you can skip the () if there is only one parameter. you can also skip the type of the parameter(s) because it can be inferred from the usage| |`val evenNumbers = List(1,2,3,4).filter(_ % 2 == 0)`|same as above, just shorter. you can skip part before "=>" if you use a parameter only once and replace the parameter usage by "_"| @@ -89,7 +90,7 @@ about: Thanks to Brendan O'Connor, this cheat |`List(1,2,3,4,5).reduce(_ + _)`|same as above, using "_" for the first and second parameter| |`List(1,2,3,4,5).fold(0)((sumSoFar,element) => sumSoFar+element)`|same as above, but fold uses an explicit start value| |`List(1,2,3,4,5).fold(0)(_ + _)`|same as the fold above, just shorter| -|`"comma separated numbers: " + List(1, 2, 3, 4, 5).fold("0")(_ + ", " + _)`|finally, you won't have to fiddle around with the last "," anymore!| +|`"comma separated numbers: " + List(1, 2, 3, 4, 5).fold("")(_ + ", " + _)`|finally, you won't have to fiddle around with the last "," anymore!| |in java this would all look like:
`Acc acc = ?;`
` for (T t: coll) {if (acc==null) {acc = t;} else {acc = doStuff(acc,t);}}`|this is boilerplate code you can avoid *every single time!*. write only what (doStuff) should happen, not "what and how" (boilerplate code + doStuff).| |where else could you save boilerplate? think about it!
try-catch-finally |

Generics

| @@ -99,7 +100,7 @@ about: Thanks to Brendan O'Connor, this cheat |`val strings:List[String] = List("hello","generics")`
`val objects:List[java.lang.Object] = strings`|in scala, type parameters of collections are covariant. this means they "inherit" the inhertance relations of their type parameters. in java, have to do an ugly cast:
`List ints = new ArrayList()`;
`List numbers = ((List`val func:(String) => java.lang.Number`|the return type is +, the parameter is -, so the function can be replaced by one declared like
`val func2:(java.lang.Object) => java.lang.Integer`
Think about it. a function that can take any object can also take a string. a function that returns an integer automatically returns a number, so the second one can replace the first one in every possible case.| |`def foo[A, B[A]] (nested: B[A])`|nested type parameters are possible. nested must be of a type that has a type parameter. for example, you could pass a List[Int]| |`def foo[A, B, C <: B[A]](nested: C))`|same as above, using an alias for B[A] named C| @@ -107,7 +108,15 @@ about: Thanks to Brendan O'Connor, this cheat |`foo(List(5))`|call to the method above, returns an Int| |`def foo[A: Manifest] {val classAtRuntime = manifest[A].erasure; println(classAtRuntime);}`|Adding ":Manifest" will make the compiler add magic so you can get the type parameter at runtime via `manifest[TYPEPARAM]`| |`foo[String]`|call to method above, prints "class java.lang.String"| - +|
Option aka "Avoid NullPointerExceptions with type safety" +|`def neverReturnsNull:Option[Foo] = ....`|in scala, you can use the type system to tell the caller of a method whether or not "null" is a valid return or parameter value. the way scala offers is "Option". you can follow a simple convention: if a parameter or return type can be null, wrap it in an Option instead.| +|`if (neverReturnsNull.isEmpty) fail(); else success(neverReturnsNull.get);`|this forces the caller to check for null explicitly.| +|`val modified = neverReturnsNull.map(notNullInHere => doStuffAndReturnNewResult(notNullInHere)`|you can use options like collections. the conversion/mapping function is applied to the contained value if there is one.| +|example:
`val maybeString:Option[String] = ....`
`val mayBeNumber:Option[Int] = maybeString.map(Integer.parseInt)`|this is perfectly safe (let's assume that the string can be parsed, we ignore exceptions here). if there was a string, there now is a number. if there was an empty option, we still have that empty option. (all empty options are actually the same instance)| +|`val emptyOption:Option[Foo] = None`|None is our empty option singleton. by type system magic, it is a subclass of any option and can therefore replace any option.| +|`val filledOption:Option[Foo] = Some(new Foo)`|Some(x) creates an option around x. you can of course drive everyone insane by putting null into a Some.| +|`val unsafelyAccessed = option.get`|the compiler does not force you to check if an option is filled| +|`val safelyAccessed = option.getOrElse(bar)`|gets the content of the option or "bar" if the option is empty| not yet pimped part of the cheat sheet: |

functions

| | From a347230a325906b52227bad57ba38aad0f4f0ea7 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Sat, 24 Dec 2011 12:09:24 +0100 Subject: [PATCH 12/36] Update cheatsheets/index.md --- cheatsheets/index.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 88e3e80800..26ba7a543e 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -44,6 +44,7 @@ about: Thanks to Brendan O'Connor, this cheat |`def method(i:Int) = t.toString;val func = method _`|appending an "_" converts any method into a function| |`takesFunction(method)`|is also possible, the compiler does the conversion for you in obvious cases| |`def method(s:String)(s2:String) = s+" "+s2`
`val intermediate:(String)=>String = method("hello")`
`intermediate("world")`|parameter lists revisited: the intermediate, "incomplete method calls" are functions. the result of the last call is "hello world"| +|`func(5)`
`func.apply(5)`|what you are actually calling is the apply-method of a function instance, but you don't have to explicitly write that. if no method name is given, the compiler assumed you want to call "apply"| |

Return types and type inference

| | | `val x = "hello"`|the compiler always picks the most specific type possible, in this case java.lang.String| | `val x:Serializable = "hello"`|you can always specify a more general one| @@ -114,9 +115,18 @@ about: Thanks to Brendan O'Connor, this cheat |`val modified = neverReturnsNull.map(notNullInHere => doStuffAndReturnNewResult(notNullInHere)`|you can use options like collections. the conversion/mapping function is applied to the contained value if there is one.| |example:
`val maybeString:Option[String] = ....`
`val mayBeNumber:Option[Int] = maybeString.map(Integer.parseInt)`|this is perfectly safe (let's assume that the string can be parsed, we ignore exceptions here). if there was a string, there now is a number. if there was an empty option, we still have that empty option. (all empty options are actually the same instance)| |`val emptyOption:Option[Foo] = None`|None is our empty option singleton. by type system magic, it is a subclass of any option and can therefore replace any option.| -|`val filledOption:Option[Foo] = Some(new Foo)`|Some(x) creates an option around x. you can of course drive everyone insane by putting null into a Some.| +|`val filledOption:Option[Foo] = Some(new Foo)`|Some(x) creates an option around x. if you pass null, None is returned| |`val unsafelyAccessed = option.get`|the compiler does not force you to check if an option is filled| |`val safelyAccessed = option.getOrElse(bar)`|gets the content of the option or "bar" if the option is empty| +|`val firstNonEmptyOption = option.orElse(option2).orElse(option3)`|no need for if-else| +

Objects

+|`object Foo {val bar = "hello"}`|declared as a class, but "simply exists", similar to "static" in java. however, it is a real singleton so it can be passed around as an object.| +|`Foo.bar`|field access and method callswork like "Foo" is a val pointing at the object instance. or in java terms "just like static stuff"| +|`object Foo {def apply(s:String) = Integer.parseInt(s)}`|the apply-shortcut works everywhere, Foo("5") becomes Foo.apply("5"). remember Some(x)? it was the same here. +|`class Foo;object Foo`|this is possible. the object Foo is then called a companion object.| +|`object Foo {def apply(i:Int) = new Foo(i+1)}`|you can use methods in the object Foo as factory methods to keep the actual constructor nice and clean| +|`def apply[A](x: A): Option[A] = if (x == null) None else Some(x)`|this is what happens when you call Some(x)| + not yet pimped part of the cheat sheet: |

functions

| | From e0b5768467d307baa0e6144169d7160f2d84d4af Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Sat, 24 Dec 2011 12:24:57 +0100 Subject: [PATCH 13/36] Update cheatsheets/index.md --- cheatsheets/index.md | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 26ba7a543e..ee4dace76c 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -109,7 +109,8 @@ about: Thanks to Brendan O'Connor, this cheat |`foo(List(5))`|call to the method above, returns an Int| |`def foo[A: Manifest] {val classAtRuntime = manifest[A].erasure; println(classAtRuntime);}`|Adding ":Manifest" will make the compiler add magic so you can get the type parameter at runtime via `manifest[TYPEPARAM]`| |`foo[String]`|call to method above, prints "class java.lang.String"| -|
Option aka "Avoid NullPointerExceptions with type safety" +|`def foo[A <: Bar with Serializable with Foobar]`|A must be a subtype of Bar, implement Serializable and also Foobar at the same time| +|

Option aka "Avoid NullPointerExceptions with type safety"

|`def neverReturnsNull:Option[Foo] = ....`|in scala, you can use the type system to tell the caller of a method whether or not "null" is a valid return or parameter value. the way scala offers is "Option". you can follow a simple convention: if a parameter or return type can be null, wrap it in an Option instead.| |`if (neverReturnsNull.isEmpty) fail(); else success(neverReturnsNull.get);`|this forces the caller to check for null explicitly.| |`val modified = neverReturnsNull.map(notNullInHere => doStuffAndReturnNewResult(notNullInHere)`|you can use options like collections. the conversion/mapping function is applied to the contained value if there is one.| @@ -119,15 +120,27 @@ about: Thanks to Brendan O'Connor, this cheat |`val unsafelyAccessed = option.get`|the compiler does not force you to check if an option is filled| |`val safelyAccessed = option.getOrElse(bar)`|gets the content of the option or "bar" if the option is empty| |`val firstNonEmptyOption = option.orElse(option2).orElse(option3)`|no need for if-else| -

Objects

-|`object Foo {val bar = "hello"}`|declared as a class, but "simply exists", similar to "static" in java. however, it is a real singleton so it can be passed around as an object.| +|

Objects

| +|`object Foo {val bar = "hello"}`|declared like a class, but "simply exists", similar to "static" in java. however, it is a real singleton so it can be passed around as an object.| |`Foo.bar`|field access and method callswork like "Foo" is a val pointing at the object instance. or in java terms "just like static stuff"| |`object Foo {def apply(s:String) = Integer.parseInt(s)}`|the apply-shortcut works everywhere, Foo("5") becomes Foo.apply("5"). remember Some(x)? it was the same here. |`class Foo;object Foo`|this is possible. the object Foo is then called a companion object.| |`object Foo {def apply(i:Int) = new Foo(i+1)}`|you can use methods in the object Foo as factory methods to keep the actual constructor nice and clean| |`def apply[A](x: A): Option[A] = if (x == null) None else Some(x)`|this is what happens when you call Some(x)| +|

Pattern matching

| +|`x match {`|scala has a very powerful switch| +|`case "hello" => {...}`|gets executed if x equals "hello". is tested via equals +|`case s:String => {...}`|gets executed if x is any string. s then exists in the code block as a val. +|`case i:Int if i < 10 => {...}`|gets executed if x is any Int < 10. i then exists in the code block as a val. +|`case 11|12|13 => {...}`|matches on more than one value| +|`case _ => `|default case, always matches| +|`}`| these were just the boring cases :)| +|`x match {`|scala can also match on values *inside* x| +|`case Some(e) => {...}`|matches of x is a Some. e then exists as a val inside the following code block| +|`case List(_, _, 3, y, z) if z == 5 => {...}`|matches if x is a list of size 5 which has a 5 at index 3 and if the fifth element is 5. the fourth element of the list then exists as "y" inside the code block, the last one does as "z".| +|`}`|how the hell did that work?| -not yet pimped part of the cheat sheet: +|not yet pimped part of the cheat sheet:| |

functions

| | | Good `def f(x: Int) = { x*x }`
Bad `def f(x: Int) { x*x }` | define function
hidden error: without = it's a Unit-returning procedure; causes havoc | From 6c3ce7faaa19387b396c6d4c9c7687ac0526efce Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Sat, 24 Dec 2011 12:56:30 +0100 Subject: [PATCH 14/36] Update cheatsheets/index.md --- cheatsheets/index.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index ee4dace76c..18c7d48325 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -138,10 +138,17 @@ about: Thanks to Brendan O'Connor, this cheat |`x match {`|scala can also match on values *inside* x| |`case Some(e) => {...}`|matches of x is a Some. e then exists as a val inside the following code block| |`case List(_, _, 3, y, z) if z == 5 => {...}`|matches if x is a list of size 5 which has a 5 at index 3 and if the fifth element is 5. the fourth element of the list then exists as "y" inside the code block, the last one does as "z".| -|`}`|how the hell did that work?| - -|not yet pimped part of the cheat sheet:| - +|`}`|how the hell did that work? see below| +|

Destructuring

| +|`object Foo { def unapply(i: Int) = if (i%2==2) Some("even") else None`|we need the reverse of an apply method - unapply.| +|`val Foo(infoString) = 42`|here, 42 is passed to unapply. if the result is an option, it's value is now stored in "infoString"| +|`42 match {case Foo(infoText) => {...}}`|if some is returned, the match is considered positive and the options value is bound to a val| +|`42 match {case Foo("even") => {...}}`|or it is tested for equality against a given value or instance| +|`41 match {case Digits(a,b) if (a == 4) => {...}}`|if the returned option contains a tuple instead of a single value, the expected happens: we now can access all the tuples fields| +|one more thing:
`unapplySeq(foo:Foo):Option[Seq[Bar]]`|like unapply, but offers special features for matching on sequences| +|`val List(a,b@_*) = List("hello","scala","world")`|a = "hello", b = List("scala", "world")| +|`val List(a,_*) = List("hello","scala","world")`|sams as above, but discards the last 2 elements, b does not exist| +|not yet pimped part of the cheat sheet:|| |

functions

| | | Good `def f(x: Int) = { x*x }`
Bad `def f(x: Int) { x*x }` | define function
hidden error: without = it's a Unit-returning procedure; causes havoc | | Good `def f(x: Any) = println(x)`
Bad `def f(x) = println(x)` | define function
syntax error: need types for every arg. | From ed549994316fcaacb0472f718d2a23cb6ccd6051 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Sat, 24 Dec 2011 12:57:15 +0100 Subject: [PATCH 15/36] Update cheatsheets/index.md --- cheatsheets/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 18c7d48325..181a22768c 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -132,7 +132,7 @@ about: Thanks to Brendan O'Connor, this cheat |`case "hello" => {...}`|gets executed if x equals "hello". is tested via equals |`case s:String => {...}`|gets executed if x is any string. s then exists in the code block as a val. |`case i:Int if i < 10 => {...}`|gets executed if x is any Int < 10. i then exists in the code block as a val. -|`case 11|12|13 => {...}`|matches on more than one value| +|`case 11 | 12 | 13 => {...}`|matches on more than one value| |`case _ => `|default case, always matches| |`}`| these were just the boring cases :)| |`x match {`|scala can also match on values *inside* x| From 554b3129f464ed8d1713656bae66ba6adb2e21fb Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Sat, 24 Dec 2011 13:00:07 +0100 Subject: [PATCH 16/36] Update cheatsheets/index.md --- cheatsheets/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 181a22768c..3eb8aed0a1 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -132,7 +132,7 @@ about: Thanks to Brendan O'Connor, this cheat |`case "hello" => {...}`|gets executed if x equals "hello". is tested via equals |`case s:String => {...}`|gets executed if x is any string. s then exists in the code block as a val. |`case i:Int if i < 10 => {...}`|gets executed if x is any Int < 10. i then exists in the code block as a val. -|`case 11 | 12 | 13 => {...}`|matches on more than one value| +|`case 11 *pipe* 12 *pipe* 13 => {...}`|matches on more than one value. how to escape the pipe character in here?| |`case _ => `|default case, always matches| |`}`| these were just the boring cases :)| |`x match {`|scala can also match on values *inside* x| From 39760ba6bd90c69e1cd687d7ca93bce721a2bf99 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Sat, 24 Dec 2011 13:09:45 +0100 Subject: [PATCH 17/36] Update cheatsheets/index.md --- cheatsheets/index.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 3eb8aed0a1..ff04df7978 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -127,6 +127,12 @@ about: Thanks to Brendan O'Connor, this cheat |`class Foo;object Foo`|this is possible. the object Foo is then called a companion object.| |`object Foo {def apply(i:Int) = new Foo(i+1)}`|you can use methods in the object Foo as factory methods to keep the actual constructor nice and clean| |`def apply[A](x: A): Option[A] = if (x == null) None else Some(x)`|this is what happens when you call Some(x)| +|

Tuples

| +|`val x:(Int, Int) = (1,2)`|Sometimes, you want to group things together and pass them around as one object, but creating a class for that would be overkill| +|`x._1`|access the first element of a tuple| +|`def takesTuple(p:(Int, String) {...}`|method accepting a tuple| +|`takesTuple(5,"hello)`|(5, "hello") could be 2 parameters or a tuple. the compiler is smart enough to figure out you meant the tuple one because it looks at the type signature of "takesTuple".| +|`takesTuple((5,"hello))`|same as above, but explicitly creating the tuple| |

Pattern matching

| |`x match {`|scala has a very powerful switch| |`case "hello" => {...}`|gets executed if x equals "hello". is tested via equals @@ -137,7 +143,7 @@ about: Thanks to Brendan O'Connor, this cheat |`}`| these were just the boring cases :)| |`x match {`|scala can also match on values *inside* x| |`case Some(e) => {...}`|matches of x is a Some. e then exists as a val inside the following code block| -|`case List(_, _, 3, y, z) if z == 5 => {...}`|matches if x is a list of size 5 which has a 5 at index 3 and if the fifth element is 5. the fourth element of the list then exists as "y" inside the code block, the last one does as "z".| +|`case List(_, _, 3, y, z) if z == 5 => {...}`|matches if x is a list of size 5 which has a 3 at index 3 and if the fifth element is 5. the fourth element of the list then exists as "y" inside the code block, the last one does as "z".| |`}`|how the hell did that work? see below| |

Destructuring

| |`object Foo { def unapply(i: Int) = if (i%2==2) Some("even") else None`|we need the reverse of an apply method - unapply.| @@ -148,6 +154,8 @@ about: Thanks to Brendan O'Connor, this cheat |one more thing:
`unapplySeq(foo:Foo):Option[Seq[Bar]]`|like unapply, but offers special features for matching on sequences| |`val List(a,b@_*) = List("hello","scala","world")`|a = "hello", b = List("scala", "world")| |`val List(a,_*) = List("hello","scala","world")`|sams as above, but discards the last 2 elements, b does not exist| + + |not yet pimped part of the cheat sheet:|| |

functions

| | | Good `def f(x: Int) = { x*x }`
Bad `def f(x: Int) { x*x }` | define function
hidden error: without = it's a Unit-returning procedure; causes havoc | From e97319dbcdc8601f7a742eb2cfecefaca2d8a3a3 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Sat, 24 Dec 2011 16:03:56 +0100 Subject: [PATCH 18/36] Update cheatsheets/index.md --- cheatsheets/index.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index ff04df7978..f72c7f7939 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -20,11 +20,13 @@ about: Thanks to Brendan O'Connor, this cheat | `def x(foo:String, bar:String):String = return foo+"hello world"+bar` | method declaration with two parameters | | `def x:String = {val x = 1;return "hello world"+1}` | multiple statements need {} around the code | | `def x = "hello world"`|return keyword and return type declaration are optional, but if a method contains return, the return type *must* be specified explicitly. default return value = last value in code block. -| `def x = {def y = 7;y}` | nested declarations are possible| +|`def iAcceptVarArgs(i:Int,s:String,d:Double*) = {...}`|method accepting varargs| +|`def x = {def y = 7;y}` | nested declarations are possible| | `class Foo`| class declaration - nested declaration also possible| | `class Foo(var x:String, val y:Int)`| class declaration with 2 public fields, one mutable, one immutable. constructor is automatically generated. only new Foo("1",2) is possible| | `class Foo {var x = 5;val y = 6}`|class like above, but with default constructor, only new Foo() is possible| | `class Foo {def x = 5}`|class with default constructor and one method| + |

Not so basic declarations

| | | `val x = {class y(val z: String); new y("hello").z}`
Bad`val foo = new y("does not work outside the block above")`| everything can be nested in anything, but everything can only be accessed in its scope| | `lazy val x = expensiveOperation()`|the expensive operation is executed once as soon as the value of x is needed, not before| @@ -56,6 +58,8 @@ about: Thanks to Brendan O'Connor, this cheat |`def x(i:Int):Int = if (i==0) 1 else i*x(i-1)`|recursive methods need an explicit return type. fail.| |

Scala Collections

| | |`1 to 3, Set(1,2,3), Buffer(1,2,3), ArrayBuffer(1,2,3), ListBuffer(1,2,3), List(1,2,3), Array(1,2,3),Vector(1,2,3), Map(1 -> "a", 2 -> "b")`|simple collection creations. scala has mutable and immutable collections.| +|`1 :: 2 :: 3 :: Nil`|In addition to that, Lists have an alternative syntax| +|`1 #:: 2 #:: 3 #:: Stream.empty`|Streams also save an alternative syntax| |prepend, append, union, remove, insertAll... |the usual methods every collection framework offers are present in scala as well| |if you like to use operators instead, there are some scary but concise ones. you'll need some practice to get them right:
+,++,++=,++:=-,--,--=,:+,:++,:=+,+=:,:++=,++:=, ++=:|method name rules:
"+" means add
"-" means remove
"++" or "--" mean add/remove many elements, not just one
"=" means modify mutable collection or (never both) assign new immutable collection to var. in the reassign case, "=" is appended to the actual method name, just like "int i=0;i+=1" in java.
":" goes on the side of the target collection and is always the first or last character of a method name. if a method end with :=, the method actually ends with : and = means it's a reassignment
if method contains ":" it is an add to an ordered collection, either at the beginning or the end of the collection| |`mutableColl += elem`|add element to a collection| @@ -153,9 +157,9 @@ about: Thanks to Brendan O'Connor, this cheat |`41 match {case Digits(a,b) if (a == 4) => {...}}`|if the returned option contains a tuple instead of a single value, the expected happens: we now can access all the tuples fields| |one more thing:
`unapplySeq(foo:Foo):Option[Seq[Bar]]`|like unapply, but offers special features for matching on sequences| |`val List(a,b@_*) = List("hello","scala","world")`|a = "hello", b = List("scala", "world")| +|`val a::tl = List("hello", "scala", "world"`|same as above using alternative list syntax| |`val List(a,_*) = List("hello","scala","world")`|sams as above, but discards the last 2 elements, b does not exist| - |not yet pimped part of the cheat sheet:|| |

functions

| | | Good `def f(x: Int) = { x*x }`
Bad `def f(x: Int) { x*x }` | define function
hidden error: without = it's a Unit-returning procedure; causes havoc | From b124fc69ab6bf69a3fd48fa54736c587c099f907 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Sat, 24 Dec 2011 16:05:00 +0100 Subject: [PATCH 19/36] Update cheatsheets/index.md --- cheatsheets/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index f72c7f7939..40105544e3 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -26,7 +26,6 @@ about: Thanks to Brendan O'Connor, this cheat | `class Foo(var x:String, val y:Int)`| class declaration with 2 public fields, one mutable, one immutable. constructor is automatically generated. only new Foo("1",2) is possible| | `class Foo {var x = 5;val y = 6}`|class like above, but with default constructor, only new Foo() is possible| | `class Foo {def x = 5}`|class with default constructor and one method| - |

Not so basic declarations

| | | `val x = {class y(val z: String); new y("hello").z}`
Bad`val foo = new y("does not work outside the block above")`| everything can be nested in anything, but everything can only be accessed in its scope| | `lazy val x = expensiveOperation()`|the expensive operation is executed once as soon as the value of x is needed, not before| From 7038c41b904447162ee3df3c5f98adc68f1b6383 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Sun, 25 Dec 2011 13:04:40 +0100 Subject: [PATCH 20/36] Update cheatsheets/index.md --- cheatsheets/index.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 40105544e3..30812df09d 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -96,7 +96,7 @@ about: Thanks to Brendan O'Connor, this cheat |`List(1,2,3,4,5).fold(0)(_ + _)`|same as the fold above, just shorter| |`"comma separated numbers: " + List(1, 2, 3, 4, 5).fold("")(_ + ", " + _)`|finally, you won't have to fiddle around with the last "," anymore!| |in java this would all look like:
`Acc acc = ?;`
` for (T t: coll) {if (acc==null) {acc = t;} else {acc = doStuff(acc,t);}}`|this is boilerplate code you can avoid *every single time!*. write only what (doStuff) should happen, not "what and how" (boilerplate code + doStuff).| -|where else could you save boilerplate? think about it!
try-catch-finally +|where else could you save boilerplate? think about it!
try-catch-finally. define your error handling once, and just inject your logic there. no need to copy & paste your try-catch blocks anywhere |

Generics

| | `def foo[BAR](bar:BAR):BAR = bar`|simple type parameter, can be anything| | `def foo[BAR <: java.lang.Number](bar: BAR) = bar.doubleValue() + 5`|upper bound, BAR must be a java.lang.Number or a subclass of it| @@ -158,7 +158,17 @@ about: Thanks to Brendan O'Connor, this cheat |`val List(a,b@_*) = List("hello","scala","world")`|a = "hello", b = List("scala", "world")| |`val a::tl = List("hello", "scala", "world"`|same as above using alternative list syntax| |`val List(a,_*) = List("hello","scala","world")`|sams as above, but discards the last 2 elements, b does not exist| - +|

Traits

| +|`trait Foo {`|Like a java interface, but more powerful. you can:| +|`def getBar():Bar`|define abstract methods like in a java interface| +|`def predefinedMethod(s:String) = "hello world"`|add non-abstract methods as well. a good example is the Ordered-trait. is expects you to implement a compare-method and delivers 4 other methods (<, >, <=, >=) which already come with an implementation based on compare| +|`val someVal = "someString"`|traits can also contain fields| +|`}`| but that's not all!| +|`trait Plugin extends java.lang.Object {`|a trait can "extend" any existing class or trait. the difference to the trait Foo above is that our Plugin here is restricted to classes which it extends. in this case java.lang.Object. why might such a thing be useful?| +|`override int hashcode = {....}`
`override int equals(other:Object) = {....}`|you can override a method of the class the trait extends. you can selectively replace or extend implementations of existing methods by adding traits. this way, you can say "these 5 classes should use *this* implementation of method foo" instead of manually overriding the method in each class| +|`override boolean add(t:T) = {println(t +" is about to be added to the collection");super.add(t)}`|this is useful for stuff like logging. you can also use this to add features to specific classes. for example, there is a MultiMap-trait in scala which can be attached to maps having sets as values. it adds a addBinding- and removeBinding-methods that are based on the original put/remove-methods and handle the details| +|`}`|these traits are called mixins. a class can have more than one mixin, and they can also override each other. from inside the trait, "super" refers to whatever they extend.| +|`new Foo with BarTrait with SomeOtherTrait`|create a new instance of foo having 2 traits.| |not yet pimped part of the cheat sheet:|| |

functions

| | | Good `def f(x: Int) = { x*x }`
Bad `def f(x: Int) { x*x }` | define function
hidden error: without = it's a Unit-returning procedure; causes havoc | From 43d9cf490f6e84e4abc270c6a0c4643cee791825 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Sun, 25 Dec 2011 13:14:31 +0100 Subject: [PATCH 21/36] Update cheatsheets/index.md --- cheatsheets/index.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 30812df09d..31bb23c7cc 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -168,7 +168,10 @@ about: Thanks to Brendan O'Connor, this cheat |`override int hashcode = {....}`
`override int equals(other:Object) = {....}`|you can override a method of the class the trait extends. you can selectively replace or extend implementations of existing methods by adding traits. this way, you can say "these 5 classes should use *this* implementation of method foo" instead of manually overriding the method in each class| |`override boolean add(t:T) = {println(t +" is about to be added to the collection");super.add(t)}`|this is useful for stuff like logging. you can also use this to add features to specific classes. for example, there is a MultiMap-trait in scala which can be attached to maps having sets as values. it adds a addBinding- and removeBinding-methods that are based on the original put/remove-methods and handle the details| |`}`|these traits are called mixins. a class can have more than one mixin, and they can also override each other. from inside the trait, "super" refers to whatever they extend.| -|`new Foo with BarTrait with SomeOtherTrait`|create a new instance of foo having 2 traits.| +|`new Foo extends FirstTrait with BarTrait with SomeOtherTrait`|create a new instance of foo implementing 3 traits. the first one is extended, the next n are "withed".| +|`class Foo extends BarTrait`|declaring a class which implements Bar directly| +|`class Foo extends BarTrait with Serializable`|first extends, then with| +|`class A extends B with C with D with E`|inside E, super refers to D. inside D, super refers to C, and so on. keep this in mind when overriding the same method with different traits which all call they supers.| |not yet pimped part of the cheat sheet:|| |

functions

| | | Good `def f(x: Int) = { x*x }`
Bad `def f(x: Int) { x*x }` | define function
hidden error: without = it's a Unit-returning procedure; causes havoc | From 7f49dba84b99fa8a81ba5ef739ad3d2064027102 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Sun, 25 Dec 2011 13:42:55 +0100 Subject: [PATCH 22/36] Update cheatsheets/index.md --- cheatsheets/index.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 31bb23c7cc..b909535591 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -18,16 +18,16 @@ about: Thanks to Brendan O'Connor, this cheat | `def x:String = return "hello world"` | method declaration | | `def x(foo:String):String = return foo+"hello world"` | method declaration with simple parameter | | `def x(foo:String, bar:String):String = return foo+"hello world"+bar` | method declaration with two parameters | -| `def x:String = {val x = 1;return "hello world"+1}` | multiple statements need {} around the code | +| `def x:String = {`
`val x = 1`
`return "hello world"+1`
`}` | multiple statements need {} around the code | | `def x = "hello world"`|return keyword and return type declaration are optional, but if a method contains return, the return type *must* be specified explicitly. default return value = last value in code block. |`def iAcceptVarArgs(i:Int,s:String,d:Double*) = {...}`|method accepting varargs| |`def x = {def y = 7;y}` | nested declarations are possible| | `class Foo`| class declaration - nested declaration also possible| | `class Foo(var x:String, val y:Int)`| class declaration with 2 public fields, one mutable, one immutable. constructor is automatically generated. only new Foo("1",2) is possible| -| `class Foo {var x = 5;val y = 6}`|class like above, but with default constructor, only new Foo() is possible| +| `class Foo {`
`var x = 5`
`val y = 6`
`}`|class like above, but with default constructor, only new Foo() is possible| | `class Foo {def x = 5}`|class with default constructor and one method| |

Not so basic declarations

| | -| `val x = {class y(val z: String); new y("hello").z}`
Bad`val foo = new y("does not work outside the block above")`| everything can be nested in anything, but everything can only be accessed in its scope| +| `val x = {`
`class y(val z: String)`
`new y("hello").z`
`}`
Bad`val foo = new y("does not work outside the block above")`| everything can be nested in anything, but everything can only be accessed in its scope| | `lazy val x = expensiveOperation()`|the expensive operation is executed once as soon as the value of x is needed, not before| | `def method(a:String = "hello", b:String = "world") = a+" "+b`|method will default values| | `method("goodbye")`|call to method above, unspecificed parameters will get default values. returns "goodbye world"| @@ -53,7 +53,7 @@ about: Thanks to Brendan O'Connor, this cheat | `def x:Unit = {...}`
`def x() {...}`|leaving out the "=" at a method declaration is the same as specifying "Unit"| | `val blocks = {{{{5}}}}`|every block has a return type that is passed back to the next outer block| | `val block = if (a) foo else bar`|almost everything is an expression and thus, has a return type. this includes if-else-structures| -|`def x = if (System.currentTimeMillis() % 2 == 0) Integer.valueOf(1) else java.lang.Double.valueOf(2)`|here, the compiler picks the most specific supertype of both Integer and Double which is java.lang.Number (this is a lie)| +|`def x = {`
`if (System.currentTimeMillis() % 2 == 0) Integer.valueOf(1) else java.lang.Double.valueOf(2)`
`}`|here, the compiler picks the most specific supertype of both Integer and Double which is java.lang.Number (this is a lie)| |`def x(i:Int):Int = if (i==0) 1 else i*x(i-1)`|recursive methods need an explicit return type. fail.| |

Scala Collections

| | |`1 to 3, Set(1,2,3), Buffer(1,2,3), ArrayBuffer(1,2,3), ListBuffer(1,2,3), List(1,2,3), Array(1,2,3),Vector(1,2,3), Map(1 -> "a", 2 -> "b")`|simple collection creations. scala has mutable and immutable collections.| @@ -166,12 +166,12 @@ about: Thanks to Brendan O'Connor, this cheat |`}`| but that's not all!| |`trait Plugin extends java.lang.Object {`|a trait can "extend" any existing class or trait. the difference to the trait Foo above is that our Plugin here is restricted to classes which it extends. in this case java.lang.Object. why might such a thing be useful?| |`override int hashcode = {....}`
`override int equals(other:Object) = {....}`|you can override a method of the class the trait extends. you can selectively replace or extend implementations of existing methods by adding traits. this way, you can say "these 5 classes should use *this* implementation of method foo" instead of manually overriding the method in each class| -|`override boolean add(t:T) = {println(t +" is about to be added to the collection");super.add(t)}`|this is useful for stuff like logging. you can also use this to add features to specific classes. for example, there is a MultiMap-trait in scala which can be attached to maps having sets as values. it adds a addBinding- and removeBinding-methods that are based on the original put/remove-methods and handle the details| +|`override boolean add(t:T) = {`
`println(t +" is about to be added to the collection")`
`super.add(t)`
`}`|this is useful for stuff like logging. you can also use this to add features to specific classes. for example, there is a MultiMap-trait in scala which can be attached to maps having sets as values. it adds a addBinding- and removeBinding-methods that are based on the original put/remove-methods and handle the details| |`}`|these traits are called mixins. a class can have more than one mixin, and they can also override each other. from inside the trait, "super" refers to whatever they extend.| |`new Foo extends FirstTrait with BarTrait with SomeOtherTrait`|create a new instance of foo implementing 3 traits. the first one is extended, the next n are "withed".| |`class Foo extends BarTrait`|declaring a class which implements Bar directly| |`class Foo extends BarTrait with Serializable`|first extends, then with| -|`class A extends B with C with D with E`|inside E, super refers to D. inside D, super refers to C, and so on. keep this in mind when overriding the same method with different traits which all call they supers.| +|`class A extends B with C with D with E`|inside E, super refers to D. inside D, super refers to C, and so on. keep this in mind when overriding the same method with different traits which call they supers.| |not yet pimped part of the cheat sheet:|| |

functions

| | | Good `def f(x: Int) = { x*x }`
Bad `def f(x: Int) { x*x }` | define function
hidden error: without = it's a Unit-returning procedure; causes havoc | From 5e75bb8aaf82e8984038482735031ff79e3bb1ba Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Sun, 25 Dec 2011 15:15:06 +0100 Subject: [PATCH 23/36] Update cheatsheets/index.md --- cheatsheets/index.md | 90 ++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 54 deletions(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index b909535591..dc71a87d5e 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -26,6 +26,12 @@ about: Thanks to Brendan O'Connor, this cheat | `class Foo(var x:String, val y:Int)`| class declaration with 2 public fields, one mutable, one immutable. constructor is automatically generated. only new Foo("1",2) is possible| | `class Foo {`
`var x = 5`
`val y = 6`
`}`|class like above, but with default constructor, only new Foo() is possible| | `class Foo {def x = 5}`|class with default constructor and one method| +|

Syntax details

| +|just a few things that didn't fit anywhere else|| +|`instance.bar`|bar can be a reading field access or a parameterless method call. scala doesn't make a difference. this means you can easily switch between def and val without the need for a refactoring| +|`instance.bar()`|for method calls, you can add (). by convention, methods without () don't change any states and just return a calculated value. methods with () are called for they effects, for example changing a value, printing something on the console and so on| +|`instance bar`|you can skip the "." if it is obvious to the compiler what you mean. humans and the compiler usually agree if there is an instance on the left and a method of that instance on the right. this is useful for DSLs| +|`println {"hello world"}`|if a method has one parameter, you can also pass a block instead of using (). also useful for DSLs| |

Not so basic declarations

| | | `val x = {`
`class y(val z: String)`
`new y("hello").z`
`}`
Bad`val foo = new y("does not work outside the block above")`| everything can be nested in anything, but everything can only be accessed in its scope| | `lazy val x = expensiveOperation()`|the expensive operation is executed once as soon as the value of x is needed, not before| @@ -35,6 +41,17 @@ about: Thanks to Brendan O'Connor, this cheat |`def method(param: => String)`|"=>" means that when the method is called, the parameter is wrapped in a function which is executed when accessed. the string is evaluated every time when needed (see Iterator.continually), but not before. the value is not cached, but you can pass a lazy val to make it cached.| |`def method(s:String)(i:Int)`|method with multiple parameter lists| |`val intermediate = method("hello")`
`intermediate(5)`|why? because you can apply one parameter list at once and the next ones later and pass "the incomplete call" around. in java, you would use a builder for this.| +|

Declarations related to OO

| | +| `class C(x: R)` _same as_
`class C(private val x: R)`
`var c = new C(4)` | constructor params - automatically turn into private fields if used after construction. if not, the compiler doesn't generate fields for the params| +| `class C(val x: R)`
`var c = new C(4)`
`c.x` | constructor params - exposed as public fields | +| `class C(var x: R) {`
`assert(x > 0, "positive please")`
`var y = x`
`val readonly = 5`
`private var secret = 1`
`def this = this(42)`
`}`|
constructor is class body
declare a public member
declare a gettable but not settable member
declare a private member
alternative constructor. all alternative constructors must call the main constructor from the class declaration| +| `new{ ... }` | anonymous class. more later.| +| `abstract class D { ... }` | define an abstract class. (non-createable) | +| `class C extends D { ... }` | define an inherited class. | +| `class D(var x: R)`
`class C(x: R) extends D(x)` | inheritance and constructor params) +| `classOf[String]` | class literal. | +| `x.isInstanceOf[String]` | type check (runtime) | +| `x.asInstanceOf[String]` | type cast (runtime) | |

Declaring functions

| | | `(i:Int) => i+1`|creates a function.| | `var func = (i:Int) => i+1`|creates a function and stores it in a variable| @@ -136,6 +153,7 @@ about: Thanks to Brendan O'Connor, this cheat |`def takesTuple(p:(Int, String) {...}`|method accepting a tuple| |`takesTuple(5,"hello)`|(5, "hello") could be 2 parameters or a tuple. the compiler is smart enough to figure out you meant the tuple one because it looks at the type signature of "takesTuple".| |`takesTuple((5,"hello))`|same as above, but explicitly creating the tuple| +|`coll zip coll2`|creates a single collection which contains tuples which contain values from coll and coll2, matching by index. for example `List(1,2) zip (List("a","b")` becomes `List((1,"a"),(2,"b"))` |

Pattern matching

| |`x match {`|scala has a very powerful switch| |`case "hello" => {...}`|gets executed if x equals "hello". is tested via equals @@ -172,69 +190,33 @@ about: Thanks to Brendan O'Connor, this cheat |`class Foo extends BarTrait`|declaring a class which implements Bar directly| |`class Foo extends BarTrait with Serializable`|first extends, then with| |`class A extends B with C with D with E`|inside E, super refers to D. inside D, super refers to C, and so on. keep this in mind when overriding the same method with different traits which call they supers.| -|not yet pimped part of the cheat sheet:|| -|

functions

| | -| Good `def f(x: Int) = { x*x }`
Bad `def f(x: Int) { x*x }` | define function
hidden error: without = it's a Unit-returning procedure; causes havoc | -| Good `def f(x: Any) = println(x)`
Bad `def f(x) = println(x)` | define function
syntax error: need types for every arg. | -| `type R = Double` | type alias | -| `def f(x: R)` vs.
`def f(x: => R)` | call-by-value
call-by-name (lazy parameters) | -| `(x:R) => x*x` | anonymous function | -| `(1 to 5).map(_*2)` vs.
`(1 to 5).reduceLeft( _+_ )` | anonymous function: underscore is positionally matched arg. | -| `(1 to 5).map( x => x*x )` | anonymous function: to use an arg twice, have to name it. | -| Good `(1 to 5).map(2*)`
Bad `(1 to 5).map(*2)` | anonymous function: bound infix method. Use `2*_` for sanity's sake instead. | -| `(1 to 5).map { val x=_*2; println(x); x }` | anonymous function: block style returns last expression. | -| `(1 to 5) filter {_%2 == 0} map {_*2}` | anonymous functions: pipeline style. (or parens too). | -| `def compose(g:R=>R, h:R=>R) = (x:R) => g(h(x))`
`val f = compose({_*2}, {_-1})` | anonymous functions: to pass in multiple blocks, need outer parens. | -| `val zscore = (mean:R, sd:R) => (x:R) => (x-mean)/sd` | currying, obvious syntax. | -| `def zscore(mean:R, sd:R) = (x:R) => (x-mean)/sd` | currying, obvious syntax | -| `def zscore(mean:R, sd:R)(x:R) = (x-mean)/sd` | currying, sugar syntax. but then: | -| `val normer = zscore(7, 0.4)_` | need trailing underscore to get the partial, only for the sugar version. | -| `def mapmake[T](g:T=>T)(seq: List[T]) = seq.map(g)` | generic type. | -| `5.+(3); 5 + 3`
`(1 to 5) map (_*2)` | infix sugar. | -| `def sum(args: Int*) = args.reduceLeft(_+_)` | varargs. | |

packages

| | | `import scala.collection._` | wildcard import. | | `import scala.collection.Vector`
`import scala.collection.{Vector, Sequence}` | selective import. | | `import scala.collection.{Vector => Vec28}` | renaming import. | | `import java.util.{Date => _, _}` | import all from java.util except Date. | | `package pkg` _at start of file_
`package pkg { ... }` | declare a package. | -|

data structures

| | -| `(1,2,3)` | tuple literal. (`Tuple3`) | -| `var (x,y,z) = (1,2,3)` | destructuring bind: tuple unpacking via pattern matching. | -| Bad`var x,y,z = (1,2,3)` | hidden error: each assigned to the entire tuple. | -| `var xs = List(1,2,3)` | list (immutable). | -| `xs(2)` | paren indexing. ([slides](http://www.slideshare.net/Odersky/fosdem-2009-1013261/27)) | -| `1 :: List(2,3)` | cons. | -| `1 to 5` _same as_ `1 until 6`
`1 to 10 by 2` | range sugar. | -| `()` _(empty parens)_ | sole member of the Unit type (like C/Java void). | |

control constructs

| | | `if (check) happy else sad` | conditional. | | `if (check) happy` _same as_
`if (check) happy else ()` | conditional sugar. | | `while (x < 5) { println(x); x += 1}` | while loop. | | `do { println(x); x += 1} while (x < 5)` | do while loop. | | `import scala.util.control.Breaks._`
`breakable {`
` for (x <- xs) {`
` if (Math.random < 0.1) break`
` }`
`}`| break. ([slides](http://www.slideshare.net/Odersky/fosdem-2009-1013261/21)) | -| `for (x <- xs if x%2 == 0) yield x*10` _same as_
`xs.filter(_%2 == 0).map(_*10)` | for comprehension: filter/map | -| `for ((x,y) <- xs zip ys) yield x*y` _same as_
`(xs zip ys) map { case (x,y) => x*y }` | for comprehension: destructuring bind | -| `for (x <- xs; y <- ys) yield x*y` _same as_
`xs flatMap {x => ys map {y => x*y}}` | for comprehension: cross product | -| `for (x <- xs; y <- ys) {`
`println("%d/%d = %.1f".format(x,y, x*y))`
`}` | for comprehension: imperative-ish
[sprintf-style](http://java.sun.com/javase/6/docs/api/java/util/Formatter.html#syntax) | -|

pattern matching

| | -| Good `(xs zip ys) map { case (x,y) => x*y }`
Bad `(xs zip ys) map( (x,y) => x*y )` | use case in function args for pattern matching. | -| Bad
`val v42 = 42`
`Some(3) match {`
` case Some(v42) => println("42")`
` case _ => println("Not 42")`
`}` | "v42" is interpreted as a name matching any Int value, and "42" is printed. -| Good
`val v42 = 42`
`Some(3) match {`
`` case Some(`v42`) => println("42")``
`case _ => println("Not 42")`
`}` | "\`v42\`" with backticks is interpreted as the read-only variable v42, and "Not 42" is printed. -|

object orientation

| | -| `class C(x: R)` _same as_
`class C(private val x: R)`
`var c = new C(4)` | constructor params - private | -| `class C(val x: R)`
`var c = new C(4)`
`c.x` | constructor params - public | -| `class C(var x: R) {`
`assert(x > 0, "positive please")`
`var y = x`
`val readonly = 5`
`private var secret = 1`
`def this = this(42)`
`}`|
constructor is class body
declare a public member
declare a gettable but not settable member
declare a private member
alternative constructor| -| `new{ ... }` | anonymous class | -| `abstract class D { ... }` | define an abstract class. (non-createable) | -| `class C extends D { ... }` | define an inherited class. | -| `class D(var x: R)`
`class C(x: R) extends D(x)` | inheritance and constructor params. (wishlist: automatically pass-up params by default) -| `object O extends D { ... }` | define a singleton. (module-like) | -| `trait T { ... }`
`class C extends T { ... }`
`class C extends D with T { ... }` | traits.
interfaces-with-implementation. no constructor params. [mixin-able]({{ site.baseurl }}/tutorials/tour/mixin-class-composition.html). -| `trait T1; trait T2`
`class C extends T1 with T2`
`class C extends D with T1 with T2` | multiple traits. | -| `class C extends D { override def f = ...}` | must declare method overrides. | -| `new java.io.File("f")` | create object. | -| Bad `new List[Int]`
Good `List(1,2,3)` | type error: abstract type
instead, convention: callable factory shadowing the type | -| `classOf[String]` | class literal. | -| `x.isInstanceOf[String]` | type check (runtime) | -| `x.asInstanceOf[String]` | type cast (runtime) | +| `for (i <- 1 to 10 {doStuffWith(i)}`|most basic "for loop". actually it's not a loop but the compiler turns it into `1 to 10 foreach {i => *block content*}. and it is not called for loop, but for comprehension. it's a higher level construct - loops are low level.| +| `for (i <- 1 to 10 if i % 2 == 0) {}`|conditions are possible| +| `for (i <- 1 to 10;i2 <- 10 to 10) {println(i+i2)}`|no need for nested fors| +| `val evenNumbers = for (i <- 1 to 10) yield (i*2)`|yield means "the loop should return that". in this case, you get all even numbers from 2 to 20| +| `for (x <- xs if x%2 == 0) yield x*10` _same as_
`xs.filter(_%2 == 0).map(_*10)` | what you write, and what the compiler does | +| `for ((x,y) <- xs zip ys) yield x*y` | pattern matching works in here | +|

Implicits

| +|`implicit`|mystic keyword. can be attached to vals, vars, defs and objects and method parameters| +|`def parseInt(s:String) = Integer.parseInt(s)`|simple string -> int method| +|`implicit def parseInt(s:String) = Integer.parseInt(s)`|implicit string -> int method. it still can be used as a normal method, but it has one special feature| +|`val i:Int = "42"`|if there is an implicit method in scope which can convert a "wrong" type (string 42) into a "correct" one, the compiler automatically uses it. the code becomes `val i = parseInt("42")`| +|`implicit def attachMethod(i:Int) = new {def tenTimes = i*10}`|another implicit conversion from "Int" to an anonymous class having a method "tenTimes"| +|using several implicit conversions attaching methods in a chain, combined with scala's .-inference, you can create code that looks like a text that acually makes sense to a human. for a great example, take a look at ScalaTest| +|`val i:Int = 42`
`println(i.tenTimes)`|if there is an implicit method which can convert a type not having a method into one having that method - the compiler uses that conversion to make your code valid. this is a common pattern to attach methods to objects| +|`abstract class GenericAddition[T] {def add(t:T,t2:T):T}`
`implicit object IntAddition extends GenericAddition[Int] {def add(t:Int, t2:Int) = t+t2}`|an implicit object| +|`def addTwoThings[T](t:T, t2:T)(implicit logicToUse:GenericAddition[T]) = logicToUse.add(t,t2)`|method using a second implicit parameter list| +|`addTwoThings(1,2)(IntAddition)`|call to method above. so far, no magic involved.| +|`addTwoThings(1,2)`|if a matching implicit object is in scope, it will automatically be used. you don't have to pass it yourself. it's a nice feature to separate the "what" from "how" and let the compiler pick the "how"-logic automatically.| \ No newline at end of file From 68e76b0ce57eb430a92690fd6f983b523db80554 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Sun, 25 Dec 2011 16:10:35 +0100 Subject: [PATCH 24/36] Update cheatsheets/index.md --- cheatsheets/index.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index dc71a87d5e..239dcc65ee 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -22,10 +22,6 @@ about: Thanks to Brendan O'Connor, this cheat | `def x = "hello world"`|return keyword and return type declaration are optional, but if a method contains return, the return type *must* be specified explicitly. default return value = last value in code block. |`def iAcceptVarArgs(i:Int,s:String,d:Double*) = {...}`|method accepting varargs| |`def x = {def y = 7;y}` | nested declarations are possible| -| `class Foo`| class declaration - nested declaration also possible| -| `class Foo(var x:String, val y:Int)`| class declaration with 2 public fields, one mutable, one immutable. constructor is automatically generated. only new Foo("1",2) is possible| -| `class Foo {`
`var x = 5`
`val y = 6`
`}`|class like above, but with default constructor, only new Foo() is possible| -| `class Foo {def x = 5}`|class with default constructor and one method| |

Syntax details

| |just a few things that didn't fit anywhere else|| |`instance.bar`|bar can be a reading field access or a parameterless method call. scala doesn't make a difference. this means you can easily switch between def and val without the need for a refactoring| @@ -42,10 +38,14 @@ about: Thanks to Brendan O'Connor, this cheat |`def method(s:String)(i:Int)`|method with multiple parameter lists| |`val intermediate = method("hello")`
`intermediate(5)`|why? because you can apply one parameter list at once and the next ones later and pass "the incomplete call" around. in java, you would use a builder for this.| |

Declarations related to OO

| | +| `class Foo`| class declaration - nested declaration also possible| +| `class Foo(var x:String, val y:Int)`| class declaration with 2 public fields, one mutable, one immutable. constructor is automatically generated. only new Foo("1",2) is possible| +| `class Foo {`
`var x = 5`
`val y = 6`
`}`|class like above, but with default constructor, only new Foo() is possible| +| `class Foo {def x = 5}`|class with default constructor and one method| | `class C(x: R)` _same as_
`class C(private val x: R)`
`var c = new C(4)` | constructor params - automatically turn into private fields if used after construction. if not, the compiler doesn't generate fields for the params| | `class C(val x: R)`
`var c = new C(4)`
`c.x` | constructor params - exposed as public fields | -| `class C(var x: R) {`
`assert(x > 0, "positive please")`
`var y = x`
`val readonly = 5`
`private var secret = 1`
`def this = this(42)`
`}`|
constructor is class body
declare a public member
declare a gettable but not settable member
declare a private member
alternative constructor. all alternative constructors must call the main constructor from the class declaration| -| `new{ ... }` | anonymous class. more later.| +| `class C(var x: R) {`
`assert(x > 0, "positive please") //class body = constructor`
`var y = x // public field`
`val readonly = 5 // readonly field`
`private var secret = 1 // private field`
`def this = this(42) // alternative constructor`
`}`|simple example covering the common use cases. note: all alternative constructors must call the main constructor declared at the class declaration. this is it is impossible to forget to initialize a field by constructor overloading.| +| `new{ ... }` | anonymous class. more later (see implicits)| | `abstract class D { ... }` | define an abstract class. (non-createable) | | `class C extends D { ... }` | define an inherited class. | | `class D(var x: R)`
`class C(x: R) extends D(x)` | inheritance and constructor params) @@ -213,10 +213,16 @@ about: Thanks to Brendan O'Connor, this cheat |`def parseInt(s:String) = Integer.parseInt(s)`|simple string -> int method| |`implicit def parseInt(s:String) = Integer.parseInt(s)`|implicit string -> int method. it still can be used as a normal method, but it has one special feature| |`val i:Int = "42"`|if there is an implicit method in scope which can convert a "wrong" type (string 42) into a "correct" one, the compiler automatically uses it. the code becomes `val i = parseInt("42")`| -|`implicit def attachMethod(i:Int) = new {def tenTimes = i*10}`|another implicit conversion from "Int" to an anonymous class having a method "tenTimes"| +|`implicit def attachMethod(i:Int) = new {def tenTimes = i*10}`|another implicit conversion from "Int" to an anonymous class having a method "tenTimes". the returnes class doesn't need a name.| |using several implicit conversions attaching methods in a chain, combined with scala's .-inference, you can create code that looks like a text that acually makes sense to a human. for a great example, take a look at ScalaTest| |`val i:Int = 42`
`println(i.tenTimes)`|if there is an implicit method which can convert a type not having a method into one having that method - the compiler uses that conversion to make your code valid. this is a common pattern to attach methods to objects| |`abstract class GenericAddition[T] {def add(t:T,t2:T):T}`
`implicit object IntAddition extends GenericAddition[Int] {def add(t:Int, t2:Int) = t+t2}`|an implicit object| |`def addTwoThings[T](t:T, t2:T)(implicit logicToUse:GenericAddition[T]) = logicToUse.add(t,t2)`|method using a second implicit parameter list| |`addTwoThings(1,2)(IntAddition)`|call to method above. so far, no magic involved.| -|`addTwoThings(1,2)`|if a matching implicit object is in scope, it will automatically be used. you don't have to pass it yourself. it's a nice feature to separate the "what" from "how" and let the compiler pick the "how"-logic automatically.| \ No newline at end of file +|`addTwoThings(1,2)`|if a matching implicit object is in scope, it will automatically be used. you don't have to pass it yourself. it's a nice feature to separate the "what" from "how" and let the compiler pick the "how"-logic automatically.| +|

Abstract types

| +|`type Str = String`|simple alias. Str and String are equal for the compiler| +|`type Complex[A] = (String,String,String,A)`|if you are too lazy to write a complex type expression because a part of the expression is constant, use this. "Complex" is called a type contructor, and A is its parameter. you can declare something as Complex[Int] and it is considered equal to any Tuple having the type (String, String, String, Int)| +|`type StructualType = {def x:String;val y:Int}`|this is a structural type. is allows type safe duck-typing. if you declare a method that accepts "StructuralType", is accepts all objects that have a method x:String and a field y:Int. at runtime, reflection is used for this, but you cannot mess it up at compile time like in dynamically types languages.| +|`class X {type Y <: Foo}`|types can be clared in classes and traits and overridden in subclasses. upper and lower bounds apply here, too.| +|`type X = {type U = Foo}`|types can be nested. this is useful for things that are too big to explain here, but i can tease you a bit: you can declare a type that "is an int but with an attached subtype". at runtime, everything is still an int, but at compile time, userids, inches, the number of hairs - everything would have a different type and you would get compile errors if you tried to mix them. for strings, you could tag them with an "is resource key", "is already resolved" or "is already html-escaped"-type to avoid doubly resolved or escaped strings. for details, see http://etorreborre.blogspot.com/2011/11/practical-uses-for-unboxed-tagged-types.html \ No newline at end of file From 29c257920256a665387b18e90ca335b02852c198 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Sun, 25 Dec 2011 16:18:11 +0100 Subject: [PATCH 25/36] Update cheatsheets/index.md --- cheatsheets/index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 239dcc65ee..c3d992465f 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -225,4 +225,5 @@ about: Thanks to Brendan O'Connor, this cheat |`type Complex[A] = (String,String,String,A)`|if you are too lazy to write a complex type expression because a part of the expression is constant, use this. "Complex" is called a type contructor, and A is its parameter. you can declare something as Complex[Int] and it is considered equal to any Tuple having the type (String, String, String, Int)| |`type StructualType = {def x:String;val y:Int}`|this is a structural type. is allows type safe duck-typing. if you declare a method that accepts "StructuralType", is accepts all objects that have a method x:String and a field y:Int. at runtime, reflection is used for this, but you cannot mess it up at compile time like in dynamically types languages.| |`class X {type Y <: Foo}`|types can be clared in classes and traits and overridden in subclasses. upper and lower bounds apply here, too.| -|`type X = {type U = Foo}`|types can be nested. this is useful for things that are too big to explain here, but i can tease you a bit: you can declare a type that "is an int but with an attached subtype". at runtime, everything is still an int, but at compile time, userids, inches, the number of hairs - everything would have a different type and you would get compile errors if you tried to mix them. for strings, you could tag them with an "is resource key", "is already resolved" or "is already html-escaped"-type to avoid doubly resolved or escaped strings. for details, see http://etorreborre.blogspot.com/2011/11/practical-uses-for-unboxed-tagged-types.html \ No newline at end of file +|`type X = {type U = Foo}`|types can be nested. this is useful for things that are too big to explain here, but i can tease you a bit: you can declare a type that "is an int but with an attached subtype". at runtime, everything is still an int, but at compile time, userids, inches, the number of hairs - everything would have a different type and you would get compile errors if you tried to mix them. for strings, you could tag them with an "is resource key", "is already resolved" or "is already html-escaped"-type to avoid doubly resolved or escaped strings. for details, see http://etorreborre.blogspot.com/2011/11/practical-uses-for-unboxed-tagged-types.html +|`this.type`|this refers to the type "this" has. this is pretty useless as long as you are inside "this". but if you use it as a return type, it get's updated once you use a subclass. simple use case: `def cloneOfMe:this.type`. you'll want a subclass to return it's own type, not the parent type.| \ No newline at end of file From 3cf82d21c632599f721f5805be962698ee4c86be Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Sun, 25 Dec 2011 16:29:01 +0100 Subject: [PATCH 26/36] Update cheatsheets/index.md --- cheatsheets/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index c3d992465f..8135400177 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -63,6 +63,7 @@ about: Thanks to Brendan O'Connor, this cheat |`takesFunction(method)`|is also possible, the compiler does the conversion for you in obvious cases| |`def method(s:String)(s2:String) = s+" "+s2`
`val intermediate:(String)=>String = method("hello")`
`intermediate("world")`|parameter lists revisited: the intermediate, "incomplete method calls" are functions. the result of the last call is "hello world"| |`func(5)`
`func.apply(5)`|what you are actually calling is the apply-method of a function instance, but you don't have to explicitly write that. if no method name is given, the compiler assumed you want to call "apply"| +|`def createFunction = (i:Int) => i+1`
`createFunction(5)`|if you have read the syntax section above, you can figure out what happens here. first, createFunction is called without () and without a parameter. then, 5 is applied to the apply method of the *result* of createfunction| |

Return types and type inference

| | | `val x = "hello"`|the compiler always picks the most specific type possible, in this case java.lang.String| | `val x:Serializable = "hello"`|you can always specify a more general one| From 44f2ab5f488dd36ce1d963d8592b1e129e90b0cd Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Sun, 25 Dec 2011 21:41:33 +0100 Subject: [PATCH 27/36] Update cheatsheets/index.md --- cheatsheets/index.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 8135400177..07200d71b0 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -52,6 +52,7 @@ about: Thanks to Brendan O'Connor, this cheat | `classOf[String]` | class literal. | | `x.isInstanceOf[String]` | type check (runtime) | | `x.asInstanceOf[String]` | type cast (runtime) | +|`case class Foo; case object Bar`|the keyword "case" makes the compiler generate equals & hashcode methods for that class. also, constructor params are always public readonly fields| |

Declaring functions

| | | `(i:Int) => i+1`|creates a function.| | `var func = (i:Int) => i+1`|creates a function and stores it in a variable| @@ -177,6 +178,7 @@ about: Thanks to Brendan O'Connor, this cheat |`val List(a,b@_*) = List("hello","scala","world")`|a = "hello", b = List("scala", "world")| |`val a::tl = List("hello", "scala", "world"`|same as above using alternative list syntax| |`val List(a,_*) = List("hello","scala","world")`|sams as above, but discards the last 2 elements, b does not exist| +|Note: for case classes, an unapply method is automatically generated| |

Traits

| |`trait Foo {`|Like a java interface, but more powerful. you can:| |`def getBar():Bar`|define abstract methods like in a java interface| @@ -227,4 +229,9 @@ about: Thanks to Brendan O'Connor, this cheat |`type StructualType = {def x:String;val y:Int}`|this is a structural type. is allows type safe duck-typing. if you declare a method that accepts "StructuralType", is accepts all objects that have a method x:String and a field y:Int. at runtime, reflection is used for this, but you cannot mess it up at compile time like in dynamically types languages.| |`class X {type Y <: Foo}`|types can be clared in classes and traits and overridden in subclasses. upper and lower bounds apply here, too.| |`type X = {type U = Foo}`|types can be nested. this is useful for things that are too big to explain here, but i can tease you a bit: you can declare a type that "is an int but with an attached subtype". at runtime, everything is still an int, but at compile time, userids, inches, the number of hairs - everything would have a different type and you would get compile errors if you tried to mix them. for strings, you could tag them with an "is resource key", "is already resolved" or "is already html-escaped"-type to avoid doubly resolved or escaped strings. for details, see http://etorreborre.blogspot.com/2011/11/practical-uses-for-unboxed-tagged-types.html -|`this.type`|this refers to the type "this" has. this is pretty useless as long as you are inside "this". but if you use it as a return type, it get's updated once you use a subclass. simple use case: `def cloneOfMe:this.type`. you'll want a subclass to return it's own type, not the parent type.| \ No newline at end of file +|`this.type`|this refers to the type "this" has. this is pretty useless as long as you are inside "this". but if you use it as a return type, it get's updated once you use a subclass. simple use case: `def cloneOfMe:this.type`. you'll want a subclass to return it's own type, not the parent type.| +|

For java programmers: Lifted restrictions / Important differences

| +|If you are coming from java, you might have gotten used to several restrictions and might not even try to do it in scala because you expect it not to work. here is what does work in scala, but not in java| +|`a == b`|this is a null safe call to equals. if you want a check by reference, use "eq" instead of "=="| +|`var x = 0`
`1 to 10 foreach {i => {println("changing x from inside another class");x += i;}`|in java, you cannot access local variables from anonymous classes unless they are final. in scala, you can.| +|`class Foo {def x = "a"}`
`class Bar extends Foo {override val x = "b"}`|parameterless methods can be overridden by readonly fields| From 5a8a2bc9a862b41e42eef499378974e8f6afa0a0 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Mon, 26 Dec 2011 12:53:27 +0100 Subject: [PATCH 28/36] Update cheatsheets/index.md --- cheatsheets/index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 07200d71b0..ffe5a5931f 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -233,5 +233,6 @@ about: Thanks to Brendan O'Connor, this cheat |

For java programmers: Lifted restrictions / Important differences

| |If you are coming from java, you might have gotten used to several restrictions and might not even try to do it in scala because you expect it not to work. here is what does work in scala, but not in java| |`a == b`|this is a null safe call to equals. if you want a check by reference, use "eq" instead of "=="| -|`var x = 0`
`1 to 10 foreach {i => {println("changing x from inside another class");x += i;}`|in java, you cannot access local variables from anonymous classes unless they are final. in scala, you can.| +|`var x = 0`
`1 to 10 foreach {i => {`
`println("changing x from inside another class")`
`x += i`
`}`|in java, you cannot access local variables from anonymous classes unless they are final. in scala, you can.| |`class Foo {def x = "a"}`
`class Bar extends Foo {override val x = "b"}`|parameterless methods can be overridden by readonly fields| +|`def allExceptionsAreEqual = throw new CheckedException`|in scala, you don't need to declare checked exceptions in your method signature. by default, the compiler handles them just like runtimeexceptions. the common case is that a caller doesn't care about exceptions and just lets them propagate up to the top level where they are logged and handled.| From 3debbc3bda0eb276d4ef50892df0e00867109b24 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Mon, 26 Dec 2011 13:15:37 +0100 Subject: [PATCH 29/36] Update cheatsheets/index.md --- cheatsheets/index.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index ffe5a5931f..3bdf9119e8 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -22,6 +22,8 @@ about: Thanks to Brendan O'Connor, this cheat | `def x = "hello world"`|return keyword and return type declaration are optional, but if a method contains return, the return type *must* be specified explicitly. default return value = last value in code block. |`def iAcceptVarArgs(i:Int,s:String,d:Double*) = {...}`|method accepting varargs| |`def x = {def y = 7;y}` | nested declarations are possible| +|

Primitive types

| +|`Byte, Char, Boolean, Double, Float, Long, Int, Short`|Primitive types. These are automatically boxed or unboxed, no need to use their java.lang.Number-counterparts anywhere. I use java.lang.Integer and friends in this sheet to be friendly to java devs and because i use their type hierarchy for examples.| |

Syntax details

| |just a few things that didn't fit anywhere else|| |`instance.bar`|bar can be a reading field access or a parameterless method call. scala doesn't make a difference. this means you can easily switch between def and val without the need for a refactoring| @@ -79,7 +81,7 @@ about: Thanks to Brendan O'Connor, this cheat |`1 :: 2 :: 3 :: Nil`|In addition to that, Lists have an alternative syntax| |`1 #:: 2 #:: 3 #:: Stream.empty`|Streams also save an alternative syntax| |prepend, append, union, remove, insertAll... |the usual methods every collection framework offers are present in scala as well| -|if you like to use operators instead, there are some scary but concise ones. you'll need some practice to get them right:
+,++,++=,++:=-,--,--=,:+,:++,:=+,+=:,:++=,++:=, ++=:|method name rules:
"+" means add
"-" means remove
"++" or "--" mean add/remove many elements, not just one
"=" means modify mutable collection or (never both) assign new immutable collection to var. in the reassign case, "=" is appended to the actual method name, just like "int i=0;i+=1" in java.
":" goes on the side of the target collection and is always the first or last character of a method name. if a method end with :=, the method actually ends with : and = means it's a reassignment
if method contains ":" it is an add to an ordered collection, either at the beginning or the end of the collection| +|if you like to use operators instead, there are some scary but concise ones. you'll need some practice to get them right:
+,++,++=,++:=-,--,--=,:+,:++,:=+,+=:,:++=,++:=, ++=:|method name rules:
"+" means add
"-" means remove
"++" or "--" mean add/remove many elements, not just one
"=" either means modify mutable collection or assign new immutable collection to var. in the reassign case, "=" is appended to the actual method name, just like "int i=0;i+=1" in java.
":" goes on the side of the target collection and is always the first or last character of a method name. if a method end with :=, the method actually ends with : and = means it's a reassignment
if method contains ":" it is an add to an ordered collection, either at the beginning or the end of the collection| |`mutableColl += elem`|add element to a collection| |`mutableColl -= elem`|remove element| |`mutableColl ++= elems`|add elements| @@ -167,6 +169,7 @@ about: Thanks to Brendan O'Connor, this cheat |`x match {`|scala can also match on values *inside* x| |`case Some(e) => {...}`|matches of x is a Some. e then exists as a val inside the following code block| |`case List(_, _, 3, y, z) if z == 5 => {...}`|matches if x is a list of size 5 which has a 3 at index 3 and if the fifth element is 5. the fourth element of the list then exists as "y" inside the code block, the last one does as "z".| +|`case _ :: _ :: 3 :: y :: z :: Nil if z == 5 => {...}`|same as above. note: the compiler will refuse to compile matches if they are obviously nonsense. for example x must not be something that cannot be a list for this case to compile. try `5 match {case List(5) => ...}`| |`}`|how the hell did that work? see below| |

Destructuring

| |`object Foo { def unapply(i: Int) = if (i%2==2) Some("even") else None`|we need the reverse of an apply method - unapply.| @@ -236,3 +239,4 @@ about: Thanks to Brendan O'Connor, this cheat |`var x = 0`
`1 to 10 foreach {i => {`
`println("changing x from inside another class")`
`x += i`
`}`|in java, you cannot access local variables from anonymous classes unless they are final. in scala, you can.| |`class Foo {def x = "a"}`
`class Bar extends Foo {override val x = "b"}`|parameterless methods can be overridden by readonly fields| |`def allExceptionsAreEqual = throw new CheckedException`|in scala, you don't need to declare checked exceptions in your method signature. by default, the compiler handles them just like runtimeexceptions. the common case is that a caller doesn't care about exceptions and just lets them propagate up to the top level where they are logged and handled.| +|`List[Int]`|primitives are possible as generic types. no need to use java.lang.Integer| \ No newline at end of file From 6508b0fbc8ea5d721107ea7b1f8eaa50c6f103e1 Mon Sep 17 00:00:00 2001 From: HamsterofDeath Date: Mon, 26 Dec 2011 13:29:35 +0100 Subject: [PATCH 30/36] Update cheatsheets/index.md --- cheatsheets/index.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cheatsheets/index.md b/cheatsheets/index.md index 3bdf9119e8..dd74970d39 100644 --- a/cheatsheets/index.md +++ b/cheatsheets/index.md @@ -48,9 +48,11 @@ about: Thanks to Brendan O'Connor, this cheat | `class C(val x: R)`
`var c = new C(4)`
`c.x` | constructor params - exposed as public fields | | `class C(var x: R) {`
`assert(x > 0, "positive please") //class body = constructor`
`var y = x // public field`
`val readonly = 5 // readonly field`
`private var secret = 1 // private field`
`def this = this(42) // alternative constructor`
`}`|simple example covering the common use cases. note: all alternative constructors must call the main constructor declared at the class declaration. this is it is impossible to forget to initialize a field by constructor overloading.| | `new{ ... }` | anonymous class. more later (see implicits)| -| `abstract class D { ... }` | define an abstract class. (non-createable) | +|`new Foo {...}`|anonymous subclass of Foo. Foo might be a class or a trait| +| `abstract class D { ... }` | define an abstract class. (non-createable, you have to create a subclass) | | `class C extends D { ... }` | define an inherited class. | | `class D(var x: R)`
`class C(x: R) extends D(x)` | inheritance and constructor params) +|`abstract class Foo {def bar:String}`|skipping the body of a method or value of a val makes the method/val abstract. no need for an "abstract" keyword. overriding an abstract def or val doesn not require an "override" keyword. overriding a non abstract def or val does.| | `classOf[String]` | class literal. | | `x.isInstanceOf[String]` | type check (runtime) | | `x.asInstanceOf[String]` | type cast (runtime) | From 7aa0521f877d59656154a3d82f5d6c644730988a Mon Sep 17 00:00:00 2001 From: wuhaixing Date: Wed, 28 Dec 2011 18:30:08 +0800 Subject: [PATCH 31/36] Update index.md --- index.md | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 242 insertions(+), 2 deletions(-) diff --git a/index.md b/index.md index 13ba6fe844..cd4669e9e0 100644 --- a/index.md +++ b/index.md @@ -1,4 +1,244 @@ --- -layout: frontpage -title: Scala Documentation +layout: cheatsheet +title: Scalacheat +by: (initial version: Brendan O'Connor) HamsterofDea +about: Thanks to Brendan O'Connor, this cheatsheet aims to be a quick reference of Scala syntactic constructions. Licensed by Brendan O'Connor under a CC-BY-SA 3.0 license. Pimped by HamsterofDeath who doesn't care about the license and just wants to help scala to spread :) --- + +###### Contributed by {{ page.by }} + +|note: "this is a lie" means i gave a simplified explanation and left out details which will be covered later | | +| ------ | ------ | +|

基本声明

| | +| `var x = 5`
`x = 6` | 可变变量, 其值可修改 | +| `val x = 5`
Bad `x=6` | 不可变, 不能修改其值 | +| `var x: Double = 5` | 明确类型. 如果未说明,编译器会自己决定 (more later) | +| `var x: Double = 5;val y = 42` | 本行最后一条语句的分号是可选的 | +| `var x = {5}`
`var x = {1+2}` | 也可以用表达式的结果赋值 | +| `def x:String = return "hello world"` | 声明方法 | +| `def x(foo:String):String = return foo+"hello world"` | 声明带有简单参数的方法 | +| `def x(foo:String, bar:String):String = return foo+"hello world"+bar` | 声明带有两个参数的方法 | +| `def x:String = {`
`val x = 1`
`return "hello world"+1`
`}` | 多行语句需要用 {} 括起来 | +| `def x = "hello world"`|关键字 return 和返回类型的声明可选, 但如果方法中有 return, *必须* 明确指定返回类型. 默认的返回值是代码中最后一条语句的值(所以别随便移动最后一条语句哦). +|`def iAcceptVarArgs(i:Int,s:String,d:Double*) = {...}`|参数数量可变的方法| +|`def x = {def y = 7;y}` | 可以在方法内声明方法| +|

基础类型

| +|`Byte, Char, Boolean, Double, Float, Long, Int, Short`|基础类型. 他们会自动的 boxed 或 unboxed, 不需要再用对应的java.lang.Number. 我在这里用java.lang.Integer们及其类型结构完全是为了java开发人员着想.| +|

语法细节

| +|不知道该放哪的一些内容|| +|`instance.bar`|bar 可能是一个field访问,或者一个无参方法调用. scala 里面两者是没有区别的. 因此在 def 和 val 之间你可以根据个人喜欢选择| +|`instance.bar()`|for method calls, you can add (). by convention, methods without () don't change any states and just return a calculated value. methods with () are called for they effects, for example changing a value, printing something on the console and so on| +|`instance bar`|you can skip the "." if it is obvious to the compiler what you mean. humans and the compiler usually agree if there is an instance on the left and a method of that instance on the right. this is useful for DSLs| +|`println {"hello world"}`|if a method has one parameter, you can also pass a block instead of using (). also useful for DSLs| +|

Not so basic declarations

| | +| `val x = {`
`class y(val z: String)`
`new y("hello").z`
`}`
`val foo = new y("does not work outside the block above")`| everything can be nested in anything, but everything can only be accessed in its scope| +| `lazy val x = expensiveOperation()`|the expensive operation is executed once as soon as the value of x is needed, not before| +| `def method(a:String = "hello", b:String = "world") = a+" "+b`|method will default values| +| `method("goodbye")`|call to method above, unspecificed parameters will get default values. returns "goodbye world"| +| `method(b = "friend")`|call to method above, explicitly passes a string to b. a defaults to "hello". returns "hello friend"| +|`def method(param: => String)`|"=>" means that when the method is called, the parameter is wrapped in a function which is executed when accessed. the string is evaluated every time when needed (see Iterator.continually), but not before. the value is not cached, but you can pass a lazy val to make it cached.| +|`def method(s:String)(i:Int)`|method with multiple parameter lists| +|`val intermediate = method("hello")`
`intermediate(5)`|why? because you can apply one parameter list at once and the next ones later and pass "the incomplete call" around. in java, you would use a builder for this.| +|

Declarations related to OO

| | +| `class Foo`| class declaration - nested declaration also possible| +| `class Foo(var x:String, val y:Int)`| class declaration with 2 public fields, one mutable, one immutable. constructor is automatically generated. only new Foo("1",2) is possible| +| `class Foo {`
`var x = 5`
`val y = 6`
`}`|class like above, but with default constructor, only new Foo() is possible| +| `class Foo {def x = 5}`|class with default constructor and one method| +| `class C(x: R)` _same as_
`class C(private val x: R)`
`var c = new C(4)` | constructor params - automatically turn into private fields if used after construction. if not, the compiler doesn't generate fields for the params| +| `class C(val x: R)`
`var c = new C(4)`
`c.x` | constructor params - exposed as public fields | +| `class C(var x: R) {`
`assert(x > 0, "positive please") //class body = constructor`
`var y = x // public field`
`val readonly = 5 // readonly field`
`private var secret = 1 // private field`
`def this = this(42) // alternative constructor`
`}`|simple example covering the common use cases. note: all alternative constructors must call the main constructor declared at the class declaration. this is it is impossible to forget to initialize a field by constructor overloading.| +| `new{ ... }` | anonymous class. more later (see implicits)| +|`new Foo {...}`|anonymous subclass of Foo. Foo might be a class or a trait| +| `abstract class D { ... }` | define an abstract class. (non-createable, you have to create a subclass) | +| `class C extends D { ... }` | define an inherited class. | +| `class D(var x: R)`
`class C(x: R) extends D(x)` | inheritance and constructor params) +|`abstract class Foo {def bar:String}`|skipping the body of a method or value of a val makes the method/val abstract. no need for an "abstract" keyword. overriding an abstract def or val doesn not require an "override" keyword. overriding a non abstract def or val does.| +| `classOf[String]` | class literal. | +| `x.isInstanceOf[String]` | type check (runtime) | +| `x.asInstanceOf[String]` | type cast (runtime) | +|`case class Foo; case object Bar`|the keyword "case" makes the compiler generate equals & hashcode methods for that class. also, constructor params are always public readonly fields| +|

Declaring functions

| | +| `(i:Int) => i+1`|creates a function.| +| `var func = (i:Int) => i+1`|creates a function and stores it in a variable| +| `func(5)`|executing the function above| +| `def func = (i:Int) => i+1`|creates a function each time the method is called and returns that function, not i+1| +|`val func:(Int) => String = (i:Int) => i.toString`|just so you know the syntax of a type of a function :)| +|`def takesFunction(f:(Int) => String) = f(5)`| method that takes the function above as a parameter and calls it. compiler figures out the return type "string" for you.| +|`def method(i:Int) = t.toString;val func = method _`|appending an "_" converts any method into a function| +|`takesFunction(method)`|is also possible, the compiler does the conversion for you in obvious cases| +|`def method(s:String)(s2:String) = s+" "+s2`
`val intermediate:(String)=>String = method("hello")`
`intermediate("world")`|parameter lists revisited: the intermediate, "incomplete method calls" are functions. the result of the last call is "hello world"| +|`func(5)`
`func.apply(5)`|what you are actually calling is the apply-method of a function instance, but you don't have to explicitly write that. if no method name is given, the compiler assumed you want to call "apply"| +|`def createFunction = (i:Int) => i+1`
`createFunction(5)`|if you have read the syntax section above, you can figure out what happens here. first, createFunction is called without () and without a parameter. then, 5 is applied to the apply method of the *result* of createfunction| +|

Return types and type inference

| | +| `val x = "hello"`|the compiler always picks the most specific type possible, in this case java.lang.String| +| `val x:Serializable = "hello"`|you can always specify a more general one| +| `def x {print("hello world")}` | method without "=" means the method has no return type/return type is void (this is a lie) | +| `def x:Unit = {...}`
`def x() {...}`|leaving out the "=" at a method declaration is the same as specifying "Unit"| +| `val blocks = {{{{5}}}}`|every block has a return type that is passed back to the next outer block| +| `val block = if (a) foo else bar`|almost everything is an expression and thus, has a return type. this includes if-else-structures| +|`def x = {`
`if (System.currentTimeMillis() % 2 == 0) Integer.valueOf(1) else java.lang.Double.valueOf(2)`
`}`|here, the compiler picks the most specific supertype of both Integer and Double which is java.lang.Number (this is a lie)| +|`def x(i:Int):Int = if (i==0) 1 else i*x(i-1)`|recursive methods need an explicit return type. fail.| +|

Scala Collections

| | +|`1 to 3, Set(1,2,3), Buffer(1,2,3), ArrayBuffer(1,2,3), ListBuffer(1,2,3), List(1,2,3), Array(1,2,3),Vector(1,2,3), Map(1 -> "a", 2 -> "b")`|simple collection creations. scala has mutable and immutable collections.| +|`1 :: 2 :: 3 :: Nil`|In addition to that, Lists have an alternative syntax| +|`1 #:: 2 #:: 3 #:: Stream.empty`|Streams also save an alternative syntax| +|prepend, append, union, remove, insertAll... |the usual methods every collection framework offers are present in scala as well| +|if you like to use operators instead, there are some scary but concise ones. you'll need some practice to get them right:
+,++,++=,++:=-,--,--=,:+,:++,:=+,+=:,:++=,++:=, ++=:|method name rules:
"+" means add
"-" means remove
"++" or "--" mean add/remove many elements, not just one
"=" either means modify mutable collection or assign new immutable collection to var. in the reassign case, "=" is appended to the actual method name, just like "int i=0;i+=1" in java.
":" goes on the side of the target collection and is always the first or last character of a method name. if a method end with :=, the method actually ends with : and = means it's a reassignment
if method contains ":" it is an add to an ordered collection, either at the beginning or the end of the collection| +|`mutableColl += elem`|add element to a collection| +|`mutableColl -= elem`|remove element| +|`mutableColl ++= elems`|add elements| +|`mutableColl --= elems`|remove elements| +|`elem +=: mutableColl`|adds element at the beginning of a collection| +|`mutableColl :+= elem`|adds element at the end of a collection| +|`mutableColl(0) = 1`|write access by index on mutable collections| +|`coll(0)`|read access by index| +|`coll - elem`|create new collection that has all elements of coll except elem| +|`coll ++ elems`|create new collection that has all elements of coll and elems| +|`coll -- elems`|create new collection that has all elements of coll except elems| +|`coll :+ elem`|create new collection that has all elements of coll and elem at the end| +|`elem +: coll`|create new collection that has all elements of coll and elem at the beginning| +|`immutableColl += elem`
`immutableColl -= elem`
`immutableColl ++= elems`
`immutableColl --= elems`
`elem +=: immutableColl`
`immutableColl :+= elem`|same as the operations without "=", but works only if "immutableColl is a var, not a val. the created collection is assigned to "immutableColl".| +|`def isEven(i:Int= if (i%2==0) true else false`
`val evenNumbers:List[Int] = List(1,2,3,4).filter(isEven)`|scala collections are a major epic win. they have ~100 methods which operate on the data of a collection and there is *absolutely nothing* you cannot do with them.| +|`hashmap.getOrElseUpdate(key, methodThatCreatesTheValueInCaseItDoesNotExist)`|admit it, you wanted to do this in java for at least a decade| +|`val evenNumbers:List[Int] = List(1,2,3,4).filter((i:Int)=> i%2==0)`|same as above, just shorter| +|`val evenNumbers = List(1,2,3,4).filter(i => i%2==0)`|same as above, just shorter. you can skip the () if there is only one parameter. you can also skip the type of the parameter(s) because it can be inferred from the usage| +|`val evenNumbers = List(1,2,3,4).filter(_ % 2 == 0)`|same as above, just shorter. you can skip part before "=>" if you use a parameter only once and replace the parameter usage by "_"| +|`val doubleNumbers = List(1,2,3,4).map(_ * 2)`|for the non functional programmers: map means convert| +|`listOfManyPersons.filter(_.hasChildren).map(_.getChildren)`|collection operations can be chained. you can do anything without loops and conditions which makes your code very easy to read| +|`List(1,2,3,4,5).foreach(println)`|do something with every element| +|`List(1,2,3,4,5).par.filter(_ % 2 == 0)`|is executed in parallel just like that| +|`List(1).toSet.toArray.toBuffer.iterator.toStream.toSeq`|conversions are easy| +|`Iterator.continually(randomNumber)`|collections and iterators can also be created from functions and methods| +|`Iterator.continually(randomNumber).take(100).max`|highest of 100 random numbers. again: there are methods for everything you can possibly imagine. many are taking functions so the flexibility is epic :)| +|`Iterator.continually(randomThings).take(100).maxBy(comparisonFunction)`|highest of 100 random things. as above, but can be used for anything.| +|

The power of collections and functions

| +| using closures, it is possible to avoid repetitions of boilerplate - instead you pass a function to a method that hides the boilerplate. apart from filter and map, two other epic wins are reduce and fold.| +|`List(1,2,3,4,5).reduce((i,i2) => i+i2)`|result: ((((1+2)+3)+4)+5). in human speech, it takes 2 elements and merges them into one. imagine the collection turning from 1,2,3,4,5 into 3,3,4,5. then repeat:6,4,5 -> 10,5 -> 15| +|`List(1,2,3,4,5).reduce(_ + _)`|same as above, using "_" for the first and second parameter| +|`List(1,2,3,4,5).fold(0)((sumSoFar,element) => sumSoFar+element)`|same as above, but fold uses an explicit start value| +|`List(1,2,3,4,5).fold(0)(_ + _)`|same as the fold above, just shorter| +|`"comma separated numbers: " + List(1, 2, 3, 4, 5).fold("")(_ + ", " + _)`|finally, you won't have to fiddle around with the last "," anymore!| +|in java this would all look like:
`Acc acc = ?;`
` for (T t: coll) {if (acc==null) {acc = t;} else {acc = doStuff(acc,t);}}`|this is boilerplate code you can avoid *every single time!*. write only what (doStuff) should happen, not "what and how" (boilerplate code + doStuff).| +|where else could you save boilerplate? think about it!
try-catch-finally. define your error handling once, and just inject your logic there. no need to copy & paste your try-catch blocks anywhere +|

Generics

| +| `def foo[BAR](bar:BAR):BAR = bar`|simple type parameter, can be anything| +| `def foo[BAR <: java.lang.Number](bar: BAR) = bar.doubleValue() + 5`|upper bound, BAR must be a java.lang.Number or a subclass of it| +| `def foo[BAR >: java.lang.Number](bar: BAR) = bar`|lower bound, type must be java.lang.Number or a superclass of it, but not a subclass of java.lang.Number. note that you can still pass a double, but the type parameter and therefore the return type will be java.lang.Number. the bound applies to the type parameter itself, not the type of the parameter that is passed to the function| +|`val strings:List[String] = List("hello","generics")`
`val objects:List[java.lang.Object] = strings`|in scala, type parameters of collections are covariant. this means they "inherit" the inhertance relations of their type parameters. in java, have to do an ugly cast:
`List ints = new ArrayList()`;
`List numbers = ((List`val func:(String) => java.lang.Number`|the return type is +, the parameter is -, so the function can be replaced by one declared like
`val func2:(java.lang.Object) => java.lang.Integer`
Think about it. a function that can take any object can also take a string. a function that returns an integer automatically returns a number, so the second one can replace the first one in every possible case.| +|`def foo[A, B[A]] (nested: B[A])`|nested type parameters are possible. nested must be of a type that has a type parameter. for example, you could pass a List[Int]| +|`def foo[A, B, C <: B[A]](nested: C))`|same as above, using an alias for B[A] named C| +|`def foo[C <: Traversable[_]] (nested: C) = nested.head`|if there is no need to access the inner type explicitly, it can be replaced by an _. in this example, the compiler infers that the return type must be whatever _ is, so the actual return type depends on the call site.| +|`foo(List(5))`|call to the method above, returns an Int| +|`def foo[A: Manifest] {val classAtRuntime = manifest[A].erasure; println(classAtRuntime);}`|Adding ":Manifest" will make the compiler add magic so you can get the type parameter at runtime via `manifest[TYPEPARAM]`| +|`foo[String]`|call to method above, prints "class java.lang.String"| +|`def foo[A <: Bar with Serializable with Foobar]`|A must be a subtype of Bar, implement Serializable and also Foobar at the same time| +|

Option aka "Avoid NullPointerExceptions with type safety"

+|`def neverReturnsNull:Option[Foo] = ....`|in scala, you can use the type system to tell the caller of a method whether or not "null" is a valid return or parameter value. the way scala offers is "Option". you can follow a simple convention: if a parameter or return type can be null, wrap it in an Option instead.| +|`if (neverReturnsNull.isEmpty) fail(); else success(neverReturnsNull.get);`|this forces the caller to check for null explicitly.| +|`val modified = neverReturnsNull.map(notNullInHere => doStuffAndReturnNewResult(notNullInHere)`|you can use options like collections. the conversion/mapping function is applied to the contained value if there is one.| +|example:
`val maybeString:Option[String] = ....`
`val mayBeNumber:Option[Int] = maybeString.map(Integer.parseInt)`|this is perfectly safe (let's assume that the string can be parsed, we ignore exceptions here). if there was a string, there now is a number. if there was an empty option, we still have that empty option. (all empty options are actually the same instance)| +|`val emptyOption:Option[Foo] = None`|None is our empty option singleton. by type system magic, it is a subclass of any option and can therefore replace any option.| +|`val filledOption:Option[Foo] = Some(new Foo)`|Some(x) creates an option around x. if you pass null, None is returned| +|`val unsafelyAccessed = option.get`|the compiler does not force you to check if an option is filled| +|`val safelyAccessed = option.getOrElse(bar)`|gets the content of the option or "bar" if the option is empty| +|`val firstNonEmptyOption = option.orElse(option2).orElse(option3)`|no need for if-else| +|

Objects

| +|`object Foo {val bar = "hello"}`|declared like a class, but "simply exists", similar to "static" in java. however, it is a real singleton so it can be passed around as an object.| +|`Foo.bar`|field access and method callswork like "Foo" is a val pointing at the object instance. or in java terms "just like static stuff"| +|`object Foo {def apply(s:String) = Integer.parseInt(s)}`|the apply-shortcut works everywhere, Foo("5") becomes Foo.apply("5"). remember Some(x)? it was the same here. +|`class Foo;object Foo`|this is possible. the object Foo is then called a companion object.| +|`object Foo {def apply(i:Int) = new Foo(i+1)}`|you can use methods in the object Foo as factory methods to keep the actual constructor nice and clean| +|`def apply[A](x: A): Option[A] = if (x == null) None else Some(x)`|this is what happens when you call Some(x)| +|

Tuples

| +|`val x:(Int, Int) = (1,2)`|Sometimes, you want to group things together and pass them around as one object, but creating a class for that would be overkill| +|`x._1`|access the first element of a tuple| +|`def takesTuple(p:(Int, String) {...}`|method accepting a tuple| +|`takesTuple(5,"hello)`|(5, "hello") could be 2 parameters or a tuple. the compiler is smart enough to figure out you meant the tuple one because it looks at the type signature of "takesTuple".| +|`takesTuple((5,"hello))`|same as above, but explicitly creating the tuple| +|`coll zip coll2`|creates a single collection which contains tuples which contain values from coll and coll2, matching by index. for example `List(1,2) zip (List("a","b")` becomes `List((1,"a"),(2,"b"))` +|

Pattern matching

| +|`x match {`|scala has a very powerful switch| +|`case "hello" => {...}`|gets executed if x equals "hello". is tested via equals +|`case s:String => {...}`|gets executed if x is any string. s then exists in the code block as a val. +|`case i:Int if i < 10 => {...}`|gets executed if x is any Int < 10. i then exists in the code block as a val. +|`case 11 *pipe* 12 *pipe* 13 => {...}`|matches on more than one value. how to escape the pipe character in here?| +|`case _ => `|default case, always matches| +|`}`| these were just the boring cases :)| +|`x match {`|scala can also match on values *inside* x| +|`case Some(e) => {...}`|matches of x is a Some. e then exists as a val inside the following code block| +|`case List(_, _, 3, y, z) if z == 5 => {...}`|matches if x is a list of size 5 which has a 3 at index 3 and if the fifth element is 5. the fourth element of the list then exists as "y" inside the code block, the last one does as "z".| +|`case _ :: _ :: 3 :: y :: z :: Nil if z == 5 => {...}`|same as above. note: the compiler will refuse to compile matches if they are obviously nonsense. for example x must not be something that cannot be a list for this case to compile. try `5 match {case List(5) => ...}`| +|`}`|how the hell did that work? see below| +|

Destructuring

| +|`object Foo { def unapply(i: Int) = if (i%2==2) Some("even") else None`|we need the reverse of an apply method - unapply.| +|`val Foo(infoString) = 42`|here, 42 is passed to unapply. if the result is an option, it's value is now stored in "infoString"| +|`42 match {case Foo(infoText) => {...}}`|if some is returned, the match is considered positive and the options value is bound to a val| +|`42 match {case Foo("even") => {...}}`|or it is tested for equality against a given value or instance| +|`41 match {case Digits(a,b) if (a == 4) => {...}}`|if the returned option contains a tuple instead of a single value, the expected happens: we now can access all the tuples fields| +|one more thing:
`unapplySeq(foo:Foo):Option[Seq[Bar]]`|like unapply, but offers special features for matching on sequences| +|`val List(a,b@_*) = List("hello","scala","world")`|a = "hello", b = List("scala", "world")| +|`val a::tl = List("hello", "scala", "world"`|same as above using alternative list syntax| +|`val List(a,_*) = List("hello","scala","world")`|sams as above, but discards the last 2 elements, b does not exist| +|Note: for case classes, an unapply method is automatically generated| +|

Traits

| +|`trait Foo {`|Like a java interface, but more powerful. you can:| +|`def getBar():Bar`|define abstract methods like in a java interface| +|`def predefinedMethod(s:String) = "hello world"`|add non-abstract methods as well. a good example is the Ordered-trait. is expects you to implement a compare-method and delivers 4 other methods (<, >, <=, >=) which already come with an implementation based on compare| +|`val someVal = "someString"`|traits can also contain fields| +|`}`| but that's not all!| +|`trait Plugin extends java.lang.Object {`|a trait can "extend" any existing class or trait. the difference to the trait Foo above is that our Plugin here is restricted to classes which it extends. in this case java.lang.Object. why might such a thing be useful?| +|`override int hashcode = {....}`
`override int equals(other:Object) = {....}`|you can override a method of the class the trait extends. you can selectively replace or extend implementations of existing methods by adding traits. this way, you can say "these 5 classes should use *this* implementation of method foo" instead of manually overriding the method in each class| +|`override boolean add(t:T) = {`
`println(t +" is about to be added to the collection")`
`super.add(t)`
`}`|this is useful for stuff like logging. you can also use this to add features to specific classes. for example, there is a MultiMap-trait in scala which can be attached to maps having sets as values. it adds a addBinding- and removeBinding-methods that are based on the original put/remove-methods and handle the details| +|`}`|these traits are called mixins. a class can have more than one mixin, and they can also override each other. from inside the trait, "super" refers to whatever they extend.| +|`new Foo extends FirstTrait with BarTrait with SomeOtherTrait`|create a new instance of foo implementing 3 traits. the first one is extended, the next n are "withed".| +|`class Foo extends BarTrait`|declaring a class which implements Bar directly| +|`class Foo extends BarTrait with Serializable`|first extends, then with| +|`class A extends B with C with D with E`|inside E, super refers to D. inside D, super refers to C, and so on. keep this in mind when overriding the same method with different traits which call they supers.| +|

packages

| | +| `import scala.collection._` | wildcard import. | +| `import scala.collection.Vector`
`import scala.collection.{Vector, Sequence}` | selective import. | +| `import scala.collection.{Vector => Vec28}` | renaming import. | +| `import java.util.{Date => _, _}` | import all from java.util except Date. | +| `package pkg` _at start of file_
`package pkg { ... }` | declare a package. | +|

control constructs

| | +| `if (check) happy else sad` | conditional. | +| `if (check) happy` _same as_
`if (check) happy else ()` | conditional sugar. | +| `while (x < 5) { println(x); x += 1}` | while loop. | +| `do { println(x); x += 1} while (x < 5)` | do while loop. | +| `import scala.util.control.Breaks._`
`breakable {`
` for (x <- xs) {`
` if (Math.random < 0.1) break`
` }`
`}`| break. ([slides](http://www.slideshare.net/Odersky/fosdem-2009-1013261/21)) | +| `for (i <- 1 to 10 {doStuffWith(i)}`|most basic "for loop". actually it's not a loop but the compiler turns it into `1 to 10 foreach {i => *block content*}. and it is not called for loop, but for comprehension. it's a higher level construct - loops are low level.| +| `for (i <- 1 to 10 if i % 2 == 0) {}`|conditions are possible| +| `for (i <- 1 to 10;i2 <- 10 to 10) {println(i+i2)}`|no need for nested fors| +| `val evenNumbers = for (i <- 1 to 10) yield (i*2)`|yield means "the loop should return that". in this case, you get all even numbers from 2 to 20| +| `for (x <- xs if x%2 == 0) yield x*10` _same as_
`xs.filter(_%2 == 0).map(_*10)` | what you write, and what the compiler does | +| `for ((x,y) <- xs zip ys) yield x*y` | pattern matching works in here | +|

Implicits

| +|`implicit`|mystic keyword. can be attached to vals, vars, defs and objects and method parameters| +|`def parseInt(s:String) = Integer.parseInt(s)`|simple string -> int method| +|`implicit def parseInt(s:String) = Integer.parseInt(s)`|implicit string -> int method. it still can be used as a normal method, but it has one special feature| +|`val i:Int = "42"`|if there is an implicit method in scope which can convert a "wrong" type (string 42) into a "correct" one, the compiler automatically uses it. the code becomes `val i = parseInt("42")`| +|`implicit def attachMethod(i:Int) = new {def tenTimes = i*10}`|another implicit conversion from "Int" to an anonymous class having a method "tenTimes". the returnes class doesn't need a name.| +|using several implicit conversions attaching methods in a chain, combined with scala's .-inference, you can create code that looks like a text that acually makes sense to a human. for a great example, take a look at ScalaTest| +|`val i:Int = 42`
`println(i.tenTimes)`|if there is an implicit method which can convert a type not having a method into one having that method - the compiler uses that conversion to make your code valid. this is a common pattern to attach methods to objects| +|`abstract class GenericAddition[T] {def add(t:T,t2:T):T}`
`implicit object IntAddition extends GenericAddition[Int] {def add(t:Int, t2:Int) = t+t2}`|an implicit object| +|`def addTwoThings[T](t:T, t2:T)(implicit logicToUse:GenericAddition[T]) = logicToUse.add(t,t2)`|method using a second implicit parameter list| +|`addTwoThings(1,2)(IntAddition)`|call to method above. so far, no magic involved.| +|`addTwoThings(1,2)`|if a matching implicit object is in scope, it will automatically be used. you don't have to pass it yourself. it's a nice feature to separate the "what" from "how" and let the compiler pick the "how"-logic automatically.| +|

Abstract types

| +|`type Str = String`|simple alias. Str and String are equal for the compiler| +|`type Complex[A] = (String,String,String,A)`|if you are too lazy to write a complex type expression because a part of the expression is constant, use this. "Complex" is called a type contructor, and A is its parameter. you can declare something as Complex[Int] and it is considered equal to any Tuple having the type (String, String, String, Int)| +|`type StructualType = {def x:String;val y:Int}`|this is a structural type. is allows type safe duck-typing. if you declare a method that accepts "StructuralType", is accepts all objects that have a method x:String and a field y:Int. at runtime, reflection is used for this, but you cannot mess it up at compile time like in dynamically types languages.| +|`class X {type Y <: Foo}`|types can be clared in classes and traits and overridden in subclasses. upper and lower bounds apply here, too.| +|`type X = {type U = Foo}`|types can be nested. this is useful for things that are too big to explain here, but i can tease you a bit: you can declare a type that "is an int but with an attached subtype". at runtime, everything is still an int, but at compile time, userids, inches, the number of hairs - everything would have a different type and you would get compile errors if you tried to mix them. for strings, you could tag them with an "is resource key", "is already resolved" or "is already html-escaped"-type to avoid doubly resolved or escaped strings. for details, see http://etorreborre.blogspot.com/2011/11/practical-uses-for-unboxed-tagged-types.html +|`this.type`|this refers to the type "this" has. this is pretty useless as long as you are inside "this". but if you use it as a return type, it get's updated once you use a subclass. simple use case: `def cloneOfMe:this.type`. you'll want a subclass to return it's own type, not the parent type.| +|

For java programmers: Lifted restrictions / Important differences

| +|If you are coming from java, you might have gotten used to several restrictions and might not even try to do it in scala because you expect it not to work. here is what does work in scala, but not in java| +|`a == b`|this is a null safe call to equals. if you want a check by reference, use "eq" instead of "=="| +|`var x = 0`
`1 to 10 foreach {i => {`
`println("changing x from inside another class")`
`x += i`
`}`|in java, you cannot access local variables from anonymous classes unless they are final. in scala, you can.| +|`class Foo {def x = "a"}`
`class Bar extends Foo {override val x = "b"}`|parameterless methods can be overridden by readonly fields| +|`def allExceptionsAreEqual = throw new CheckedException`|in scala, you don't need to declare checked exceptions in your method signature. by default, the compiler handles them just like runtimeexceptions. the common case is that a caller doesn't care about exceptions and just lets them propagate up to the top level where they are logged and handled.| +|`List[Int]`|primitives are possible as generic types. no need to use java.lang.Integer| \ No newline at end of file From 21cd8f8812a7ad4defc168004af38fb071a1a7e7 Mon Sep 17 00:00:00 2001 From: wuhaixing Date: Thu, 29 Dec 2011 14:10:08 +0800 Subject: [PATCH 32/36] Update index.md --- index.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/index.md b/index.md index cd4669e9e0..95499f0c6f 100644 --- a/index.md +++ b/index.md @@ -11,7 +11,7 @@ about: Thanks to Brendan O'Connor, this cheat | ------ | ------ | |

基本声明

| | | `var x = 5`
`x = 6` | 可变变量, 其值可修改 | -| `val x = 5`
Bad `x=6` | 不可变, 不能修改其值 | +| `val x = 5`
`x=6` | 不可变, 不能修改其值 | | `var x: Double = 5` | 明确类型. 如果未说明,编译器会自己决定 (more later) | | `var x: Double = 5;val y = 42` | 本行最后一条语句的分号是可选的 | | `var x = {5}`
`var x = {1+2}` | 也可以用表达式的结果赋值 | @@ -27,17 +27,17 @@ about: Thanks to Brendan O'Connor, this cheat |

语法细节

| |不知道该放哪的一些内容|| |`instance.bar`|bar 可能是一个field访问,或者一个无参方法调用. scala 里面两者是没有区别的. 因此在 def 和 val 之间你可以根据个人喜欢选择| -|`instance.bar()`|for method calls, you can add (). by convention, methods without () don't change any states and just return a calculated value. methods with () are called for they effects, for example changing a value, printing something on the console and so on| -|`instance bar`|you can skip the "." if it is obvious to the compiler what you mean. humans and the compiler usually agree if there is an instance on the left and a method of that instance on the right. this is useful for DSLs| -|`println {"hello world"}`|if a method has one parameter, you can also pass a block instead of using (). also useful for DSLs| -|

Not so basic declarations

| | -| `val x = {`
`class y(val z: String)`
`new y("hello").z`
`}`
`val foo = new y("does not work outside the block above")`| everything can be nested in anything, but everything can only be accessed in its scope| -| `lazy val x = expensiveOperation()`|the expensive operation is executed once as soon as the value of x is needed, not before| -| `def method(a:String = "hello", b:String = "world") = a+" "+b`|method will default values| -| `method("goodbye")`|call to method above, unspecificed parameters will get default values. returns "goodbye world"| -| `method(b = "friend")`|call to method above, explicitly passes a string to b. a defaults to "hello". returns "hello friend"| -|`def method(param: => String)`|"=>" means that when the method is called, the parameter is wrapped in a function which is executed when accessed. the string is evaluated every time when needed (see Iterator.continually), but not before. the value is not cached, but you can pass a lazy val to make it cached.| -|`def method(s:String)(i:Int)`|method with multiple parameter lists| +|`instance.bar()`|对于方法调用, 可以加上 (). 依照规范, 不带 () 的方法只进行计算,返回结果,不会改变任何状态.调用带 () 的方法是为了其效果,比如改变一个值,在终端上打印内容等| +|`instance bar`|如果对于编译器来说你的意图很明显,就可以省略 "." 通常人类和编译器都会同意把类实例放左边,它的方法放右边,这对于DSL很有用| +|`println {"hello world"}`|对于单参方法,你可以用一个block代替(). 这个对 DSLs 也很有用| +|

不是那么基本的声明

| | +| `val x = {`
`class y(val z: String)`
`new y("hello").z`
`}`
`val foo = new y("does not work outside the block above")`| 任何东西都可以嵌入其他东西,但只能在其作用域内访问到| +| `lazy val x = expensiveOperation()`|这个昂贵的操作仅在需要x的时候执行, 之前不会| +| `def method(a:String = "hello", b:String = "world") = a+" "+b`|带默认值的方法| +| `method("goodbye")`|调用上面的方法, 未指定的参数会使用其默认值. 返回 "goodbye world"| +| `method(b = "friend")`|调用上面的方法, 明确传入参数b. a 用默认的 "hello". 返回 "hello friend"| +|`def method(param: => String)`|"=>" 的含义是,当调用这个方法时,参数是由一个函数返回的 that when the method is called, the parameter is wrapped in a function which is executed when accessed. the string is evaluated every time when needed (see Iterator.continually), but not before. the value is not cached, but you can pass a lazy val to make it cached.| +|`def method(s:String)(i:Int)`|有多个参数列表的方法| |`val intermediate = method("hello")`
`intermediate(5)`|why? because you can apply one parameter list at once and the next ones later and pass "the incomplete call" around. in java, you would use a builder for this.| |

Declarations related to OO

| | | `class Foo`| class declaration - nested declaration also possible| From 2e1742078d9f9700dd42792d90ddcb16ad3ffe63 Mon Sep 17 00:00:00 2001 From: wuhaixing Date: Tue, 3 Jan 2012 23:58:01 +0800 Subject: [PATCH 33/36] Update index.md --- index.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/index.md b/index.md index 95499f0c6f..dd2587c156 100644 --- a/index.md +++ b/index.md @@ -36,17 +36,17 @@ about: Thanks to Brendan O'Connor, this cheat | `def method(a:String = "hello", b:String = "world") = a+" "+b`|带默认值的方法| | `method("goodbye")`|调用上面的方法, 未指定的参数会使用其默认值. 返回 "goodbye world"| | `method(b = "friend")`|调用上面的方法, 明确传入参数b. a 用默认的 "hello". 返回 "hello friend"| -|`def method(param: => String)`|"=>" 的含义是,当调用这个方法时,参数是由一个函数返回的 that when the method is called, the parameter is wrapped in a function which is executed when accessed. the string is evaluated every time when needed (see Iterator.continually), but not before. the value is not cached, but you can pass a lazy val to make it cached.| +|`def method(param: => String)`|"=>" 的含义是,当调用这个方法时,参数是一个函数的返回值,每次访问这个参数,都要执行此函数进行计算(see Iterator.continually). 计算结果不会被cached, 但可以传递一个lazy val使它cached.| |`def method(s:String)(i:Int)`|有多个参数列表的方法| -|`val intermediate = method("hello")`
`intermediate(5)`|why? because you can apply one parameter list at once and the next ones later and pass "the incomplete call" around. in java, you would use a builder for this.| -|

Declarations related to OO

| | -| `class Foo`| class declaration - nested declaration also possible| -| `class Foo(var x:String, val y:Int)`| class declaration with 2 public fields, one mutable, one immutable. constructor is automatically generated. only new Foo("1",2) is possible| -| `class Foo {`
`var x = 5`
`val y = 6`
`}`|class like above, but with default constructor, only new Foo() is possible| -| `class Foo {def x = 5}`|class with default constructor and one method| -| `class C(x: R)` _same as_
`class C(private val x: R)`
`var c = new C(4)` | constructor params - automatically turn into private fields if used after construction. if not, the compiler doesn't generate fields for the params| -| `class C(val x: R)`
`var c = new C(4)`
`c.x` | constructor params - exposed as public fields | -| `class C(var x: R) {`
`assert(x > 0, "positive please") //class body = constructor`
`var y = x // public field`
`val readonly = 5 // readonly field`
`private var secret = 1 // private field`
`def this = this(42) // alternative constructor`
`}`|simple example covering the common use cases. note: all alternative constructors must call the main constructor declared at the class declaration. this is it is impossible to forget to initialize a field by constructor overloading.| +|`val intermediate = method("hello")`
`intermediate(5)`|why? 因为你可以先传递一个参数列表, 稍后再提供另一个。可以绕过 "不完整的调用" . 在java中,你得为这个创建个builder.| +|

与OO相关的声明

| | +| `class Foo`| class 声明 - 可嵌套| +| `class Foo(var x:String, val y:Int)`|带有2个公开field 的 class 声明, 一个可变, 一个不可变. 构造函数式自动生成. 只能用new Foo("1",2)| +| `class Foo {`
`var x = 5`
`val y = 6`
`}`|和上面那个差不多 , 但是用的是默认函数, 也就是new Foo()| +| `class Foo {def x = 5}`|默认的构造函数,声明了方法x| +| `class C(x: R)` _等同于_
`class C(private val x: R)`
`var c = new C(4)` | 构造参数 - 如果没有明确val,自动转化成私有field. | +| `class C(val x: R)`
`var c = new C(4)`
`c.x` | 构造参数 - 明确val,作为公开 fields | +| `class C(var x: R) {`
`assert(x > 0, "positive please") //class body = constructor`
`var y = x // 公开 field`
`val readonly = 5 // 只读 field`
`private var secret = 1 // 私有 field`
`def this = this(42) // 替代构造函数`
`}`|包含常用情况的简单例子. 注: 所有的替代构造函数必须调用类声明中声明的主构造函数.以确保不会因为构造函数重载忘记初始化某个field.| | `new{ ... }` | anonymous class. more later (see implicits)| |`new Foo {...}`|anonymous subclass of Foo. Foo might be a class or a trait| | `abstract class D { ... }` | define an abstract class. (non-createable, you have to create a subclass) | From bafe89fa6245fd5f578dba7886a4fdad07db3af6 Mon Sep 17 00:00:00 2001 From: wuhaixing Date: Wed, 4 Jan 2012 00:25:19 +0800 Subject: [PATCH 34/36] Update index.md --- index.md | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/index.md b/index.md index dd2587c156..1a045fd4d2 100644 --- a/index.md +++ b/index.md @@ -47,17 +47,17 @@ about: Thanks to Brendan O'Connor, this cheat | `class C(x: R)` _等同于_
`class C(private val x: R)`
`var c = new C(4)` | 构造参数 - 如果没有明确val,自动转化成私有field. | | `class C(val x: R)`
`var c = new C(4)`
`c.x` | 构造参数 - 明确val,作为公开 fields | | `class C(var x: R) {`
`assert(x > 0, "positive please") //class body = constructor`
`var y = x // 公开 field`
`val readonly = 5 // 只读 field`
`private var secret = 1 // 私有 field`
`def this = this(42) // 替代构造函数`
`}`|包含常用情况的简单例子. 注: 所有的替代构造函数必须调用类声明中声明的主构造函数.以确保不会因为构造函数重载忘记初始化某个field.| -| `new{ ... }` | anonymous class. more later (see implicits)| -|`new Foo {...}`|anonymous subclass of Foo. Foo might be a class or a trait| -| `abstract class D { ... }` | define an abstract class. (non-createable, you have to create a subclass) | -| `class C extends D { ... }` | define an inherited class. | -| `class D(var x: R)`
`class C(x: R) extends D(x)` | inheritance and constructor params) -|`abstract class Foo {def bar:String}`|skipping the body of a method or value of a val makes the method/val abstract. no need for an "abstract" keyword. overriding an abstract def or val doesn not require an "override" keyword. overriding a non abstract def or val does.| -| `classOf[String]` | class literal. | -| `x.isInstanceOf[String]` | type check (runtime) | -| `x.asInstanceOf[String]` | type cast (runtime) | -|`case class Foo; case object Bar`|the keyword "case" makes the compiler generate equals & hashcode methods for that class. also, constructor params are always public readonly fields| -|

Declaring functions

| | +| `new{ ... }` | 匿名类. more later (see implicits)| +|`new Foo {...}`|Foo的匿名子类. Foo 可能是 class 或 trait| +| `abstract class D { ... }` | 定义一个抽象 class. (不可实例化, 必须创建其子类) | +| `class C extends D { ... }` | 定义一个继承类. | +| `class D(var x: R)`
`class C(x: R) extends D(x)` | 继承与构造参数) +|`abstract class Foo {def bar:String}`|不带body的方法或没有value的val是抽象的,不需要显示声明 "abstract". 覆盖抽象的 def 或 val 也不需要 "override" 关键字. 但覆盖非抽象的 def 或 val 时必须带有 "override" 关键字.| +| `classOf[String]` | class 字面值. | +| `x.isInstanceOf[String]` | 类型检查 (运行时) | +| `x.asInstanceOf[String]` | 类型转换 (运行时) | +|`case class Foo; case object Bar`|遇到关键字 "case" ,编译器会为其生成 equals & hashcode 方法,并且其构造参数都是只读的公开fields| +|

函数声明

| | | `(i:Int) => i+1`|creates a function.| | `var func = (i:Int) => i+1`|creates a function and stores it in a variable| | `func(5)`|executing the function above| @@ -69,7 +69,7 @@ about: Thanks to Brendan O'Connor, this cheat |`def method(s:String)(s2:String) = s+" "+s2`
`val intermediate:(String)=>String = method("hello")`
`intermediate("world")`|parameter lists revisited: the intermediate, "incomplete method calls" are functions. the result of the last call is "hello world"| |`func(5)`
`func.apply(5)`|what you are actually calling is the apply-method of a function instance, but you don't have to explicitly write that. if no method name is given, the compiler assumed you want to call "apply"| |`def createFunction = (i:Int) => i+1`
`createFunction(5)`|if you have read the syntax section above, you can figure out what happens here. first, createFunction is called without () and without a parameter. then, 5 is applied to the apply method of the *result* of createfunction| -|

Return types and type inference

| | +|

返回类型与类型推断

| | | `val x = "hello"`|the compiler always picks the most specific type possible, in this case java.lang.String| | `val x:Serializable = "hello"`|you can always specify a more general one| | `def x {print("hello world")}` | method without "=" means the method has no return type/return type is void (this is a lie) | @@ -78,7 +78,7 @@ about: Thanks to Brendan O'Connor, this cheat | `val block = if (a) foo else bar`|almost everything is an expression and thus, has a return type. this includes if-else-structures| |`def x = {`
`if (System.currentTimeMillis() % 2 == 0) Integer.valueOf(1) else java.lang.Double.valueOf(2)`
`}`|here, the compiler picks the most specific supertype of both Integer and Double which is java.lang.Number (this is a lie)| |`def x(i:Int):Int = if (i==0) 1 else i*x(i-1)`|recursive methods need an explicit return type. fail.| -|

Scala Collections

| | +|

Scala 集合

| | |`1 to 3, Set(1,2,3), Buffer(1,2,3), ArrayBuffer(1,2,3), ListBuffer(1,2,3), List(1,2,3), Array(1,2,3),Vector(1,2,3), Map(1 -> "a", 2 -> "b")`|simple collection creations. scala has mutable and immutable collections.| |`1 :: 2 :: 3 :: Nil`|In addition to that, Lists have an alternative syntax| |`1 #:: 2 #:: 3 #:: Stream.empty`|Streams also save an alternative syntax| @@ -111,7 +111,7 @@ about: Thanks to Brendan O'Connor, this cheat |`Iterator.continually(randomNumber)`|collections and iterators can also be created from functions and methods| |`Iterator.continually(randomNumber).take(100).max`|highest of 100 random numbers. again: there are methods for everything you can possibly imagine. many are taking functions so the flexibility is epic :)| |`Iterator.continually(randomThings).take(100).maxBy(comparisonFunction)`|highest of 100 random things. as above, but can be used for anything.| -|

The power of collections and functions

| +|

集合与函数的力量

| | using closures, it is possible to avoid repetitions of boilerplate - instead you pass a function to a method that hides the boilerplate. apart from filter and map, two other epic wins are reduce and fold.| |`List(1,2,3,4,5).reduce((i,i2) => i+i2)`|result: ((((1+2)+3)+4)+5). in human speech, it takes 2 elements and merges them into one. imagine the collection turning from 1,2,3,4,5 into 3,3,4,5. then repeat:6,4,5 -> 10,5 -> 15| |`List(1,2,3,4,5).reduce(_ + _)`|same as above, using "_" for the first and second parameter| @@ -120,7 +120,7 @@ about: Thanks to Brendan O'Connor, this cheat |`"comma separated numbers: " + List(1, 2, 3, 4, 5).fold("")(_ + ", " + _)`|finally, you won't have to fiddle around with the last "," anymore!| |in java this would all look like:
`Acc acc = ?;`
` for (T t: coll) {if (acc==null) {acc = t;} else {acc = doStuff(acc,t);}}`|this is boilerplate code you can avoid *every single time!*. write only what (doStuff) should happen, not "what and how" (boilerplate code + doStuff).| |where else could you save boilerplate? think about it!
try-catch-finally. define your error handling once, and just inject your logic there. no need to copy & paste your try-catch blocks anywhere -|

Generics

| +|

泛型

| | `def foo[BAR](bar:BAR):BAR = bar`|simple type parameter, can be anything| | `def foo[BAR <: java.lang.Number](bar: BAR) = bar.doubleValue() + 5`|upper bound, BAR must be a java.lang.Number or a subclass of it| | `def foo[BAR >: java.lang.Number](bar: BAR) = bar`|lower bound, type must be java.lang.Number or a superclass of it, but not a subclass of java.lang.Number. note that you can still pass a double, but the type parameter and therefore the return type will be java.lang.Number. the bound applies to the type parameter itself, not the type of the parameter that is passed to the function| @@ -136,7 +136,7 @@ about: Thanks to Brendan O'Connor, this cheat |`def foo[A: Manifest] {val classAtRuntime = manifest[A].erasure; println(classAtRuntime);}`|Adding ":Manifest" will make the compiler add magic so you can get the type parameter at runtime via `manifest[TYPEPARAM]`| |`foo[String]`|call to method above, prints "class java.lang.String"| |`def foo[A <: Bar with Serializable with Foobar]`|A must be a subtype of Bar, implement Serializable and also Foobar at the same time| -|

Option aka "Avoid NullPointerExceptions with type safety"

+|

Option 即 "类型安全的避免NullPointerException"

|`def neverReturnsNull:Option[Foo] = ....`|in scala, you can use the type system to tell the caller of a method whether or not "null" is a valid return or parameter value. the way scala offers is "Option". you can follow a simple convention: if a parameter or return type can be null, wrap it in an Option instead.| |`if (neverReturnsNull.isEmpty) fail(); else success(neverReturnsNull.get);`|this forces the caller to check for null explicitly.| |`val modified = neverReturnsNull.map(notNullInHere => doStuffAndReturnNewResult(notNullInHere)`|you can use options like collections. the conversion/mapping function is applied to the contained value if there is one.| @@ -146,21 +146,21 @@ about: Thanks to Brendan O'Connor, this cheat |`val unsafelyAccessed = option.get`|the compiler does not force you to check if an option is filled| |`val safelyAccessed = option.getOrElse(bar)`|gets the content of the option or "bar" if the option is empty| |`val firstNonEmptyOption = option.orElse(option2).orElse(option3)`|no need for if-else| -|

Objects

| +|

Objects-对象

| |`object Foo {val bar = "hello"}`|declared like a class, but "simply exists", similar to "static" in java. however, it is a real singleton so it can be passed around as an object.| |`Foo.bar`|field access and method callswork like "Foo" is a val pointing at the object instance. or in java terms "just like static stuff"| |`object Foo {def apply(s:String) = Integer.parseInt(s)}`|the apply-shortcut works everywhere, Foo("5") becomes Foo.apply("5"). remember Some(x)? it was the same here. |`class Foo;object Foo`|this is possible. the object Foo is then called a companion object.| |`object Foo {def apply(i:Int) = new Foo(i+1)}`|you can use methods in the object Foo as factory methods to keep the actual constructor nice and clean| |`def apply[A](x: A): Option[A] = if (x == null) None else Some(x)`|this is what happens when you call Some(x)| -|

Tuples

| +|

Tuples-元组

| |`val x:(Int, Int) = (1,2)`|Sometimes, you want to group things together and pass them around as one object, but creating a class for that would be overkill| |`x._1`|access the first element of a tuple| |`def takesTuple(p:(Int, String) {...}`|method accepting a tuple| |`takesTuple(5,"hello)`|(5, "hello") could be 2 parameters or a tuple. the compiler is smart enough to figure out you meant the tuple one because it looks at the type signature of "takesTuple".| |`takesTuple((5,"hello))`|same as above, but explicitly creating the tuple| |`coll zip coll2`|creates a single collection which contains tuples which contain values from coll and coll2, matching by index. for example `List(1,2) zip (List("a","b")` becomes `List((1,"a"),(2,"b"))` -|

Pattern matching

| +|

模式匹配

| |`x match {`|scala has a very powerful switch| |`case "hello" => {...}`|gets executed if x equals "hello". is tested via equals |`case s:String => {...}`|gets executed if x is any string. s then exists in the code block as a val. @@ -173,7 +173,7 @@ about: Thanks to Brendan O'Connor, this cheat |`case List(_, _, 3, y, z) if z == 5 => {...}`|matches if x is a list of size 5 which has a 3 at index 3 and if the fifth element is 5. the fourth element of the list then exists as "y" inside the code block, the last one does as "z".| |`case _ :: _ :: 3 :: y :: z :: Nil if z == 5 => {...}`|same as above. note: the compiler will refuse to compile matches if they are obviously nonsense. for example x must not be something that cannot be a list for this case to compile. try `5 match {case List(5) => ...}`| |`}`|how the hell did that work? see below| -|

Destructuring

| +|

Destructuring-解构

| |`object Foo { def unapply(i: Int) = if (i%2==2) Some("even") else None`|we need the reverse of an apply method - unapply.| |`val Foo(infoString) = 42`|here, 42 is passed to unapply. if the result is an option, it's value is now stored in "infoString"| |`42 match {case Foo(infoText) => {...}}`|if some is returned, the match is considered positive and the options value is bound to a val| @@ -184,7 +184,7 @@ about: Thanks to Brendan O'Connor, this cheat |`val a::tl = List("hello", "scala", "world"`|same as above using alternative list syntax| |`val List(a,_*) = List("hello","scala","world")`|sams as above, but discards the last 2 elements, b does not exist| |Note: for case classes, an unapply method is automatically generated| -|

Traits

| +|

Traits-特性

| |`trait Foo {`|Like a java interface, but more powerful. you can:| |`def getBar():Bar`|define abstract methods like in a java interface| |`def predefinedMethod(s:String) = "hello world"`|add non-abstract methods as well. a good example is the Ordered-trait. is expects you to implement a compare-method and delivers 4 other methods (<, >, <=, >=) which already come with an implementation based on compare| @@ -198,7 +198,7 @@ about: Thanks to Brendan O'Connor, this cheat |`class Foo extends BarTrait`|declaring a class which implements Bar directly| |`class Foo extends BarTrait with Serializable`|first extends, then with| |`class A extends B with C with D with E`|inside E, super refers to D. inside D, super refers to C, and so on. keep this in mind when overriding the same method with different traits which call they supers.| -|

packages

| | +|

| | | `import scala.collection._` | wildcard import. | | `import scala.collection.Vector`
`import scala.collection.{Vector, Sequence}` | selective import. | | `import scala.collection.{Vector => Vec28}` | renaming import. | @@ -216,7 +216,7 @@ about: Thanks to Brendan O'Connor, this cheat | `val evenNumbers = for (i <- 1 to 10) yield (i*2)`|yield means "the loop should return that". in this case, you get all even numbers from 2 to 20| | `for (x <- xs if x%2 == 0) yield x*10` _same as_
`xs.filter(_%2 == 0).map(_*10)` | what you write, and what the compiler does | | `for ((x,y) <- xs zip ys) yield x*y` | pattern matching works in here | -|

Implicits

| +|

Implicits-隐含

| |`implicit`|mystic keyword. can be attached to vals, vars, defs and objects and method parameters| |`def parseInt(s:String) = Integer.parseInt(s)`|simple string -> int method| |`implicit def parseInt(s:String) = Integer.parseInt(s)`|implicit string -> int method. it still can be used as a normal method, but it has one special feature| @@ -228,14 +228,14 @@ about: Thanks to Brendan O'Connor, this cheat |`def addTwoThings[T](t:T, t2:T)(implicit logicToUse:GenericAddition[T]) = logicToUse.add(t,t2)`|method using a second implicit parameter list| |`addTwoThings(1,2)(IntAddition)`|call to method above. so far, no magic involved.| |`addTwoThings(1,2)`|if a matching implicit object is in scope, it will automatically be used. you don't have to pass it yourself. it's a nice feature to separate the "what" from "how" and let the compiler pick the "how"-logic automatically.| -|

Abstract types

| +|

抽象类型

| |`type Str = String`|simple alias. Str and String are equal for the compiler| |`type Complex[A] = (String,String,String,A)`|if you are too lazy to write a complex type expression because a part of the expression is constant, use this. "Complex" is called a type contructor, and A is its parameter. you can declare something as Complex[Int] and it is considered equal to any Tuple having the type (String, String, String, Int)| |`type StructualType = {def x:String;val y:Int}`|this is a structural type. is allows type safe duck-typing. if you declare a method that accepts "StructuralType", is accepts all objects that have a method x:String and a field y:Int. at runtime, reflection is used for this, but you cannot mess it up at compile time like in dynamically types languages.| |`class X {type Y <: Foo}`|types can be clared in classes and traits and overridden in subclasses. upper and lower bounds apply here, too.| |`type X = {type U = Foo}`|types can be nested. this is useful for things that are too big to explain here, but i can tease you a bit: you can declare a type that "is an int but with an attached subtype". at runtime, everything is still an int, but at compile time, userids, inches, the number of hairs - everything would have a different type and you would get compile errors if you tried to mix them. for strings, you could tag them with an "is resource key", "is already resolved" or "is already html-escaped"-type to avoid doubly resolved or escaped strings. for details, see http://etorreborre.blogspot.com/2011/11/practical-uses-for-unboxed-tagged-types.html |`this.type`|this refers to the type "this" has. this is pretty useless as long as you are inside "this". but if you use it as a return type, it get's updated once you use a subclass. simple use case: `def cloneOfMe:this.type`. you'll want a subclass to return it's own type, not the parent type.| -|

For java programmers: Lifted restrictions / Important differences

| +|

致java程序员: 升腾限定 / 重要差异

| |If you are coming from java, you might have gotten used to several restrictions and might not even try to do it in scala because you expect it not to work. here is what does work in scala, but not in java| |`a == b`|this is a null safe call to equals. if you want a check by reference, use "eq" instead of "=="| |`var x = 0`
`1 to 10 foreach {i => {`
`println("changing x from inside another class")`
`x += i`
`}`|in java, you cannot access local variables from anonymous classes unless they are final. in scala, you can.| From ad065e41278c6ec5170fe1b04ee35627086e2510 Mon Sep 17 00:00:00 2001 From: wuhaixing Date: Wed, 4 Jan 2012 23:42:13 +0800 Subject: [PATCH 35/36] complete function section --- index.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/index.md b/index.md index 1a045fd4d2..b57d8a88f5 100644 --- a/index.md +++ b/index.md @@ -58,17 +58,17 @@ about: Thanks to Brendan O'Connor, this cheat | `x.asInstanceOf[String]` | 类型转换 (运行时) | |`case class Foo; case object Bar`|遇到关键字 "case" ,编译器会为其生成 equals & hashcode 方法,并且其构造参数都是只读的公开fields| |

函数声明

| | -| `(i:Int) => i+1`|creates a function.| -| `var func = (i:Int) => i+1`|creates a function and stores it in a variable| -| `func(5)`|executing the function above| -| `def func = (i:Int) => i+1`|creates a function each time the method is called and returns that function, not i+1| -|`val func:(Int) => String = (i:Int) => i.toString`|just so you know the syntax of a type of a function :)| -|`def takesFunction(f:(Int) => String) = f(5)`| method that takes the function above as a parameter and calls it. compiler figures out the return type "string" for you.| -|`def method(i:Int) = t.toString;val func = method _`|appending an "_" converts any method into a function| -|`takesFunction(method)`|is also possible, the compiler does the conversion for you in obvious cases| -|`def method(s:String)(s2:String) = s+" "+s2`
`val intermediate:(String)=>String = method("hello")`
`intermediate("world")`|parameter lists revisited: the intermediate, "incomplete method calls" are functions. the result of the last call is "hello world"| -|`func(5)`
`func.apply(5)`|what you are actually calling is the apply-method of a function instance, but you don't have to explicitly write that. if no method name is given, the compiler assumed you want to call "apply"| -|`def createFunction = (i:Int) => i+1`
`createFunction(5)`|if you have read the syntax section above, you can figure out what happens here. first, createFunction is called without () and without a parameter. then, 5 is applied to the apply method of the *result* of createfunction| +| `(i:Int) => i+1`|创建一个函数.| +| `var func = (i:Int) => i+1`|创建函数并把它声明为一个变量 func: Int => Int = | +| `func(5)`|执行上面的函数| +| `def func = (i:Int) => i+1`|每次调用方法的时候都创建一个函数并返回该函数,不是i+1 func: Int => Int| +|`val func:(Int) => String = (i:Int) => i.toString`|这样你就了解函数类型的语法了吧 :)| +|`def takesFunction(f:(Int) => String) = f(5)`| 用上面函数类型的函数作为参数的方法,并调用该函数.编译器能推断出返回类型为"string".| +|`def method(i:Int) = t.toString;val func = method _`|在任何方法后面加上 "_" 都可以把他变成一个函数| +|`takesFunction(method)`|这样也行, 当情况很明显的时候,编译器会为你做这种转换| +|`def method(s:String)(s2:String) = s+" "+s2`
`val intermediate:(String)=>String = method("hello")`
`intermediate("world")`|再访参数列表: the intermediate, "非完整方法调用" 是函数. 最终结果是 "hello world"| +|`func(5)`
`func.apply(5)`|实际上是调用了函数实例的apply方法, 只是你不必那么写罢了.如果没有写明方法名,编译器会假定你想调用 "apply" | +|`def createFunction = (i:Int) => i+1`
`createFunction(5)`|如果看过了上面的语法部分, 你应该能明白这发生了什么. 首先, createFunction的调用没有 () 也没有参数. 然后, 5 传递给 creatFunction的返回结果的 apply 方法| |

返回类型与类型推断

| | | `val x = "hello"`|the compiler always picks the most specific type possible, in this case java.lang.String| | `val x:Serializable = "hello"`|you can always specify a more general one| From d16c6414e6fa5e38b535c15ac8e30089fcb02123 Mon Sep 17 00:00:00 2001 From: wuhaixing Date: Fri, 6 Jan 2012 21:42:39 +0800 Subject: [PATCH 36/36] Update index.md --- index.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/index.md b/index.md index b57d8a88f5..29c7e13ec2 100644 --- a/index.md +++ b/index.md @@ -70,14 +70,14 @@ about: Thanks to Brendan O'Connor, this cheat |`func(5)`
`func.apply(5)`|实际上是调用了函数实例的apply方法, 只是你不必那么写罢了.如果没有写明方法名,编译器会假定你想调用 "apply" | |`def createFunction = (i:Int) => i+1`
`createFunction(5)`|如果看过了上面的语法部分, 你应该能明白这发生了什么. 首先, createFunction的调用没有 () 也没有参数. 然后, 5 传递给 creatFunction的返回结果的 apply 方法| |

返回类型与类型推断

| | -| `val x = "hello"`|the compiler always picks the most specific type possible, in this case java.lang.String| -| `val x:Serializable = "hello"`|you can always specify a more general one| -| `def x {print("hello world")}` | method without "=" means the method has no return type/return type is void (this is a lie) | -| `def x:Unit = {...}`
`def x() {...}`|leaving out the "=" at a method declaration is the same as specifying "Unit"| -| `val blocks = {{{{5}}}}`|every block has a return type that is passed back to the next outer block| -| `val block = if (a) foo else bar`|almost everything is an expression and thus, has a return type. this includes if-else-structures| -|`def x = {`
`if (System.currentTimeMillis() % 2 == 0) Integer.valueOf(1) else java.lang.Double.valueOf(2)`
`}`|here, the compiler picks the most specific supertype of both Integer and Double which is java.lang.Number (this is a lie)| -|`def x(i:Int):Int = if (i==0) 1 else i*x(i-1)`|recursive methods need an explicit return type. fail.| +| `val x = "hello"`|编译器总是会选择最可能的类型, 在这里是 java.lang.String| +| `val x:Serializable = "hello"`|你总能指定更通用的类型| +| `def x {print("hello world")}` | 没有 "=" 的方法表明这个方法没有返回类型,或者返回类型为void(逗你玩呢) | +| `def x:Unit = {...}`
`def x() {...}`|去掉方法声明中的 "=" 和指定返回类型为 "Unit" 是一样的| +| `val blocks = {{{{5}}}}`|每个代码块都会返回给外层代码块一个值| +| `val block = if (a) foo else bar`|几乎一切都是表达式,因此,都有返回类型,包括if-else结构| +|`def x = {`
`if (System.currentTimeMillis() % 2 == 0) Integer.valueOf(1) else java.lang.Double.valueOf(2)`
`}`|这个, 编译器选择 Integer 和 Double 的超类 java.lang.Number (实际上并非如此)| +|`def x(i:Int):Int = if (i==0) 1 else i*x(i-1)`|递归方法需要显示的返回类型声明. 编译器没法进行推断.| |

Scala 集合

| | |`1 to 3, Set(1,2,3), Buffer(1,2,3), ArrayBuffer(1,2,3), ListBuffer(1,2,3), List(1,2,3), Array(1,2,3),Vector(1,2,3), Map(1 -> "a", 2 -> "b")`|simple collection creations. scala has mutable and immutable collections.| |`1 :: 2 :: 3 :: Nil`|In addition to that, Lists have an alternative syntax|