Functional programming

Scala & Clojure  
  
@joelcorrea_       @humbertostreb

JVM powered languages



Imperative vs Functional


   









  • Martin Odersky
  • Current stable version = 2.11.0
  • OO + FP



Who is using


  • Rich Hickey
  • Current stable version = 1.6.0



Who is using








  

Clojure is a LISP


Rationale


"It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data structures."
 Alan J. Perlis


Data structures

Lists
(1 2 3 4 5), (list 1 2 3) 

Vectors
[1 2 3], ["string-1" "string-2" "string-3"] 

Maps
{:a 1 :b 2 :c 3}, {1 "sample1" 2 "sample2"} 

Sets
 #{sample1 sample2 sample3} 

scala.png

Concepts

  • Immutability 
  • Referential transparency (no side-effects)
  • Lazy evaluation
  • Hybrid FP + OO
  • Simplicity
  • Immutability


Sum numbers in a list


public double sum(ArrayList<Double> numbers)
{
    double sum = 0;
    for(int i = 0; i < numbers.size(); i++)
    {
        sum = sum + numbers.get(i);
    }
    return sum;
}
 

Sum numbers in a list

> List(1, 2, 3, 4, 5).sum
> Int = 15
scala.png
> (reduce + [1 2 3 4 5]) 
> 15

Increment list values






public double increment(ArrayList numbers)
{
    ArrayList incNumbers = new ArrayList();    for(int i = 0; i < numbers.size(); i++)
    {
        incNumbers.append(numbers.get(i)+1);
    }
    return newNumbers;
} 


Increment list values


> List(1,2,3).map(_ + 1)
> List(2, 3, 4) 
scala.png

> (map inc [1 2 3]) 
> (2 3 4)









Higher Order Functions (HOFs)

Anonymous function


((x : Int) => x + 1)(1)

> 2



(#(+ % 1) 1)

> 2

scala.png


Filter



List(1,2,3).filter(_ == 1) 
> List(1) 

(filter #(= % 1) [1 2 3]) 
> (1)
scala.png


Map + Reduce


List("a","bb","").map(_.size).reduce(_+_)
> Int = 3

(reduce + (map count ["a" "bb" ""]))
> 3
scala.png

Sort


List(100, 25, 10, 1).sorted 
> List[Int] = List(1, 10, 25, 100)
(sort [3 10 25 100 1 0]) 
> (0 1 3 10 25 100)


scala.png

Unit tests


class FizzBuzzTest extends FunSuite{ 
    test("Is fizz") assert(isFizz(3) == true)
    test("Is buzz") assert(isBuzz(5) == true) 
} 

(deftest fizBuzzTest 
    (testing "is fizz" (is (= (isFizz 3) true))) 
    (testing "is buzz" (is (= (isBuzz 5) true))) ) 

scala.png

Immutable


> val a = 1 
a: Int = 1 

> a = 2 
:8: error: reassignment to val 

> var b = 1 
b: Int = 1 

> a = 2
b: Int = 2 

> case class Person(name: String, age: Int) 

> val person = Person("person", 30) 
person: Person = Person(person,30) 

> val personOlder = person.copy(age = 31) 
personOlder: Person = Person(person,31) 

 Reduce


> Seq(20, 10, 30) reduce { (accum, current) => accum + current }
Int = 60
> Seq(20, 10, 30) reduce(_ + _)
Int = 60
> Seq(20, 10, 30) sum
Int = 60  

 Map


> val people = List(Person("a", 20), Person("b", 10), Person("a", 30))
people: List[Person] = List(Person(a,20), Person(b,10), Person(a,30))
> people.map(_.age).sum
Int = 60  

 Higher order functions


> val underAge = (person: Person) => person.age < 18
underAge: Person => Boolean = 

> people.filter(underAge)
List[Person] = List(Person(b,10))  

 Anonymous function


> people.filter(person => person.age > 18)
List[Person] = List(Person(a,20), Person(a,30))

> people.sortBy(person => person.age)
List[Person] = List(Person(b,10), Person(a,20), Person(a,30))  

Java way


public List peopleUnderAge(List people) {
   List result = new ArrayList();
   for (Person person : people) {
      if (person.getAge() < 18) {
         result.add(person);
      }
   }
   return result;
}  

 For-comprehension


> val nameAge = for {
     |   person <- people
     |   age <- Seq(20, 10, 30)
     |   if (person.age == age)
     | } yield (person.name, age)
List[(String, Int)] = List((a,20), (b,10), (a,30))  




Thank you!



functional programming - Scala & Clojure

By Joel Corrêa

functional programming - Scala & Clojure

  • 1,323