/* 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
It's a mapping between two types (set of pairs (A, B)). 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)