SlideShare a Scribd company logo
Functional Programming
II
ExperTalks 2015-09-25
Prashant Kalkar, Equal Experts
Christian Hujer, Nelkinda Software Craft
Little more on side effects
Consider this example
val hitMonster = monster.hitByShooting(gunShot)
// reduces the power of gunShot
val hitPlayer = player.hitByShooting(gunShot)
Changes to the gunshot are happening on the
slide, hence they are called as Side Effects.
Not referentially transparent.
Functional way
val (hitMonster, usedGunShot) =
monster.hitByShooting(gunShot)
val hitPlayer = player.hitByShooting(usedGunShot)
Side effect is now visible in the return type.
No more side effect, just effect of the function.
New function is referentially transparent.
Recursion
Recursion
recursion
/riˈkərZHən/
noun
See recursion.
Recursion
recursion
/riˈkərZHən/
noun
See recursion. See also tail recursion.
Recursion
recursion
/riˈkərZHən/
noun
See recursion. See also tail recursion.
tail recursion
/tāl riˈkərZHən/
noun
If you aren’t sick of it already, see tail recursion.
Recursion
Recursion
Recursion
“If you already know
what recursion is, just
remember the answer.
Otherwise, find someone
who is standing closer to
Douglas Hofstadter than
you are;
then ask him or her what
recursion is.”
‒ Andrew Plotkin
A recursive law:
Hofstadter’s Law
“It always takes longer
than you expect, even
when you take into
account Hofstadter’s
Law.”
‒ Douglas Hofstadter,
Gödel, Escher, Bach:
An Eternal Golden
Braid
Recursive Acronyms
GNU
GNU's Not Unix
WINE
WINE Is Not an Emulator
PHP
PHP Hypertext Preprocessor
Recursion in Nature
Recursion in Arts
Recursion in Arts
Recursion Use Cases
● Being Awesome
● Traversing Data Structures
○ Lists
○ Trees
● Formulas
● Algorithms
● Often less error-prone than iteration!
Recursion Example: Factorial
unsigned long factorial(unsigned long n) {
return
n == 0 ? 1
: n * factorial(n - 1);
}
Base
Case
Generic
Case
Reduction
Recursion Example: Echo
Case 1: Empty List
echo([]) :- /* Base Case */
nl.
Case 2: Single Word
echo([N]) :- /* Special 1-Element Case */
write(N), echo([]).
Case 3: Multiple Words
echo([H|T]) :- /* Generic Case */
write(H), write(' '), echo([T]).
Recursion Example: Echo
Case 1: Empty List
echo([]) :- /* Base Case */
nl.
Case 2: Single Word
echo([N]) :- /* Special 1-Element Case */
write(N), echo([]).
Case 3: Multiple Words
echo([H|T]) :- /* Generic Case */
write(H), write(' '), echo([T]).
Recursion Example: Ls
import java.io.*;
public class Ls {
public static void main(final String... args) {
if (args.length == 0) ls(new File("."));
for (final String pathname : args)
ls (new File(pathname));
}
public static void ls(final File path) {
System.out.println(path);
if (path.isDirectory())
for (final File child : path.listFiles())
ls(child);
}
}
Recursive Max Function in Haskell
maximum' :: (Ord a) => [a] -> a
maximum' [] = error "maximum of empty list"
maximum' [x] = x
maximum' (x:xs)
| x > maxTail = x
| otherwise = maxTail
where maxTail = maximum' xs
Recursive Max Function in Haskell
maximum' :: (Ord a) => [a] -> a
maximum' [] = error "maximum of empty list"
maximum' [x] = x
maximum' (x:xs) = max x (maximum' xs)
Quicksort in Haskell
qsort :: (Ord a) => [a] -> [a]
qsort [] = []
qsort (x:xs) =
qsort [a | a <- xs, a <= x]
++ [x] ++
qsort [a | a <- xs, a > x]
Disclaimer: This is not a true Quicksort (it’s not in-place),
and not the fastest possible.
But behold its beauty!
How to Develop
Linear Recursive Algorithms
1. Define Base case
aka Case 0 or Case 1
2. Define special cases, if any
3. Define generic case
aka Case n → n-1 or Case n+1 → n
Recursion in C
unsigned long factorial(unsigned long n) {
return
n == 0 ? 1
: n * factorial(n - 1);
}
Disassembly (gcc -O1)factorial:
.LFB0:
.cfi_startproc
movl $1, %eax
testq %rdi, %rdi
je .L6
pushq %rbx
.cfi_def_cfa_offset 16
.cfi_offset 3, -16
movq %rdi, %rbx
leaq -1(%rdi), %rdi
call factorial
imulq %rbx, %rax
popq %rbx
.cfi_restore 3
.cfi_def_cfa_offset 8
.L6:
rep ret
.cfi_endproc
Disassembly (clang -O1)
factorial: # @factorial
.cfi_startproc
# BB#0:
movl $1, %eax
testq %rdi, %rdi
je .LBB0_2
.align 16, 0x90
.LBB0_1: # %tailrecurse
# =>This Inner Loop Header: Depth=1
imulq %rdi, %rax
decq %rdi
jne .LBB0_1
.LBB0_2: # %tailrecurse._crit_edge
retq
.cfi_endproc
Disassembly (gcc -O2)
factorial:
.LFB0:
.cfi_startproc
testq %rdi, %rdi
movl $1, %eax
je .L4
.p2align 4,,10
.p2align 3
.L3:
imulq %rdi, %rax
subq $1, %rdi
jne .L3
rep ret
.L4:
rep ret
.cfi_endproc
Conclusion
There are cases in which modern compilers
● convert recursion into tail recursion
● compile a tail recursion into a loop
Note: javac is stupid!
Oracle, are you listening?!
Fibonacci
unsigned long fibo(unsigned long n)
{
return
n < 2 ? 1
: fibo(n - 1) + fibo(n - 2);
}
⇒ Too tough for most compilers!
Converting
Recursion → Tail Recursion
typedef unsigned long u64;
u64 fiboT(u64 a, u64 b, u64 n)
{
return
n < 2 ? a
: fiboT(b, a + b, n - 1);
}
u64 fibo(u64 n)
{
return fiboT(1, 2, n);
}
Why are Functional Languages
better at Recursion?
● Pure functions
● Memoization
● (Why do impure functions not allow
memoization?)
● Lazy Evaluation
Algebraic Data Types
Algebraic data type
Composite Type
Defined by one more more data constructors.
data List a = Nil | Cons x (List xs)
● ADT algebra
○ Sum of data constructors - Disjoint unions
○ Each constructor is Product of its arguments
ADT Example
List definition in Scala
sealed trait List[+A]
case object Nil extends List[Nothing]
case class Cons[+A](head: A, tail: List[A])
extends List[A]
In OO terms these constructors can be mapped to
subtypes.
ADT Example
ADTs have finite number of constructors or subtypes.
For list we have two constructors or subtypes
Empty list
Non empty list with head and tail.
These constructions are exhaustive and no new
subtype will ever be added.
More ADT Examples
Option
Some | None
Either
Left | Right
Try
Success | Failure
Future
Success | Failure
Switch cases good or bad
OO programmers consider Switch cases bad.
Conditional code. Hard to maintain
Hunt down existing cases to add new cases.
Program will misbehave if you miss to update one.
FP enhanced switch cases to pattern matching
and promote them.
What’s the Truth??
Types and Operations
● Type against Operations
Type
Operations
Infinite Type,
Finite Operations
Finite Type,
Infinite Operations
Infinite Type, Finite Operations
Implemented as Polymorphism (class hierarchy).
Easy to add new Type by Subtyping.
Difficult to add new Operations.
Finite Type, Infinite Operations
Represented by Algebraic data types (ADTs)
Easy to add new operations using Pattern matching.
Difficult to add new Types.
Pattern Matching
Check for given pattern in the input.
Constant Pattern
def describe(x: Any) = x match {
case 5 => "five"
case "hello" => "hi!"
case () => "Unit" // => everything is a value
}
Switch cases.. Enhanced
Pattern Types
● Constructor Pattern
sealed class Expr
case class Number(num: Double) extends Expr
case class UnOp(operator: String, arg: Expr)
extends Expr
expr match {
case UnOp("-", UnOp("-", Number(a))) =>
println("Double Negation for" + a)
case _ => // return type unit ().
}
Sequence Pattern
expr match {
case List(0, _, _) =>
println("3 element, starting with 0")
case List(0, _*) => println("starting with 0")
case List(_, _, *) => println("at least two")
case e => println("something else" + e)
// variable pattern
}
Variable pattern is catch all pattern.
Type Pattern
def generalSize(x: Any) = x match {
case s: String => s.length
// typecast to string
case m: Map[_, _] => m.size
case _ => -1
}
Type pattern
def isIntIntMap(x: Any) = x match {
case m: Map[Int, Int] => true
case _ => false
}
<console>:11: warning: non-variable type argument
Int in type pattern Map[Int,Int] is unchecked since
it is eliminated by erasure
case m: Map[Int, Int] => true
^
Type erasers
Generic types in java and scala are only available at
compile time.
Compiler use this information for type checking and then
erase it.
Java and Scala arrays are exception to this rule.
def isStringArray(x: Any) = x match {
case a: Array[String] => "yes" // this works
case _ => "no"
}
Pattern matching with ADTs
def printIfExists(a: Option[Int]) = {
a match {
case Some(x) =>
println("value provided " + x)
}
}
<console>:10: warning: match may not be exhaustive.
It would fail on the following input: None
This check is possible because of ADTs
Pattern match as Higher order function
def doubleTheOdds(numbers: List[Int]) = {
numbers.map {
case x if x%2 != 0 => x * 2
case y => y
}
}
The match is happening on the input of the map function.
If condition in pattern matching is called as Guard
Condition.
Partial functions with Pattern Matching
def printIfExists:
PartialFunction[Option[Int], Unit] = {
case Some(x) =>
println("value provided " + x)
}
This will compile without any warnings.
Also no match required (similar to HOF pattern matching)
Pattern matching in variable declaration
Tuple values
val fullName = ("Jack", "Sparrow")
val (firstName, lastName) = fullName
Case class objects
val exp = BinOp("*", Number(5), Number(1))
val BinOp(op, left, right) = exp
Pattern matching as value
val number = 10
val numberDescription = number match {
case 5 => "five"
case 10 => "Ten"
case _ => "something else"
}
Everything is value in function programming.
Also said as everything is an expression (not statement).
Pattern Matching final Example
val numbers = List(1, 2, 3, 4, 5, 6)
numbers.collect { case x if x%2 == 0 => x * 2 }
output => List(4, 8, 12)
This is equivalent to
val partial: PartialFunction[Int, Int] = {
case x if x % 2 == 0 => x * 2
}
numbers.filter(partial.isDefinedAt).map(partial)
I’ve seen the future.
● It’s logical.
● It has pattern matching…
…on the right side, which is left!
Pattern matching beyond FP?
main(Argv) :- echo(Argv).
echo([]) :-
nl.
echo([Last]) :-
write(Last), echo([]).
echo([H|T]) :-
write(H), write(' '), echo(T).
Echo in Prolog
Expression Problem
Problem
What can be done when neither Types nor Operations
are limited.
Is there a way to
Add a new type easily
Add a new operation easily
This problem is well known as Expression Problem.
Philip Wadler 1998
American Computer
Scientist
He coined the term
Expression Problem
Expression Problem
Definition
Expression Problem:
The goal is to define a datatype by cases, where one
can add new cases to the datatype and new functions
over the datatype, without recompiling existing code,
and while retaining static type safety (e.g., no casts)
Used in discussing strengths and weaknesses
(expressive power) of various programming paradigms
and programming languages.
The problem manifest itself while working with
language expressions.
interface Exp { void print(); }
class Lit implements Exp {
protected int value;
Lit(int value) { this.value = value; }
public void print() { System.out.print(value); }
}
class Add implements Exp {
protected Exp left, right;
Add(Exp l, Exp r) { left = l; right = r; }
public void print() {
return left.print(); Syso.print(“+”);
right.print();
}
}
interface EvalExp extends Exp {
int eval();
}
class EvalAdd extends Add implements EvalExp {
public int eval() {
return left.eval() + right.eval();
}
}
// Ouch! This will not compile.
Generics to the Rescue
We can solve the compilation problem by somehow
limiting the left and right to EvalExp
We can do that by introducing a type parameter for
EvalAdd class.
class EvalAdd<A extends EvalExp> extends Add
implements EvalExp
But this does not change the type of the left or right.
We will have to parameterize Add too.
Simple Solution with Generics
class Add<A extends Exp> implements Exp {
protected A left, right;
Add(A l, A r) { left = l; right = r; }
public void print() { … }
}
class EvalAdd<A extends EvalExp> extends Add<A>
implements EvalExp {
public int eval() {
return left.eval() + right.eval();
// Now this will work.
}
}
Analysing the solution
The solution is possible because of Generics
which came from FP languages into Java.
But we do not like this solution.
The base interface Exp does not enforce type
parameter on derived classes.
This version was simplified version of actual
proposed solution.
Type classes
Expression problem can be solved by using
type classes
Haskell was the first language to introduce type
classes.
They are supported by Scala with the help of
implicits.
Example
sealed trait Exp
case class Lit(value: Int) extends Exp
case class Add(left: Exp, right: Exp) extends Exp
object ExpEvaluator {
def eval(exp : Exp): Int = exp match {
case Lit(value) => value
case Add(left, right) =>
eval(left) + eval(right)
}
}
We would like to convert Expression to Json.
object JsonWriter {
def write(value: JsonValue): String = // ...
def write(value: Exp) = // ...
}
But, we should be able to use JsonWriter for any
object not just Expressions.
How about this
trait JsonConvertible {
def toJson: JsValue
}
sealed trait Exp extends JsonConvertible
object JsonWriter {
def write(value: JsonValue): String = // ...
def write(value: JsonConvertible) =
write(value.toJson)
}
This works.
JsonWriter.write(Add(Lit(2), Lit(3)))
But wait! .. Why the Expression class needs to know
anything about Json.
We would like to remove the Expression dependency
on JsonCovertible.
This implementation is also called as Subtype
Polymorphism
We can solve the coupling problem by introducing a
Type class as follows
// type class
trait JsonConverter[A] {
def convertToJson(value: A): JsonValue
}
object JsonWriter {
def write(value: JsonValue): String = // ...
def write[A](value: A, conv: JsonConverter[A]) =
write(conv.convertToJson(value))
}
We need to implement a convertor.
def expJsonConverter = new JsonConverter[Exp] {
def convertToJson(exp: Exp): JsonValue = { ... }
}
JsonWriter.write(Add(Lit(2), Lit(3)),
expJsonConverter)
This removed the coupling between Exp and Json.
But we have to pass in a parameter, which can quickly
become complex for Composite type.
Scala implicits can help here.
implicit def expJsonConverter = // ...
def write[A](value: A)(implicit conv: JsonConverter[A]) =
write(conv.convertToJson(value))
JsonWriter.write(Add(Lit(2), Lit(3)))
Implicits parameters are passed in by the Compiler.
The call is now exactly like when JsonCovertible was
used.
More about Type classes
Type classes provide something called as Ad-hoc
polymorphism.
Type classes allow you to add new functionality to the
existing Types, without changing them.
Note, they are different than extension methods.
Like extension method, they do not attach themself to
the type they are working on.
More about Type classes
Type classes provide polymorphism on their type
parameters.
Interfaces in OO, provide polymorphism over the
calling object.
Type classes can accept more than one type
parameters and hence can provide polymorphism on
two different type parameters.
This is not possible for interfaces.
More about Type classes
Compiler picks-up the right type classes on the type
parameter.
So unlike interfaces, implementation is chosen at
compile time
Type classes depend on their type parameters and not
with the object so they are more like Generic Static
Method.
Solving Expression Problem with Type classes
trait Exp
case class Lit(value: Int) extends Exp
case class Add[A <: Exp, B <: Exp](left: A, right:
B) extends Exp
[A <: Exp] is same as <A extends Exp> in Java
Define type class and implicit implementations
// type class
trait Eval[E] {
def eval(e: E): Int
}
implicit def litEval = new Eval[Lit] {
def eval(l: Lit) = l.value
}
Implementation for Add is little complex.
implicit def addEval[A <: Exp, B <: Exp]
(implicit e1: Eval[A], e2: Eval[B]) = {
new Eval[Add[A, B]] {
def eval(a: Add[A, B]) =
e1.eval(a.left) + e2.eval(a.right)
}
}
The method takes two implicit arguments to evaluate left and
right exp.
In, Add[A, B], A and B are type of Exp which can be Add or Lit
Evaluating the Expressions
def expressionEvaluator[A <: Exp]
(exp: A)(implicit e : Eval[A]) = {
e.eval(exp)
}
Lets use it to evaluate something
// (1 + 2) + 3
val exp1 = Add(Add(Lit(1), Lit(2)), Lit(3))
println("" + expressionEvaluator(exp1))
// output => 6
Let add a new type
case class Mult[A <: Exp, B <: Exp]
(left: A, right: B) extends Exp
Define an Implicit evaluator for Mult (same as Add)
implicit def mulEval[A <: Exp, B <: Exp]
(implicit e1: Eval[A], e2: Eval[B]) = {
new Eval[Mult[A, B]] {
def eval(m : Mult[A, B]) =
e1.eval(m.left) * e2.eval(m.right)
}
}
This will allow us to evaluate Expression with Mult
// (3 + 4) * 7
val exp2 = Mult(Add(Lit(3), Lit(4)), Lit(7))
println("" + expressionEvaluator(exp2))
// output => 49
Lets try to add new operation like Print.
Type class for Print operation
// type class
trait Print[P] {
def print(p: P): Unit
}
Implicit implementation for Lit type
implicit def litPrint = new Print[Lit] {
def print(l: Lit) = Console.print(l.value)
}
Similarly implicit implementation for Add and Mult
implicit def addPrint[A <: Exp, B <: Exp]
(implicit p1: Print[A], p2 : Print[B]) = {
new Print[Add[A, B]] {
def print(a : Add[A, B]) = {
p1.print(a.left);
Console.print(" + ");
p2.print(a.right);
}
}
Implementation for Mult is exactly same.
Define a method to print the expression
def printExpressions[A <: Exp]
(exp : A)(implicit p : Print[A]) = {
p.print(exp)
}
Use it to print the expressions.
// (3 + 4) * 7
val exp2 = Mult(Add(Lit(3), Lit(4)), Lit(7))
printExpressions(exp2)
// output => 3 + 4 * 7
Testing
Functional Programming
● In General: Easier than OO (without FP)
○ Pure Functions are almost trivial to test.
○ No Side-effects ⇒ No additional states
○ Higher Order Functions can be mocked easily.
● But what about TDD? How do you approach
TDD for Functional Programming?
Testing Functional Programming
Transformation Priority Premise
● What is a
Transformation?
● Let’s talk about
Refactoring.
“Uncle Bob”, My Hero
Robert C. Martin →
Refactoring
“Refactoring is changing the structure of code
without significantly changing its behavior.”
‒ Robert C. Martin
Transformation
“Transformation is changing the behavior of code
without significantly changing its structure.”
‒ Robert C. Martin
Transformation Priority Premise
({} → nil) no code at all -> code that employs nil
(nil->constant)
(constant → constant+) a simple constant to a more complex constant
(constant → scalar) replacing a constant with a variable or an argument
(statement → statements) adding more unconditional statements.
(unconditional → if) splitting the execution path
(scalar → array)
(array → container)
(statement → recursion)
(if → while)
(expression → function)
replacing an expression with a function or algorithm
(variable → assignment) replacing the value of a variable
Beyond FP
● FP and OO are NOT mutually exclusive
● FOOP - Functional Object Oriented
Programming
● Logic Programming
Thank you!
Questions?
Backup Slides
TODO Testing
● Testing Pure First-Order Functions
● Testing Pure Higher-Order Functions
○ Mocking in FP
● Transformation Priority Premise for FP
○ Example how to develop from Base Case to N-Case
List Implementation - optional
package mylist
sealed trait List[A] {
def ::(e: A): List[A] = mylist.::(e, this)
def :::(l: List[A]): List[A] = ???
}
case object Nil extends List[Nothing]
case class ::[A](h: A, tail: List[A]) extends List[A]
Topic List
[P] Side Effects Continued
[C] Recursion
[P] Algebraic Datatypes
[P] Pattern Matching
[P] Expression Problem
[C] Streams in Java (creation, consumption, filtering, map, reduce etc.)
[P] Streams in Scala (creation, consumption, filtering, map, reduce etc.)
[C] Testing in Functional Programming (TDD for FP, BDD, TPP for FP)
Monads
Monoids
Functors
Applicatives
F-Bounded Types
Recursion TODO
● Replacing Assignments with Calls
● Replacing Loops with Recursion
● Developing Recursive Algorithms
○ Base Case / Most Degenerate Case
○ N-Case
○ List-Variants: Empty, 1 Element, Multiple
○ Head-Tail-Recursion vs Partition Recursion
● Tail-Recursion
○ Why
○ How to convert normal recursion into tail recursion (example: factorial) by introducing a
result parameter
○ Examples in C with Disassemblies by GCC, clang, armcc, c251
○ Example in Prolog
○ Example in Scala
○ Example in Clojure
○ Limitations in Java

More Related Content

PPTX
Functional programming
PDF
Functional Programming Patterns (BuildStuff '14)
PDF
Thinking in Functions: Functional Programming in Python
PDF
Learning Functional Programming Without Growing a Neckbeard
PDF
An Introduction to Functional Programming - DeveloperUG - 20140311
PPT
Introduction to Functional Programming in JavaScript
PDF
Javaz. Functional design in Java 8.
PDF
Scala categorytheory
Functional programming
Functional Programming Patterns (BuildStuff '14)
Thinking in Functions: Functional Programming in Python
Learning Functional Programming Without Growing a Neckbeard
An Introduction to Functional Programming - DeveloperUG - 20140311
Introduction to Functional Programming in JavaScript
Javaz. Functional design in Java 8.
Scala categorytheory

What's hot (19)

PPTX
Functional programming
PDF
46630497 fun-pointer-1
PDF
An introduction to property based testing
ODP
Clojure basics
PPS
Let Us Learn Lambda Using C# 3.0
PDF
Monadic Java
PPTX
Templates presentation
PDF
CS4200 2019 | Lecture 2 | syntax-definition
PDF
Game of Life - Polyglot FP - Haskell, Scala, Unison - Part 2 - with minor cor...
PPT
Scala functions
PDF
Lazy java
PDF
Intro to Functional Programming
PPTX
Python programming
PDF
Introduction to functional programming
PDF
Python for data science by www.dmdiploma.com
PDF
Functions
PDF
Implicit conversion and parameters
PDF
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Functional programming
46630497 fun-pointer-1
An introduction to property based testing
Clojure basics
Let Us Learn Lambda Using C# 3.0
Monadic Java
Templates presentation
CS4200 2019 | Lecture 2 | syntax-definition
Game of Life - Polyglot FP - Haskell, Scala, Unison - Part 2 - with minor cor...
Scala functions
Lazy java
Intro to Functional Programming
Python programming
Introduction to functional programming
Python for data science by www.dmdiploma.com
Functions
Implicit conversion and parameters
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Ad

Viewers also liked (13)

PDF
2016 stop writing javascript frameworks by Joe Gregorio
PPT
Introduction Functional Programming - Tech Hangout #11 - 2013.01.16
PPTX
Fuel Up JavaScript with Functional Programming
PDF
Modeling with Hadoop kdd2011
PPTX
Functional Programming Fundamentals
PDF
Lambda Calculus by Dustin Mulcahey
PPTX
Functional programming
KEY
Machine Learning with Apache Mahout
PDF
Interactive Scientific Image Analysis using Spark
PDF
Functional programming
PPTX
Functional Programming in JavaScript by Luis Atencio
PDF
The Lambda Calculus and The JavaScript
PDF
Predictive Analytics Project in Automotive Industry
2016 stop writing javascript frameworks by Joe Gregorio
Introduction Functional Programming - Tech Hangout #11 - 2013.01.16
Fuel Up JavaScript with Functional Programming
Modeling with Hadoop kdd2011
Functional Programming Fundamentals
Lambda Calculus by Dustin Mulcahey
Functional programming
Machine Learning with Apache Mahout
Interactive Scientific Image Analysis using Spark
Functional programming
Functional Programming in JavaScript by Luis Atencio
The Lambda Calculus and The JavaScript
Predictive Analytics Project in Automotive Industry
Ad

Similar to Functional programming ii (20)

PDF
Scala Functional Patterns
PDF
A taste of Functional Programming
PDF
02. haskell motivation
PDF
04. haskell handling
PPTX
Scala Introduction
PPTX
Scala training workshop 02
PPTX
Scala basic
PDF
Introducing Pattern Matching in Scala
PDF
Power of functions in a typed world
KEY
An Introduction to Functional Programming using Haskell
PDF
ecoop-slides.pdf
PDF
Rainer Grimm, “Functional Programming in C++11”
PPT
Functional Programming - Past, Present and Future
PPT
Functional Programming Past Present Future
PDF
The Next Great Functional Programming Language
PPTX
Scala Introduction - Synerzip
PPTX
Introduction to Scala
PDF
Introduction à Scala - Michel Schinz - January 2010
PDF
High-Performance Haskell
PDF
iRODS Rule Language Cheat Sheet
Scala Functional Patterns
A taste of Functional Programming
02. haskell motivation
04. haskell handling
Scala Introduction
Scala training workshop 02
Scala basic
Introducing Pattern Matching in Scala
Power of functions in a typed world
An Introduction to Functional Programming using Haskell
ecoop-slides.pdf
Rainer Grimm, “Functional Programming in C++11”
Functional Programming - Past, Present and Future
Functional Programming Past Present Future
The Next Great Functional Programming Language
Scala Introduction - Synerzip
Introduction to Scala
Introduction à Scala - Michel Schinz - January 2010
High-Performance Haskell
iRODS Rule Language Cheat Sheet

More from Prashant Kalkar (9)

PPTX
Best practices for Highly available apps on k8s.pptx
PPTX
Design principles to modularise a monolith codebase.pptx
PDF
GDCR 2022.pptx.pdf
PPTX
Exploring the flow of network traffic through kubernetes cluster.pptx
PPTX
Uncover the mysteries of infrastructure as code (iac)!
PPTX
AWS ECS workshop
PPTX
Microservices testing consumer driven contracts using pact
PPTX
Immutable infrastructure with Terraform
PPTX
Hibernate
Best practices for Highly available apps on k8s.pptx
Design principles to modularise a monolith codebase.pptx
GDCR 2022.pptx.pdf
Exploring the flow of network traffic through kubernetes cluster.pptx
Uncover the mysteries of infrastructure as code (iac)!
AWS ECS workshop
Microservices testing consumer driven contracts using pact
Immutable infrastructure with Terraform
Hibernate

Recently uploaded (20)

PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
Nekopoi APK 2025 free lastest update
PDF
medical staffing services at VALiNTRY
PPTX
ISO 45001 Occupational Health and Safety Management System
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
PPTX
Transform Your Business with a Software ERP System
PPTX
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
Understanding Forklifts - TECH EHS Solution
PPT
Introduction Database Management System for Course Database
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
System and Network Administraation Chapter 3
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
AI in Product Development-omnex systems
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PDF
System and Network Administration Chapter 2
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
Design an Analysis of Algorithms I-SECS-1021-03
How to Migrate SBCGlobal Email to Yahoo Easily
Odoo Companies in India – Driving Business Transformation.pdf
Nekopoi APK 2025 free lastest update
medical staffing services at VALiNTRY
ISO 45001 Occupational Health and Safety Management System
VVF-Customer-Presentation2025-Ver1.9.pptx
Transform Your Business with a Software ERP System
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
Adobe Illustrator 28.6 Crack My Vision of Vector Design
2025 Textile ERP Trends: SAP, Odoo & Oracle
Understanding Forklifts - TECH EHS Solution
Introduction Database Management System for Course Database
Wondershare Filmora 15 Crack With Activation Key [2025
System and Network Administraation Chapter 3
How to Choose the Right IT Partner for Your Business in Malaysia
AI in Product Development-omnex systems
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
System and Network Administration Chapter 2
Softaken Excel to vCard Converter Software.pdf
Design an Analysis of Algorithms I-SECS-1021-03

Functional programming ii

  • 1. Functional Programming II ExperTalks 2015-09-25 Prashant Kalkar, Equal Experts Christian Hujer, Nelkinda Software Craft
  • 2. Little more on side effects Consider this example val hitMonster = monster.hitByShooting(gunShot) // reduces the power of gunShot val hitPlayer = player.hitByShooting(gunShot) Changes to the gunshot are happening on the slide, hence they are called as Side Effects. Not referentially transparent.
  • 3. Functional way val (hitMonster, usedGunShot) = monster.hitByShooting(gunShot) val hitPlayer = player.hitByShooting(usedGunShot) Side effect is now visible in the return type. No more side effect, just effect of the function. New function is referentially transparent.
  • 7. recursion /riˈkərZHən/ noun See recursion. See also tail recursion. Recursion
  • 8. recursion /riˈkərZHən/ noun See recursion. See also tail recursion. tail recursion /tāl riˈkərZHən/ noun If you aren’t sick of it already, see tail recursion. Recursion
  • 10. Recursion “If you already know what recursion is, just remember the answer. Otherwise, find someone who is standing closer to Douglas Hofstadter than you are; then ask him or her what recursion is.” ‒ Andrew Plotkin
  • 11. A recursive law: Hofstadter’s Law “It always takes longer than you expect, even when you take into account Hofstadter’s Law.” ‒ Douglas Hofstadter, Gödel, Escher, Bach: An Eternal Golden Braid
  • 12. Recursive Acronyms GNU GNU's Not Unix WINE WINE Is Not an Emulator PHP PHP Hypertext Preprocessor
  • 16. Recursion Use Cases ● Being Awesome ● Traversing Data Structures ○ Lists ○ Trees ● Formulas ● Algorithms ● Often less error-prone than iteration!
  • 17. Recursion Example: Factorial unsigned long factorial(unsigned long n) { return n == 0 ? 1 : n * factorial(n - 1); } Base Case Generic Case Reduction
  • 18. Recursion Example: Echo Case 1: Empty List echo([]) :- /* Base Case */ nl. Case 2: Single Word echo([N]) :- /* Special 1-Element Case */ write(N), echo([]). Case 3: Multiple Words echo([H|T]) :- /* Generic Case */ write(H), write(' '), echo([T]).
  • 19. Recursion Example: Echo Case 1: Empty List echo([]) :- /* Base Case */ nl. Case 2: Single Word echo([N]) :- /* Special 1-Element Case */ write(N), echo([]). Case 3: Multiple Words echo([H|T]) :- /* Generic Case */ write(H), write(' '), echo([T]).
  • 20. Recursion Example: Ls import java.io.*; public class Ls { public static void main(final String... args) { if (args.length == 0) ls(new File(".")); for (final String pathname : args) ls (new File(pathname)); } public static void ls(final File path) { System.out.println(path); if (path.isDirectory()) for (final File child : path.listFiles()) ls(child); } }
  • 21. Recursive Max Function in Haskell maximum' :: (Ord a) => [a] -> a maximum' [] = error "maximum of empty list" maximum' [x] = x maximum' (x:xs) | x > maxTail = x | otherwise = maxTail where maxTail = maximum' xs
  • 22. Recursive Max Function in Haskell maximum' :: (Ord a) => [a] -> a maximum' [] = error "maximum of empty list" maximum' [x] = x maximum' (x:xs) = max x (maximum' xs)
  • 23. Quicksort in Haskell qsort :: (Ord a) => [a] -> [a] qsort [] = [] qsort (x:xs) = qsort [a | a <- xs, a <= x] ++ [x] ++ qsort [a | a <- xs, a > x] Disclaimer: This is not a true Quicksort (it’s not in-place), and not the fastest possible. But behold its beauty!
  • 24. How to Develop Linear Recursive Algorithms 1. Define Base case aka Case 0 or Case 1 2. Define special cases, if any 3. Define generic case aka Case n → n-1 or Case n+1 → n
  • 25. Recursion in C unsigned long factorial(unsigned long n) { return n == 0 ? 1 : n * factorial(n - 1); }
  • 26. Disassembly (gcc -O1)factorial: .LFB0: .cfi_startproc movl $1, %eax testq %rdi, %rdi je .L6 pushq %rbx .cfi_def_cfa_offset 16 .cfi_offset 3, -16 movq %rdi, %rbx leaq -1(%rdi), %rdi call factorial imulq %rbx, %rax popq %rbx .cfi_restore 3 .cfi_def_cfa_offset 8 .L6: rep ret .cfi_endproc
  • 27. Disassembly (clang -O1) factorial: # @factorial .cfi_startproc # BB#0: movl $1, %eax testq %rdi, %rdi je .LBB0_2 .align 16, 0x90 .LBB0_1: # %tailrecurse # =>This Inner Loop Header: Depth=1 imulq %rdi, %rax decq %rdi jne .LBB0_1 .LBB0_2: # %tailrecurse._crit_edge retq .cfi_endproc
  • 28. Disassembly (gcc -O2) factorial: .LFB0: .cfi_startproc testq %rdi, %rdi movl $1, %eax je .L4 .p2align 4,,10 .p2align 3 .L3: imulq %rdi, %rax subq $1, %rdi jne .L3 rep ret .L4: rep ret .cfi_endproc
  • 29. Conclusion There are cases in which modern compilers ● convert recursion into tail recursion ● compile a tail recursion into a loop Note: javac is stupid! Oracle, are you listening?!
  • 30. Fibonacci unsigned long fibo(unsigned long n) { return n < 2 ? 1 : fibo(n - 1) + fibo(n - 2); } ⇒ Too tough for most compilers!
  • 31. Converting Recursion → Tail Recursion typedef unsigned long u64; u64 fiboT(u64 a, u64 b, u64 n) { return n < 2 ? a : fiboT(b, a + b, n - 1); } u64 fibo(u64 n) { return fiboT(1, 2, n); }
  • 32. Why are Functional Languages better at Recursion? ● Pure functions ● Memoization ● (Why do impure functions not allow memoization?) ● Lazy Evaluation
  • 34. Algebraic data type Composite Type Defined by one more more data constructors. data List a = Nil | Cons x (List xs) ● ADT algebra ○ Sum of data constructors - Disjoint unions ○ Each constructor is Product of its arguments
  • 35. ADT Example List definition in Scala sealed trait List[+A] case object Nil extends List[Nothing] case class Cons[+A](head: A, tail: List[A]) extends List[A] In OO terms these constructors can be mapped to subtypes.
  • 36. ADT Example ADTs have finite number of constructors or subtypes. For list we have two constructors or subtypes Empty list Non empty list with head and tail. These constructions are exhaustive and no new subtype will ever be added.
  • 37. More ADT Examples Option Some | None Either Left | Right Try Success | Failure Future Success | Failure
  • 38. Switch cases good or bad OO programmers consider Switch cases bad. Conditional code. Hard to maintain Hunt down existing cases to add new cases. Program will misbehave if you miss to update one. FP enhanced switch cases to pattern matching and promote them. What’s the Truth??
  • 39. Types and Operations ● Type against Operations Type Operations Infinite Type, Finite Operations Finite Type, Infinite Operations
  • 40. Infinite Type, Finite Operations Implemented as Polymorphism (class hierarchy). Easy to add new Type by Subtyping. Difficult to add new Operations. Finite Type, Infinite Operations Represented by Algebraic data types (ADTs) Easy to add new operations using Pattern matching. Difficult to add new Types.
  • 42. Check for given pattern in the input. Constant Pattern def describe(x: Any) = x match { case 5 => "five" case "hello" => "hi!" case () => "Unit" // => everything is a value } Switch cases.. Enhanced
  • 43. Pattern Types ● Constructor Pattern sealed class Expr case class Number(num: Double) extends Expr case class UnOp(operator: String, arg: Expr) extends Expr expr match { case UnOp("-", UnOp("-", Number(a))) => println("Double Negation for" + a) case _ => // return type unit (). }
  • 44. Sequence Pattern expr match { case List(0, _, _) => println("3 element, starting with 0") case List(0, _*) => println("starting with 0") case List(_, _, *) => println("at least two") case e => println("something else" + e) // variable pattern } Variable pattern is catch all pattern.
  • 45. Type Pattern def generalSize(x: Any) = x match { case s: String => s.length // typecast to string case m: Map[_, _] => m.size case _ => -1 }
  • 46. Type pattern def isIntIntMap(x: Any) = x match { case m: Map[Int, Int] => true case _ => false } <console>:11: warning: non-variable type argument Int in type pattern Map[Int,Int] is unchecked since it is eliminated by erasure case m: Map[Int, Int] => true ^
  • 47. Type erasers Generic types in java and scala are only available at compile time. Compiler use this information for type checking and then erase it. Java and Scala arrays are exception to this rule. def isStringArray(x: Any) = x match { case a: Array[String] => "yes" // this works case _ => "no" }
  • 48. Pattern matching with ADTs def printIfExists(a: Option[Int]) = { a match { case Some(x) => println("value provided " + x) } } <console>:10: warning: match may not be exhaustive. It would fail on the following input: None This check is possible because of ADTs
  • 49. Pattern match as Higher order function def doubleTheOdds(numbers: List[Int]) = { numbers.map { case x if x%2 != 0 => x * 2 case y => y } } The match is happening on the input of the map function. If condition in pattern matching is called as Guard Condition.
  • 50. Partial functions with Pattern Matching def printIfExists: PartialFunction[Option[Int], Unit] = { case Some(x) => println("value provided " + x) } This will compile without any warnings. Also no match required (similar to HOF pattern matching)
  • 51. Pattern matching in variable declaration Tuple values val fullName = ("Jack", "Sparrow") val (firstName, lastName) = fullName Case class objects val exp = BinOp("*", Number(5), Number(1)) val BinOp(op, left, right) = exp
  • 52. Pattern matching as value val number = 10 val numberDescription = number match { case 5 => "five" case 10 => "Ten" case _ => "something else" } Everything is value in function programming. Also said as everything is an expression (not statement).
  • 53. Pattern Matching final Example val numbers = List(1, 2, 3, 4, 5, 6) numbers.collect { case x if x%2 == 0 => x * 2 } output => List(4, 8, 12) This is equivalent to val partial: PartialFunction[Int, Int] = { case x if x % 2 == 0 => x * 2 } numbers.filter(partial.isDefinedAt).map(partial)
  • 54. I’ve seen the future. ● It’s logical. ● It has pattern matching… …on the right side, which is left! Pattern matching beyond FP?
  • 55. main(Argv) :- echo(Argv). echo([]) :- nl. echo([Last]) :- write(Last), echo([]). echo([H|T]) :- write(H), write(' '), echo(T). Echo in Prolog
  • 57. Problem What can be done when neither Types nor Operations are limited. Is there a way to Add a new type easily Add a new operation easily This problem is well known as Expression Problem.
  • 58. Philip Wadler 1998 American Computer Scientist He coined the term Expression Problem Expression Problem
  • 59. Definition Expression Problem: The goal is to define a datatype by cases, where one can add new cases to the datatype and new functions over the datatype, without recompiling existing code, and while retaining static type safety (e.g., no casts) Used in discussing strengths and weaknesses (expressive power) of various programming paradigms and programming languages. The problem manifest itself while working with language expressions.
  • 60. interface Exp { void print(); } class Lit implements Exp { protected int value; Lit(int value) { this.value = value; } public void print() { System.out.print(value); } } class Add implements Exp { protected Exp left, right; Add(Exp l, Exp r) { left = l; right = r; } public void print() { return left.print(); Syso.print(“+”); right.print(); } }
  • 61. interface EvalExp extends Exp { int eval(); } class EvalAdd extends Add implements EvalExp { public int eval() { return left.eval() + right.eval(); } } // Ouch! This will not compile.
  • 62. Generics to the Rescue We can solve the compilation problem by somehow limiting the left and right to EvalExp We can do that by introducing a type parameter for EvalAdd class. class EvalAdd<A extends EvalExp> extends Add implements EvalExp But this does not change the type of the left or right. We will have to parameterize Add too.
  • 63. Simple Solution with Generics class Add<A extends Exp> implements Exp { protected A left, right; Add(A l, A r) { left = l; right = r; } public void print() { … } } class EvalAdd<A extends EvalExp> extends Add<A> implements EvalExp { public int eval() { return left.eval() + right.eval(); // Now this will work. } }
  • 64. Analysing the solution The solution is possible because of Generics which came from FP languages into Java. But we do not like this solution. The base interface Exp does not enforce type parameter on derived classes. This version was simplified version of actual proposed solution.
  • 65. Type classes Expression problem can be solved by using type classes Haskell was the first language to introduce type classes. They are supported by Scala with the help of implicits.
  • 66. Example sealed trait Exp case class Lit(value: Int) extends Exp case class Add(left: Exp, right: Exp) extends Exp object ExpEvaluator { def eval(exp : Exp): Int = exp match { case Lit(value) => value case Add(left, right) => eval(left) + eval(right) } }
  • 67. We would like to convert Expression to Json. object JsonWriter { def write(value: JsonValue): String = // ... def write(value: Exp) = // ... } But, we should be able to use JsonWriter for any object not just Expressions.
  • 68. How about this trait JsonConvertible { def toJson: JsValue } sealed trait Exp extends JsonConvertible object JsonWriter { def write(value: JsonValue): String = // ... def write(value: JsonConvertible) = write(value.toJson) }
  • 69. This works. JsonWriter.write(Add(Lit(2), Lit(3))) But wait! .. Why the Expression class needs to know anything about Json. We would like to remove the Expression dependency on JsonCovertible. This implementation is also called as Subtype Polymorphism
  • 70. We can solve the coupling problem by introducing a Type class as follows // type class trait JsonConverter[A] { def convertToJson(value: A): JsonValue } object JsonWriter { def write(value: JsonValue): String = // ... def write[A](value: A, conv: JsonConverter[A]) = write(conv.convertToJson(value)) }
  • 71. We need to implement a convertor. def expJsonConverter = new JsonConverter[Exp] { def convertToJson(exp: Exp): JsonValue = { ... } } JsonWriter.write(Add(Lit(2), Lit(3)), expJsonConverter) This removed the coupling between Exp and Json. But we have to pass in a parameter, which can quickly become complex for Composite type.
  • 72. Scala implicits can help here. implicit def expJsonConverter = // ... def write[A](value: A)(implicit conv: JsonConverter[A]) = write(conv.convertToJson(value)) JsonWriter.write(Add(Lit(2), Lit(3))) Implicits parameters are passed in by the Compiler. The call is now exactly like when JsonCovertible was used.
  • 73. More about Type classes Type classes provide something called as Ad-hoc polymorphism. Type classes allow you to add new functionality to the existing Types, without changing them. Note, they are different than extension methods. Like extension method, they do not attach themself to the type they are working on.
  • 74. More about Type classes Type classes provide polymorphism on their type parameters. Interfaces in OO, provide polymorphism over the calling object. Type classes can accept more than one type parameters and hence can provide polymorphism on two different type parameters. This is not possible for interfaces.
  • 75. More about Type classes Compiler picks-up the right type classes on the type parameter. So unlike interfaces, implementation is chosen at compile time Type classes depend on their type parameters and not with the object so they are more like Generic Static Method.
  • 76. Solving Expression Problem with Type classes trait Exp case class Lit(value: Int) extends Exp case class Add[A <: Exp, B <: Exp](left: A, right: B) extends Exp [A <: Exp] is same as <A extends Exp> in Java
  • 77. Define type class and implicit implementations // type class trait Eval[E] { def eval(e: E): Int } implicit def litEval = new Eval[Lit] { def eval(l: Lit) = l.value }
  • 78. Implementation for Add is little complex. implicit def addEval[A <: Exp, B <: Exp] (implicit e1: Eval[A], e2: Eval[B]) = { new Eval[Add[A, B]] { def eval(a: Add[A, B]) = e1.eval(a.left) + e2.eval(a.right) } } The method takes two implicit arguments to evaluate left and right exp. In, Add[A, B], A and B are type of Exp which can be Add or Lit
  • 79. Evaluating the Expressions def expressionEvaluator[A <: Exp] (exp: A)(implicit e : Eval[A]) = { e.eval(exp) } Lets use it to evaluate something // (1 + 2) + 3 val exp1 = Add(Add(Lit(1), Lit(2)), Lit(3)) println("" + expressionEvaluator(exp1)) // output => 6
  • 80. Let add a new type case class Mult[A <: Exp, B <: Exp] (left: A, right: B) extends Exp Define an Implicit evaluator for Mult (same as Add) implicit def mulEval[A <: Exp, B <: Exp] (implicit e1: Eval[A], e2: Eval[B]) = { new Eval[Mult[A, B]] { def eval(m : Mult[A, B]) = e1.eval(m.left) * e2.eval(m.right) } }
  • 81. This will allow us to evaluate Expression with Mult // (3 + 4) * 7 val exp2 = Mult(Add(Lit(3), Lit(4)), Lit(7)) println("" + expressionEvaluator(exp2)) // output => 49 Lets try to add new operation like Print.
  • 82. Type class for Print operation // type class trait Print[P] { def print(p: P): Unit } Implicit implementation for Lit type implicit def litPrint = new Print[Lit] { def print(l: Lit) = Console.print(l.value) }
  • 83. Similarly implicit implementation for Add and Mult implicit def addPrint[A <: Exp, B <: Exp] (implicit p1: Print[A], p2 : Print[B]) = { new Print[Add[A, B]] { def print(a : Add[A, B]) = { p1.print(a.left); Console.print(" + "); p2.print(a.right); } } Implementation for Mult is exactly same.
  • 84. Define a method to print the expression def printExpressions[A <: Exp] (exp : A)(implicit p : Print[A]) = { p.print(exp) } Use it to print the expressions. // (3 + 4) * 7 val exp2 = Mult(Add(Lit(3), Lit(4)), Lit(7)) printExpressions(exp2) // output => 3 + 4 * 7
  • 86. ● In General: Easier than OO (without FP) ○ Pure Functions are almost trivial to test. ○ No Side-effects ⇒ No additional states ○ Higher Order Functions can be mocked easily. ● But what about TDD? How do you approach TDD for Functional Programming? Testing Functional Programming
  • 87. Transformation Priority Premise ● What is a Transformation? ● Let’s talk about Refactoring. “Uncle Bob”, My Hero Robert C. Martin →
  • 88. Refactoring “Refactoring is changing the structure of code without significantly changing its behavior.” ‒ Robert C. Martin
  • 89. Transformation “Transformation is changing the behavior of code without significantly changing its structure.” ‒ Robert C. Martin
  • 90. Transformation Priority Premise ({} → nil) no code at all -> code that employs nil (nil->constant) (constant → constant+) a simple constant to a more complex constant (constant → scalar) replacing a constant with a variable or an argument (statement → statements) adding more unconditional statements. (unconditional → if) splitting the execution path (scalar → array) (array → container) (statement → recursion) (if → while) (expression → function) replacing an expression with a function or algorithm (variable → assignment) replacing the value of a variable
  • 91. Beyond FP ● FP and OO are NOT mutually exclusive ● FOOP - Functional Object Oriented Programming ● Logic Programming
  • 94. TODO Testing ● Testing Pure First-Order Functions ● Testing Pure Higher-Order Functions ○ Mocking in FP ● Transformation Priority Premise for FP ○ Example how to develop from Base Case to N-Case
  • 95. List Implementation - optional package mylist sealed trait List[A] { def ::(e: A): List[A] = mylist.::(e, this) def :::(l: List[A]): List[A] = ??? } case object Nil extends List[Nothing] case class ::[A](h: A, tail: List[A]) extends List[A]
  • 96. Topic List [P] Side Effects Continued [C] Recursion [P] Algebraic Datatypes [P] Pattern Matching [P] Expression Problem [C] Streams in Java (creation, consumption, filtering, map, reduce etc.) [P] Streams in Scala (creation, consumption, filtering, map, reduce etc.) [C] Testing in Functional Programming (TDD for FP, BDD, TPP for FP) Monads Monoids Functors Applicatives F-Bounded Types
  • 97. Recursion TODO ● Replacing Assignments with Calls ● Replacing Loops with Recursion ● Developing Recursive Algorithms ○ Base Case / Most Degenerate Case ○ N-Case ○ List-Variants: Empty, 1 Element, Multiple ○ Head-Tail-Recursion vs Partition Recursion ● Tail-Recursion ○ Why ○ How to convert normal recursion into tail recursion (example: factorial) by introducing a result parameter ○ Examples in C with Disassemblies by GCC, clang, armcc, c251 ○ Example in Prolog ○ Example in Scala ○ Example in Clojure ○ Limitations in Java