Some notes on Scala as a quick reference and refresher on key concepts.
- Scala: An acronym for “Scalable Language”.
- REPL: The Scala interpreter AKA REPL (=Read-Evaluate-Print Loop). An interactive interpreter that enables a developer to test Scala code interactively from the Scala interpreter.
- Concise: Giving a lot of information clearly and in a few words; brief but comprehensive.
- Imperative Programming: A programming paradigm that describes computation in terms of correctly ordered statements that change a programs state.
- Functional programming: A programming paradigm that describes computation as the evaluation of mathematical functions avoiding state, mutual data and therefore side effects.
- val vs. var: The keyword val defines a variable as an immutable value that can’t be reassigned. The keyword var defines a variable as a mutable value that can be reassigned.
- Function: A function is a mapping that takes one or more arguments and produces a single result (typically by a function definition that specify how the result can by calculated solely in terms of its arguments). No global variables, no side-effects. This is pretty much what you would also expect when looking at functions in a mathematical sense.
- Side effects: A function is said to have no side effects if it depends solely on its arguments.
- Alias: A variable name is nothing more than an alias name for a certain expression which can’t be changed.
- Higher order functions. In essence, a function is called higher ordered if it accepts another function as an argument or results into a function.
- Predicate function: Function that is passed as an argument to another function.
- Lambda expression: An anonymous function.
- Mythical underscore (_). Operating as a shortcut for a consecutive reference to all arguments of the given argument list: every occurrence of the underscore within the functions body can be replaced by the value of the given argument – the first occurrence will refer to the value of the first argument, the second occurrence refers to the second argument, and so on. Advice: you should only apply the underscore in a very economical way and in situations where context allows for easy recognition of the underlying types.
Examples:
Higher order functions and predicate functions:
val candidates = List(-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val filter = (predicate: Int => Boolean, xs: List[Int]) => { for(x <- xs; if predicate(x) ) yield x } val even = (x :Int) => x % 2 == 0 val odd = (x :Int) => x % 2 == 1 val candidates = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val evenValues = filter(even, candidates) val oddValues = filter(odd, candidates)
Lambda/anonymous function:
val evenValues = filter((x: Int) => x % 2 == 0, candidates) val positiveValues = filter((x: Int) => x > 0, candidates)
Mythical underscore:
val evenValues = filter(_ % 2 == 0, candidates) val positiveValues = filter(_ > 0, candidates) val multiply : (Int, Int) => Int = _ * _