3. A Sceptical Guide to
Functional Programming
Garth Gilmour (garth.gilmour@instil.co)
4. In the Belfast IT Forum BASH the audience are
entertained by two separate and unequal types of
presenter. World class experts who understand the
topic they are presenting on and uninformed dilettantes
who mither on about stuff they barely understand.
This is the latter
5.
6.
7. This is a Sceptical Roadmap
Personally I really like FP
Not so sure about FP programmers
Some things I’m going to say will really annoy
any FP purists out there...
8. Don't program
in Java!!
Why not?
Its restrictive – everything
has to be an object!!
What should
I use?
9. Program in
Lisp!!
Why?
Its brilliant – everything
has to be a list!!!!
Erm.....
10. Or better yet
Haskell!!
Why?
Its brilliant – you cant do
anything except pure math!!!!
Right...bye....
24. I Like Scala...
package demos.scala.classes.basic
class Employee(val name : String,
val age : Int,
val salary : Double)
$ javap -private demos.scala.classes.basic.Employee
Compiled from "Employee.scala"
public class demos.scala.classes.basic.Employee
extends java.lang.Object
implements scala.ScalaObject{
private final java.lang.String name;
private final int age;
private final double salary;
public java.lang.String name();
public int age();
public double salary();
public demos.scala.classes.basic.Employee(java.lang.String, int, double);
}
25.
26.
27.
28. A Quick Word On Clojure
A LISP with more syntax than ((( )))
Dynamically typed and mostly functional
Integrates fully with the JVM/CLR
Extensive support for concurrency
Via efficient but immutable collections
39. What Makes this Functional?
Functional Composition
Immutable State
First Class Functions
Internal Iteration
Declarative Feel
Use of a DSL
42. You Are Doing FP Already (Kinda)
If you program in:
XSLT (my favourite language)
JavaScript (esp. if you use JQuery, Dojo etc…)
C# from VS2008 onwards (esp. LINQ)
Java (believe it or not…)
If you use libraries like Guava / Google Collections
If you follow certain coding conventions / best practises
Ruby or Python
Then you are already using FP techniques
Even if you don’t already know it
43. Is XSLT a Functional Language?
<xsl:template match="title">
<header>
<h1><xsl:value-of select="text()"/></h1>
</header>
</xsl:template>
<title>Introduction to Java</title> <header>
<h1>Introduction to Java</h1>
</header>
44. Is XSLT a Functional Language?
Stylesheet
? Output Tree
Input Tree
XSLT Engine
?
?
45.
46. LINQ is a Functional Technology
Query
Expression Tree
LINQ to SQL
C# Compiler
Plug-In
?
60. The Road Not Taken...
The newest version of the Microsoft Visual J++ development environment supports a language
construct called delegates or bound method references…
It is unlikely that the Java programming language will ever include this construct. Sun already
carefully considered adopting it in 1996, to the extent of building and discarding working
prototypes. Our conclusion was that bound method references are unnecessary and detrimental
to the language…
We believe bound method references are unnecessary because another design alternative, inner
classes, provides equal or superior functionality. In particular, inner classes fully support the
requirements of user-interface event handling, and have been used to implement a user-interface
API at least as comprehensive as the Windows Foundation Classes.
We believe bound method references are harmful because they detract from the simplicity of the
Java programming language and the pervasively object-oriented character of the APIs….
Extracts From: About Microsoft’s “Delegates"
Whitepaper by the Java language team at JavaSoft
61.
62. private void demoTemplatesAndCallbacks(HibernateTemplate template) {
String query = "select delivery.course.title from Delivery delivery";
List titles = template.executeFind(new QueryCallback(query));
System.out.println("Courses being delivered are:");
for(Object title : titles) {
System.out.printf("t%sn",title);
}
}
public class QueryCallback implements HibernateCallback {
public QueryCallback(String query) {
this.queryStr = query;
}
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
Query query = session.createQuery(queryStr);
return query.list();
}
public String queryStr;
}
63. private void demoTemplatesAndCallbacks(HibernateTemplate template) {
String query = "select delivery.course.title from Delivery delivery";
List titles = template.executeFind((s) => s.createQuery(query).list());
System.out.println("Courses being delivered are:");
titles.forEach((t) => System.out.printf("t%sn",title));
}
73. class Person {
public String toString() {
StringBuilder sb = new StringBuilder(); Person earning
sb.append(“Person earning ”); 5000.0 with tax of
sb.append(salary.calcMonthlyBasic()); 763 and pension
sb.append(“ with tax of ”);
payment of 469.0
sb.append(salary.monthlyTax());
sb.append(“ and pension payment of ”);
sb.append(salary.monthlyPension());
return sb.toString();
} class Person {
private Salary salary; public String toString() {
} StringBuilder sb = new StringBuilder();
sb.append(“Person earning ”);
sb.append(5000.0);
Person earning sb.append(“ with tax of ”);
5000.0 with tax of sb.append(salary.monthlyTax());
sb.append(“ and pension payment of ”);
0 and pension
sb.append(salary.monthlyPension());
payment of 0 return sb.toString();
}
private Salary salary;
}
74. What's The Use?
Code is easier to reason about.
Compilers & VM’s can partition code automatically
into sections and run them in parallel.
Lazy Evaluation
if(foo() && bar()) { func(foo(), bar());
zed(); -------------------------------
} void func(a, b) {
if(zed()) {
if(foo() || bar()) { c = a + 1; //foo not called till here
zed(); }
} }
79. Another reason that you might be interesting in purity is that it
gives you a better handle on parallelism. It doesn't make
parallelism easy, but it kinda makes it feel a bit more within
reach.
...
I dont think its parallelism without tears, but it kinda gives you
a chance in a way that the imperative by default with shared
mutable state makes things very difficult.
Simon Peyton Jones
(On SE Radio Ep 108)
80. But all a purely functional program
can do is heat up the CPU - and
that's still a side effect!!!
90. int foo(int a) { int foo(int a) {
int b = zed(); int b = zed();
if(b > a) { if(b > a) {
return a + foo(b); return foo(a + b);
} else { } else {
return b; return 1;
} }
} }
a
b
a
b
a
a
b
b
a
b
93. def processItem(item : StockItem) {
item match {
case Book(_,"Crime") => println("Found a crime novel")
case Movie(_,MovieType.DVD) => println("Found a DVD movie")
case CD(_,_,12) => println("Found a CD with 12 tracks")
case CD(_,"Soundgarden",_) => println("Found a CD by Soundgarden")
case Book(_,_) => println("Found some kind of book")
case _ => println("Found something...")
}
}
95. Monads By Metaphor
int pthread_create(pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine) (void *),
void *arg);
96. Monads By Quotation
Monads turn control flow into data
flow, where it can be constrained
by the type system.
Oleg Kiselyov
97. Monads By Example
Monads remove the boilerplate involved when
extracting / inserting values from “Amplified Types”
Whilst enabling the compiler to perform extra checks
Kind of like AOP but without the runtime overhead
List<T>
Map<T,U>
Option<T> (aka Maybe<T>)
EntityManager<T>
Repository<T>
ThreadSafe<T>
IO<T>
100. class Person(val name : String, val address : Address) {
def findAddress() : Option[Address] = {
if(address == null) {
None
} else {
Some(address)
}
}
}
101.
102. def printPostcodeIfExists(person : Person) {
println("Working with " + person.name)
for (
place <- person findAddress;
code <- place findPostcode;
result <- code findValue
) println(result)
}
105. One Final Thought...
OO makes code understandable by
encapsulating moving parts. FP makes
code understandable by minimizing
moving parts.
Michael Feathers
106. To Summarize...
You can start doing this today
Get familiar with the FP parts of your language
Prefer internal iteration to explicit loops
Play with making sections of code side-effect free
Experiment with building functional machines
Use the emerging support for ‘hands-free’ concurrency
Review, measure, assess, adjust
Make this years new language an FP one
Try Scala to extend what you already know into FP
Try Clojure, F# or Haskell to get a new perspective