a short outline on necessity of functional programming and principles of functional programming in Scala.
In the article some keyword are used but not explained (to keep the article short and simple), the interested reader can look them up in internet.
3. Example
var x = 0
async{ x = x+1 }
async{ x = x*2 }
// the answer could be 0, 1 or 2
Non-determinism = parallel processing+ mutable values
4. Paradigm
In science, a paradigm describes distinct concepts or
thought patterns in some scientific discipline.
Main programming paradigms:
imperative programming
functional programming
logic programming
7. Referential transparency
once a variable is given a value it never changes.
no side effects are possible.
Functions are building blocks functions are free side-effect
function call does not affect other functions and it just computes its
own output for a specific input
sin (pi) = 0
Functions are expressions not statements
8. FP is inspired by mathematics
Neither theories nor functions have mutable values.
You can combine functions to make more complex functions
The result of a function or a theory does not change for different input.
(a+b)^2 = a^2 + b^2 + 2*a*b
This state doesn’t change for different inputs.
9. Functional Languages
Pure(restricted) Functional languages ( no imperative structure)
like: Pure Lisp, XSLT, XPath, XQuery, FP,Haskell (without I/O Monad or
UnsafePerformIO)
Wider sense : Lisp, Scheme, Racket, Clojure
SML, Ocaml, F# , Haskell (full language) , Scala , Smalltalk, Ruby
10. What is scala?
Scala is a statically typed JVM language that has
transparent interoperability with Java.
Both object oriented and functional language
11. Why Scala?
Lightweight syntax
Combines functional and object-oriented approaches
Advanced type system: everything has a type
Strong type inference
Performance comparable to Java
Fully interoperable with Java
12. Example of Scala High-level syntax
Scala form
class person(val name: String , val age: Int) { ...}
Java form
class person
{
private String name;
private int age;
Peron(String name, int age)
{
this.name = name;
this.age = age;
}
}
13. continue
val list = List(2,5,4)
val newList = (list map(x => x*x)) sortWith(_ > _)
//newList = list(4,16,25)
Java form ???
val people: Array[Person]
val (minors,adults) = people partition (_.age < 18)
Java form ???
14. Subsitution Model
The idea underlying this model is that all evaluation
does is reduce an expression to a value.
It can be applied to all expressions, as long as they
have no side effects.
Lambda calculus
15. Non-primitive expression
A non-primitive expression is evaluated as follows:
1. Take the leftmost operator
2. Evaluate its operands (left before right)
3. Apply the operator to the operands
(2 * pi) * radius
(2 * 3.14159) * radius
6.28318 * radius
6.28318 * 10
62.8318
16. Parameterized functions substitution
1. Evaluate all function arguments, from left to right
2. Replace the function application by the function’s
right-hand side, and, at the same time
3. Replace the formal parameters of the function by
the actual arguments
18. Scala Substitution model
What if right hand side does not terminate ?
two elements for storing expressions in Scala: def and val
def loop: Boolean = loop
def x = loop //it is ok
val x = loop // it will lead to an infinite loop.
As you see the difference between val and def becomes apparent when
the right hand side does not terminate. Val is changed to its value when it
is defined but the value of def is substituted where it is used.
19. val & def continue
def:
1. can have parameters
def cube(x: Int): Int = x*x*x
2. Call-by-name
val:
1. The value of it is substituted as it is defined. In other
words: call-by-value
21. Higher-Order functions
Functions are expressions so they can be:
Defined anywhere included in other functions
sent to other functions as parameters
Returned from other functions
def fact(x: Int) = if(x ==0) 1 else x*fact(x-1)
def cube(x: Int) = x*x
def processOnSums( f: Int => Int , a: Int , b: Int) = f(a) + f(b)
processOnSums(cube, 2 , 3 ) // Output = 2*2 + 3*3
anonymous function: x=> x*x
processOnSums(fact , 2 , 3 ) // Output: 2*1 + 3*2*1
22. Currying
def sum(f: Int => Int, a: Int, b: Int): Int = if (a > b) 0
else f(a) + sum(f, a + 1, b)
def sumInts(a: Int, b: Int) = sum(x=>x, a, b)
def sumCubes(a: Int, b: Int) = sum(x=> x*x, a, b)
def sumFactorials(a: Int, b: Int) = sum(x=>fact(x), a, b)
Can we make it even shorter???
23. continue
def sum(f: Int => Int): (Int, Int) => Int = {
def sumF(a: Int, b: Int): Int =
if (a > b) 0
else f(a) + sumF(a + 1, b)
sumF
}
Sum returns another function
We can define like this:
def sumInts = sum(x => x)
def sumCubes = sum(x => x * x * x)
def sumFactorials = sum(fact)
sumCubes(1, 10) + sumFactorials(10, 20)
Even shorter???
25. Classes
Two kinds of instant field initialization:
Class myClass(input1: Int, input2: Int)
{
Val a = input1
Vab b = input2
}
class myClass(val input1: Int, val input2: Int){…}
26. Auxiliary Constructors
In order to create auxiliary constructors, define
method this with required parameters.
Class myClass(input1: Int, input2: Int)
{
def this(input1: Int) = this (input1, 0)
}
27. Inheritance
Inheritance rules so similar to java
Traits are alternative for interfaces
Why do we need a new structure ?
In java classes can have only one super class, but what if
a class need to inherit from several supertypes ???
This is why scala introduces traits.
28. Trait
trait super
{
val a = 5
def b = a*2
def c(x: Int) = a*x
}
class sub extends Object with super{…}
31. Object Definition
The same as java. with new notation
Val myList = new List(1,2,3)
The other form:
Val myList = List(1,2,3)
What happened? Whre is new? We will see…
32. Singletone Objects
What is singleton object and why do we need it?
The reason we used singleton classes was to create
just one object of a certain type.
Scala gives us a powerful tool called singleton object
that ease the procedure we used to do with singleton
classes in java.
33. Example
object myObject
{
def +(x: java.lang.String) = x + " and "
}
def names = myObject + "Ehsan" + "Sana"
println(names)
//output Ehsan and Sana
34. Apply Method
Still don’t know how compiler translates this:
Val myList = List(1,2,3)
We can create a new object just as we call a function with
implenting apply method.
Reason: We are just trying to show the use of apply method as a
handy way of closing the gap between functions and objects in
Scala.
35. Implementation of Apply Method for
List
object List extends List
{
def apply[A](xs: A*): List[A]
//Creates a list with the specified elements.
}
40. Immutable Maps
val map = Map("Tehran" -> "Iran" , "Paris" -> "France")
println(map.keys) // output: Set(Tehran, Paris)
Does the String class has a method ->? The answer is no.
We will see how this is translated…
41. Partial Functions
partial functions obey pattern matching rules and syntax.
Instead of switch case structure here we have match and case
wide range of usage in collections and actors
Partial function is a trait
and its Constructor takes two types; Input type and output type.
It has two abstract values too; apply(v1 a: A): B and isDefinedAt(x : A):
Boolean
42. Example
val p = new PartialFunction[Int, Any] {
def apply(xs: Int) = xs match {
case xs => 1/xs.doubleValue()
case _ => 1/xs
}
def isDefinedAt(xs: Int) = xs match {
case 0 => false
case _ => true
}
}
println(p(2)) //output: 0.5
println(p(0))// output: Infinity No exception is thrown
43. Threads
Threads in java: shared objects and lock model
Synchronized and concurrency library
always control threads to not to let them have access
on a shared object at a time, using blocks
Result: race conditions, deadlocks and nondeterminism.
44. Actors
Scala suggest shared-nothing, message-passing model.
object firstActor extends Actor {
def act() {
for (i <- 1 to 3) {
println("act" + i)
Thread.sleep(1000)
}
}
firstActor.start() //output: act1 act2 act3
45. Problem
If actors do not have shared objects how do they
connect each other???
So simple: sending message…
46. Receive Method
val echoActor = actor {
while (true)
Partial function
{
receive { case msg => println("received message: "+ msg) }
}
}
console: echoActor ! “hi”
output: hi
47. How receive works?
Does not stay on a receive line.
Messages goes to inbox waiting for actor to call
receive.
receive invoke IsDefinedAt method to make sure the
input is valid.
If input is valid, receive sends the it’s body to apply
method otherwise it throw an exception.
48. Example
val reciever = actor {
receive {
case x: Int => // Only Int is valid as input
println("Got an Int: "+ x)
}
}
reciever ! “hello world” //output: Nothing
receiver ! 4 // output: Got an Int: 4