diff --git a/_cheatsheets/index.md b/_cheatsheets/index.md index 67d4c59144..ce320d1f49 100644 --- a/_cheatsheets/index.md +++ b/_cheatsheets/index.md @@ -25,16 +25,16 @@ languages: [ba, fr, ja, pl, pt-br, zh-cn, th, ru] -
var x = 5

Good
x=6
- variable +
var x = 5

Good
x = 6
+ Variable. -
val x = 5

Bad
x=6
- constant +
val x = 5

Bad
x = 6
+ Constant.
var x: Double = 5
- explicit type + Explicit type. functions @@ -42,35 +42,31 @@ languages: [ba, fr, ja, pl, pt-br, zh-cn, th, ru] 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 + Define function.
Hidden error: without = it’s a procedure returning Unit; causes havoc. Deprecated in Scala 2.13. Good
def f(x: Any) = println(x)

Bad
def f(x) = println(x)
- define function
syntax error: need types for every arg. + Define function.
Syntax error: need types for every arg.
type R = Double
- type alias + Type alias.
def f(x: R)
vs.
def f(x: => R)
- call-by-value
call-by-name (lazy parameters) + Call-by-value.

Call-by-name (lazy parameters). -
(x:R) => x * x
- anonymous function +
(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(_ * 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(x => x * x)
+ Anonymous function: to use an arg twice, have to name it.
(1 to 5).map { x =>
@@ -78,7 +74,7 @@ languages: [ba, fr, ja, pl, pt-br, zh-cn, th, ru]
   println(y)
   y
 }
- anonymous function: block style returns last expression. + Anonymous function: block style returns last expression.
(1 to 5) filter {
@@ -86,49 +82,49 @@ languages: [ba, fr, ja, pl, pt-br, zh-cn, th, ru]
 } map {
   _ * 2
 }
- anonymous functions: pipeline style. (or parens too). + 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. + Anonymous functions: to pass in multiple blocks, need outer parens. -
val zscore = 
+      
val zscore =
   (mean: R, sd: R) =>
-    (x:R) => 
+    (x: R) =>
       (x - mean) / sd
- currying, obvious syntax. + Currying, obvious syntax. -
def zscore(mean:R, sd:R) =
-  (x:R) => 
+      
def zscore(mean: R, sd: R) =
+  (x: R) =>
     (x - mean) / sd
- currying, obvious syntax + Currying, obvious syntax. -
def zscore(mean:R, sd:R)(x:R) =
+      
def zscore(mean: R, sd: R)(x: R) =
   (x - mean) / sd
- currying, sugar syntax. but then: + Currying, sugar syntax. But then:
val normer =
   zscore(7, 0.4) _
- need trailing underscore to get the partial, only for the sugar version. + 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. + Generic type.
5.+(3); 5 + 3

(1 to 5) map (_ * 2)
- infix sugar. + Infix sugar. -
def sum(args: Int*) = 
+      
def sum(args: Int*) =
   args.reduceLeft(_+_)
- varargs. + Varargs. packages @@ -136,19 +132,19 @@ languages: [ba, fr, ja, pl, pt-br, zh-cn, th, ru]
import scala.collection._
- wildcard import. + Wildcard import.
import scala.collection.Vector

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

Packaging by scope:
package pkg {
@@ -156,7 +152,7 @@ languages: [ba, fr, ja, pl, pt-br, zh-cn, th, ru]
 }

Package singleton:
package object pkg {
   ...
 }
- declare a package. + Declare a package. data structures @@ -164,35 +160,35 @@ languages: [ba, fr, ja, pl, pt-br, zh-cn, th, ru]
(1, 2, 3)
- tuple literal. (Tuple3) + Tuple literal (Tuple3).
var (x, y, z) = (1, 2, 3)
- destructuring bind: tuple unpacking via pattern matching. + Destructuring bind: tuple unpacking via pattern matching. Bad
var x, y, z = (1, 2, 3)
- hidden error: each assigned to the entire tuple. + Hidden error: each assigned to the entire tuple.
var xs = List(1, 2, 3)
- list (immutable). + List (immutable).
xs(2)
- paren indexing. (slides) + Paren indexing (slides).
1 :: List(2, 3)
- cons. + Cons.
1 to 5
same as
1 until 6

1 to 10 by 2
- range sugar. + Range sugar.
()
- Empty parens is singleton value of the Unit type
Equivalent to void in C and Java. + Empty parens is singleton value of the Unit type.
Equivalent to void in C and Java. control constructs @@ -200,83 +196,84 @@ languages: [ba, fr, ja, pl, pt-br, zh-cn, th, ru]
if (check) happy else sad
- conditional. + Conditional.
if (check) happy

same as
if (check) happy else ()
- conditional sugar. + Conditional sugar. -
while (x < 5) { 
+      
while (x < 5) {
   println(x)
   x += 1
 }
- while loop. + While loop.
do {
   println(x)
   x += 1
 } while (x < 5)
- do while loop. + Do-while loop.
import scala.util.control.Breaks._
+
 breakable {
-  for (x <- xs) {
-    if (Math.random < 0.1)
+  for (x <- xs) {
+    if (Math.random < 0.1)
       break
   }
 }
- break. (slides) + 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)
- for comprehension: filter/map +
xs.filter(_ % 2 == 0).map(_ * 10)
+ For-comprehension: filter/map.
for ((x, y) <- xs zip ys)
-yield x * y
+ yield x * y

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

same as
xs flatMap { x =>
   ys map { y =>
     x * y
   }
 }
- for comprehension: cross product + For-comprehension: cross product. -
for (x <- xs; y <- ys) {
+      
for (x <- xs; y <- ys) {
   val div = x / y.toFloat
   println("%d/%d = %.1f".format(x, y, div))
 }
- for comprehension: imperative-ish
sprintf-style + For-comprehension: imperative-ish.
sprintf style. -
for (i <- 1 to 5) {
+      
for (i <- 1 to 5) {
   println(i)
 }
- for comprehension: iterate including the upper bound + For-comprehension: iterate including the upper bound. -
for (i <- 1 until 5) {
+      
for (i <- 1 until 5) {
   println(i)
 }
- for comprehension: iterate omitting the upper bound + For-comprehension: iterate omitting the upper bound. pattern matching @@ -284,11 +281,11 @@ yield x * y
Good
(xs zip ys) map {
-  case (x, y) => x * y 
+  case (x, y) => x * y
 }

Bad
(xs zip ys) map {
   (x, y) => x * y
 }
- use case in function args for pattern matching. + Use case in function args for pattern matching. Bad
@@ -297,7 +294,7 @@ yield x * y
case v42 => println("42") case _ => println("Not 42") }
- “v42” is interpreted as a name matching any Int value, and “42” is printed. + v42 is interpreted as a name matching any Int value, and “42” is printed. Good
@@ -306,7 +303,7 @@ yield x * y
case `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
@@ -315,7 +312,7 @@ yield x * y
case 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 @@ -323,11 +320,11 @@ yield x * y
class C(x: R)
- constructor params -
x
is only available in class body + Constructor params - x is only available in class body.
class C(val x: R)

var c = new C(4)

c.x
- constructor params - automatic public member defined + Constructor params - automatic public member defined.
class C(var x: R) {
@@ -337,65 +334,65 @@ yield x * y
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 + Constructor is class body.
Declare a public member.
Declare a gettable but not settable member.
Declare a private member.
Alternative constructor.
new {
   ...
 }
- anonymous class + Anonymous class.
abstract class D { ... }
- define an abstract class. (non-createable) + Define an abstract class (non-createable).
class C extends D { ... }
- define an inherited class. + 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) + Inheritance and constructor params (wishlist: automatically pass-up params by default).
object O extends D { ... }
- define a singleton. (module-like) + 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. + 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
- multiple traits. + Multiple traits.
class C extends D { override def f = ...}
- must declare method overrides. + Must declare method overrides.
new java.io.File("f")
- create object. + Create object. Bad
new List[Int]

Good
List(1, 2, 3)
- type error: abstract type
instead, convention: callable factory shadowing the type + Type error: abstract type.
Instead, convention: callable factory shadowing the type.
classOf[String]
- class literal. + Class literal.
x.isInstanceOf[String]
- type check (runtime) + Type check (runtime).
x.asInstanceOf[String]
- type cast (runtime) + Type cast (runtime).
x: String
- ascription (compile time) + Ascription (compile time). @@ -404,16 +401,18 @@ yield x * y
Some(42)
- Construct a non empty optional value + Construct a non empty optional value.
None
- The singleton empty optional value + The singleton empty optional value.
Option(null) == None
-Option(obj.unsafeMethod)
- Null-safe optional value factory +Option(obj.unsafeMethod) + but +
Some(null) != None
+ Null-safe optional value factory.
val optStr: Option[String] = None
@@ -426,26 +425,23 @@ Option(obj.unsafeMethod) request.getParameter("name") val upper = name.map { _.trim -} -.filter { +} filter { _.length != 0 -} -.map { +} map { _.toUpperCase } -println(upper.getOrElse("")) - - Pipeline style +println(upper.getOrElse("")) + Pipeline style.
val upper = for {
-  name <- request.getParameter("name")
-  trimmed <- Some(name.trim)
+  name <- request.getParameter("name")
+  trimmed <- Some(name.trim)
     if trimmed.length != 0
-  upper <- Some(trimmed.toUpperCase)
+  upper <- Some(trimmed.toUpperCase)
 } yield upper
 println(upper.getOrElse(""))
- for-comprehension syntax + For-comprehension syntax.
option.map(f(_))
@@ -454,7 +450,7 @@ println(upper.getOrElse("")) case Some(x) => Some(f(x)) case None => None } - Apply a function on the optional value + Apply a function on the optional value.
option.flatMap(f(_))
@@ -463,7 +459,7 @@ println(upper.getOrElse("")) case Some(x) => f(x) case None => None } - Same as map but function must return an optional value + Same as map but function must return an optional value.
optionOfOption.flatten
@@ -472,7 +468,7 @@ println(upper.getOrElse("")) case Some(Some(x)) => Some(x) case _ => None } - Extract nested option + Extract nested option.
option.foreach(f(_))
@@ -481,7 +477,7 @@ println(upper.getOrElse("")) case Some(x) => f(x) case None => () } - Apply a procedure on optional value + Apply a procedure on optional value.
option.fold(y)(f(_))
@@ -490,7 +486,7 @@ println(upper.getOrElse("")) case Some(x) => f(x) case None => y } - Apply function on optional value, return default if empty + Apply function on optional value, return default if empty.
option.collect {
@@ -498,12 +494,11 @@ println(upper.getOrElse(""))
} same as
option match {
-  case Some(x)
-    if f.isDefinedAt(x) => ...
-  case Some(_)          => None
-  case None             => None
+  case Some(x) if f.isDefinedAt(x) => ...
+  case Some(_)                     => None
+  case None                        => None
 }
- Apply partial pattern match on optional value + Apply partial pattern match on optional value.
option.isDefined
@@ -512,7 +507,7 @@ println(upper.getOrElse("")) case Some(_) => true case None => false } - True if not empty + true if not empty.
option.isEmpty
@@ -521,7 +516,7 @@ println(upper.getOrElse("")) case Some(_) => false case None => true } - True if empty + true if empty.
option.nonEmpty
@@ -530,7 +525,7 @@ println(upper.getOrElse("")) case Some(_) => true case None => false } - True if not empty + true if not empty.
option.size
@@ -539,7 +534,7 @@ println(upper.getOrElse("")) case Some(_) => 1 case None => 0 } - Zero if empty, otherwise one + 0 if empty, otherwise 1.
option.orElse(Some(y))
@@ -548,7 +543,7 @@ println(upper.getOrElse("")) case Some(x) => Some(x) case None => Some(y) } - Evaluate and return alternate optional value if empty + Evaluate and return alternate optional value if empty.
option.getOrElse(y)
@@ -557,7 +552,7 @@ println(upper.getOrElse("")) case Some(x) => x case None => y } - Evaluate and return default value if empty + Evaluate and return default value if empty.
option.get
@@ -566,7 +561,7 @@ println(upper.getOrElse("")) case Some(x) => x case None => throw new Exception } - Return value, throw exception if empty + Return value, throw exception if empty.
option.orNull
@@ -575,7 +570,7 @@ println(upper.getOrElse("")) case Some(x) => x case None => null } - Return value, null if empty + Return value, null if empty.
option.filter(f)
@@ -584,7 +579,7 @@ println(upper.getOrElse("")) case Some(x) if f(x) => Some(x) case _ => None } - Optional value satisfies predicate + Optional value satisfies predicate.
option.filterNot(f(_))
@@ -593,25 +588,27 @@ println(upper.getOrElse("")) case Some(x) if !f(x) => Some(x) case _ => None } - Optional value doesn't satisfy predicate + Optional value doesn't satisfy predicate.
option.exists(f(_))
same as
option match {
   case Some(x) if f(x) => true
-  case _               => false
+  case Some(_)         => false
+  case None            => false
 }
- Apply predicate on optional value or false if empty + Apply predicate on optional value or false if empty.
option.forall(f(_))
same as
option match {
   case Some(x) if f(x) => true
-  case None            => false
+  case Some(_)         => false
+  case None            => true
 }
- Apply predicate on optional value or true if empty + Apply predicate on optional value or true if empty.
option.contains(y)
@@ -620,7 +617,7 @@ println(upper.getOrElse("")) case Some(x) => x == y case None => false } - Checks if value equals optional value or false if empty + Checks if value equals optional value or false if empty.