diff --git a/_overviews/cheatsheets/index.md b/_overviews/cheatsheets/index.md index b59d3fcdcf..6ccaad378d 100644 --- a/_overviews/cheatsheets/index.md +++ b/_overviews/cheatsheets/index.md @@ -26,15 +26,15 @@ permalink: /cheatsheets/index.html - var x = 5 +
var x = 5

Good
x=6
variable - Good
val x = 5
Bad
x=6 +
val x = 5

Bad
x=6
constant - var x: Double = 5 +
var x: Double = 5
explicit type @@ -42,75 +42,93 @@ permalink: /cheatsheets/index.html - Good
def f(x: Int) = { x*x }
Bad
def f(x: Int) { x*x } + 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) + 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 R = Double
type alias - def f(x: R) vs.
def f(x: => R) +
def f(x: R)
vs.
def f(x: => R)
call-by-value
call-by-name (lazy parameters) - (x:R) => x*x +
(x:R) => x * x
anonymous function - (1 to 5).map(_*2) vs.
(1 to 5).reduceLeft( _+_ ) +
(1 to 5).map(_ * 2)
vs.
(1 to 5).reduceLeft( _ + _ )
anonymous function: underscore is positionally matched arg. - (1 to 5).map( x => x*x ) +
(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. + 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 { x => val y=x*2; println(y); y } +
(1 to 5).map { x =>
+  val y = x * 2
+  println(y)
+  y
+}
anonymous function: block style returns last expression. - (1 to 5) filter {_%2 == 0} map {_*2} +
(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}) +
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 +
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 +
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 +
def zscore(mean:R, sd:R)(x:R) =
+  (x - mean) / sd
currying, sugar syntax. but then: - val normer = zscore(7, 0.4) _ +
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) +
def mapmake[T](g: T => T)(seq: List[T]) =
+  seq.map(g)
generic type. - 5.+(3); 5 + 3
(1 to 5) map (_*2) +
5.+(3); 5 + 3

(1 to 5) map (_ * 2)
infix sugar. - def sum(args: Int*) = args.reduceLeft(_+_) +
def sum(args: Int*) = 
+  args.reduceLeft(_+_)
varargs. @@ -118,23 +136,27 @@ permalink: /cheatsheets/index.html - import scala.collection._ +
import scala.collection._
wildcard import. - import scala.collection.Vector
import scala.collection.{Vector, Sequence} +
import scala.collection.Vector

import scala.collection.{Vector, Sequence}
selective import. - import scala.collection.{Vector => Vec28} +
import scala.collection.{Vector => Vec28}
renaming import. - import java.util.{Date => _, _} +
import java.util.{Date => _, _}
import all from java.util except Date. - package pkg at start of file
package pkg { ... } + At start of file:
package pkg

Packaging by scope:
package pkg {
+  ...
+}

Package singleton:
package object pkg {
+  ...
+}
declare a package. @@ -142,57 +164,63 @@ permalink: /cheatsheets/index.html - (1,2,3) +
(1, 2, 3)
tuple literal. (Tuple3) - var (x,y,z) = (1,2,3) +
var (x, y, z) = (1, 2, 3)
destructuring bind: tuple unpacking via pattern matching. - Bad
var x,y,z = (1,2,3) + Bad
var x, y, z = (1, 2, 3)
hidden error: each assigned to the entire tuple. - var xs = List(1,2,3) +
var xs = List(1, 2, 3)
list (immutable). - xs(2) +
xs(2)
paren indexing. (slides) - 1 :: List(2,3) +
1 :: List(2, 3)
cons. - 1 to 5 same as 1 until 6
1 to 10 by 2 +
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). +
()
+ Empty parens is singleton value of the Unit type
Equivalent to void in C and Java. control constructs - if (check) happy else sad +
if (check) happy else sad
conditional. - if (check) happy +
if (check) happy

