/* mutable, please don't */
var y = 5
y = y + 1 // y-y=1 -> 0=1 😂 WTF?
obj.setStuff(666)
/* immutable, please yes */
val x = 5
val y = x + 1
val newObj = oldObj.copy(a = 42)
DO NOT CHANGE ANYTHING!
Just create new things based on old things
/* statement, imperative, NOPE! */
var period = null
if(hours < 12) period = "AM"
else period = "PM"
/* expression, declarative, YEP! */
val period =
if(hours < 12) "AM" else "PM"
// let period = (hours < 12) ? "AM" : "PM"
// in Scala you can have else-if etc :)
Expression - stuff that returns a value
Set of possible values. Also a constraint!
Byte | { -128, .., -1, 0, .., 127 } |
String | all perms of characters.. |
enum Stuff { A, B } | these 2 values |
interface Shape | Shape & implementations |
Abuse compiler as much as possible!
// method, NOT first-class value
def formatNumber(x: Int): String = "number: " + x
// lambda, first-class function value/object
val formatNumber = (x: Int) => "number: " + x
formatNumber(3) // number: 3
Composition!?
Return type of f1 must be input type of f2
(pipes must be compatible)
Composition, again!?
Functions that take functions as parameters
val numbers = List(1, 2, 3)
val numbersInc = numbers.map(n => n + 1)
// numbers.map(_ + 1)
// for(n <- numbers) yield n + 1
// imperative, in-place change... (destructive)
val numbers = ListBuffer(1, 2, 3)
for((n, i) <- numbers.zipWithIndex)
numbers(i) += 1
Say WHAT, not HOW!
i<list.length
or i<=list.length
???
Hmmm, why would I spend my time on that!!?
sealed hierarchy (like enums), exhaustive matching (no need for default case)
Option, Either, List ...
def sumPositive(nums: List[Int]) = {
var total = 0
var i = 0
while(i < nums.size) {
i += 1
if(nums(i) >= 0)
total += nums(i)
}
total
}
Bug at: i += 1
... IndexOutOfBoundsException 😦
def sumPositive(nums: List[Int]) = {
nums.filter(_ >= 0).sum
// nums.filter(_ >= 0).fold(0)(_ + _)
}
@tailrec
def factorial(n: Int, accum: Int = 1): Int = {
if (n == 0) accum
else factorial(n - 1, n * accum)
}
val fact5 = factorial(5)
Recursion becomes simple
(and efficient!) while loop
No stackoverflow error! :)
What if there's a missing line? Partial function! Boom, a problem!? :D
val divide = (x: Double, y: Double) =>
x / y
We say this funcition is not total.
Throws exception when y=0
(FP hates exceptions)