same as
- if (check) happy else () +
if (check) happy else ()
conditional sugar. - while (x < 5) { println(x); x += 1} +
while (x < 5) { 
+  println(x)
+  x += 1
+}
while loop. - do { println(x); x += 1} while (x < 5) +
do {
+  println(x)
+  x += 1
+} while (x < 5)
do while loop. @@ -206,26 +234,36 @@ breakable { break. (slides) - for (x <- xs if x%2 == 0) yield x*10 +
for (x <- xs if x%2 == 0)
+yield x * 10

same as
- xs.filter(_%2 == 0).map(_*10) +
xs.filter(_%2 == 0).map( _ * 10)
for comprehension: filter/map - for ((x,y) <- xs zip ys) yield x*y +
for ((x, y) <- xs zip ys)
+yield x * y

same as
- (xs zip ys) map { case (x,y) => x*y } +
(xs zip ys) map {
+  case (x, y) => x * y
+}
for comprehension: destructuring bind - for (x <- xs; y <- ys) yield x*y +
for (x <- xs; y <- ys)
+yield x * y

same as
- xs flatMap {x => ys map {y => x*y}} +
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.toFloat))
+  val div = x / y.toFloat
+  println("%d/%d = %.1f".format(x, y, div))
 }
for comprehension: imperative-ish
sprintf-style @@ -246,15 +284,19 @@ breakable { - Good
(xs zip ys) map { case (x,y) => x*y }
Bad
(xs zip ys) map( (x,y) => x*y ) + 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")
+  case Some(v42) => println("42")
+  case _ => println("Not 42")
 }
“v42” is interpreted as a name matching any Int value, and “42” is printed. @@ -262,30 +304,30 @@ Some(3) match { Good
val v42 = 42
 Some(3) match {
-  case Some(`v42`) => println("42")
-  case _ => println("Not 42")
+  case Some(`v42`) => println("42")
+  case _ => println("Not 42")
 }
- ”`v42`” with backticks is interpreted as the existing val v42, and “Not 42” is printed. + ”`v42`” with backticks is interpreted as the existing val
v42
, and “Not 42” is printed. Good
val UppercaseVal = 42
 Some(3) match {
-  case Some(UppercaseVal) => println("42")
-  case _ => println("Not 42")
+  case Some(UppercaseVal) => println("42")
+  case _ => println("Not 42")
 }
- UppercaseVal is treated as an existing val, rather than a new pattern variable, because it starts with an uppercase letter. Thus, the value contained within UppercaseVal is checked against 3, and “Not 42” is printed. +
UppercaseVal
is treated as an existing val, rather than a new pattern variable, because it starts with an uppercase letter. Thus, the value contained within
UppercaseVal
is checked against
3
, and “Not 42” is printed. object orientation - class C(x: R) - constructor params - x is only available in class body +
class C(x: R)
+ constructor params -
x
is only available in class body - class C(val x: R)
var c = new C(4)
c.x +
class C(val x: R)

var c = new C(4)

c.x
constructor params - automatic public member defined @@ -299,59 +341,61 @@ Some(3) match { constructor is class body
declare a public member
declare a gettable but not settable member
declare a private member
alternative constructor - new{ ... } +
new {
+  ...
+}
anonymous class - abstract class D { ... } +
abstract class D { ... }
define an abstract class. (non-createable) - class C extends D { ... } +
class C extends D { ... }
define an inherited class. - class D(var x: R)
class C(x: R) extends D(x) +
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 { ... } +
object O extends D { ... }
define a singleton. (module-like) - trait T { ... }
class C extends T { ... }
class C extends D with T { ... } +
trait T { ... }

class C extends T { ... }

class C extends D with T { ... }
traits.
interfaces-with-implementation. no constructor params. mixin-able. - trait T1; trait T2
class C extends T1 with T2
class C extends D with T1 with T2 +
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 = ...} +
class C extends D { override def f = ...}
must declare method overrides. - new java.io.File("f") +
new java.io.File("f")
create object. - Bad
new List[Int]
Good
List(1,2,3) + Bad
new List[Int]

Good
List(1, 2, 3)
type error: abstract type
instead, convention: callable factory shadowing the type - classOf[String] +
classOf[String]
class literal. - x.isInstanceOf[String] +
x.isInstanceOf[String]
type check (runtime) - x.asInstanceOf[String] +
x.asInstanceOf[String]
type cast (runtime) - x: String +
x: String
ascription (compile time)