Top Banner
Functional Programming Past, Present and Future Pushkar N Kulkarni IBM Runtimes IBM India Software Lab
56

Functional Programming - Past, Present and Future

Apr 16, 2017

Download

Software

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Functional Programming - Past, Present and Future

Functional ProgrammingPast, Present and

FuturePushkar N Kulkarni

IBM RuntimesIBM India Software Lab

Page 2: Functional Programming - Past, Present and Future

Functional Programming - today’s special …

• Timeline – parallel to the imperative timeline

• Languages• Concepts

Goal: Bootstrapping for functional programming

Page 3: Functional Programming - Past, Present and Future

The beginning of all creation …

Page 4: Functional Programming - Past, Present and Future

Theory of Computation <- Math + Logic

Alonzo ChurchLambda Calculus

Alan TuringTuring Machine

Stephen KleeneRecursive Function

Theory

Page 5: Functional Programming - Past, Present and Future

Lambda Calculus

It’s a formal system in mathematical logic for expressing computation based on function abstraction and application using variable binding and substitution. ~ Wikipedia

Page 6: Functional Programming - Past, Present and Future

Lambda Calculus – Fundamental Idea

x //variable

t //lambda term

Λx.t //lambda abstraction

Λx. x2+1 // x is bound in t by Λx

Λx. x2+1(2) = 22+1 = 5 //application

Note: A lambda abstraction has no name

Page 7: Functional Programming - Past, Present and Future

LISP - 1958

LIST Processor

Influenced by Church’s lambda calculus notation

Multi-paradigm, pre-fix notation

John McCarthy

Page 8: Functional Programming - Past, Present and Future

LISP;;Employee compensation

(defun total (bonus-calc base) (+ (funcall bonus-calc base) base))

;; Good month

(total #'(lambda (x)(* 0.8 x)) 10000)

;; Bad month

(total #'(lambda (x)(+ (* 0.2 x) 10)) 10000)

Page 9: Functional Programming - Past, Present and Future

LISP – Well known dialects

• Scheme – 1970• Common Lisp – 1984• Racket – 1984• Clojure – 2007• Lisp Flavoured Erlang (LFE) – 2008 (v1

March 2016)

Page 10: Functional Programming - Past, Present and Future
Page 11: Functional Programming - Past, Present and Future

Academic Research (1960 – 1985)

• ISWIM – If You See What I Mean – 1966• SASL – St. Andrews Static Language – 1972• ML – MetaLanguage – 1973 => Ocaml, F#• Miranda – 1985 => Haskell

Page 12: Functional Programming - Past, Present and Future

Back to some Lambda Calculus

F(x) = x3+4x //F(x) id a first-order function

//maps values to values

dF(x)/dx = 3x2 + 4

//d/dx maps functions to functions

d/dx is an example of higher-order functions

Page 13: Functional Programming - Past, Present and Future

Higher-order Functions

A function is a higher-order function if:• It takes at least one function as an argument OR• It returns a function

All other functions are first–order functions!

Page 14: Functional Programming - Past, Present and Future

Erlang - 1984

Designed for massive scalable soft real time systems

Fault-tolerance and concurrency

Page 15: Functional Programming - Past, Present and Future

Erlang

Multi-paradigm, but has a functional core•First-class functionsFunctions can be passed to functionsFirst-class citizens=> Higher-order functions•Immutable valuesImmutable “variables” – creating new values insteadMinimizing moving parts has benefits

Page 16: Functional Programming - Past, Present and Future

Erlang – Higher-order functions%base salaries

S = [10000, 30000, 40000, 15000].

%The Bonus calculator

Bonus = fun(X)-> X + X*0.2 + 1500 end.

%Total salaries

T = lists:map(Bonus, S)

>> [13500, 37500, 49500, 19500]

Page 17: Functional Programming - Past, Present and Future

Erlang – Higher-order functions

%find total salaries exceeding 30000

MoreThan30K = fun(Y) -> Y > 30000 end.

lists:filter(MoreThan30K,T).

>> [37500, 49500]

You just learnt “map” and “filter”. Let them sink in!

Page 18: Functional Programming - Past, Present and Future

Haskell - 1990

• Full blown functional language• Algebraic data types and type classes• No statements – the entire program is an

”expression”• Pattern matching• Lazy evaluation• Purely functional – functions have no side effect

Page 19: Functional Programming - Past, Present and Future

Haskell – Algebraic Data Types (ADT)

• Derived from Type Theory• A composite type - formed by combining

other types

data List a = Nil | Cons a (List a)

data Tree a = Node a (Tree a) (Tree a) | Nil

Page 20: Functional Programming - Past, Present and Future

Haskell – Pattern Matching

-- construct a List from an list

makeList (x:xs) = Cons x (makeList xs)

makeList [] = Nil

-- construct an list from a List

makeArr (Cons x (xs)) = x:(makeArr xs)

makeArr Nil = []

Page 21: Functional Programming - Past, Present and Future

Quiz

Why was the language named Haskell?

Page 22: Functional Programming - Past, Present and Future

Haskell Curry (1900 – 1982)

Page 23: Functional Programming - Past, Present and Future

Currying

Introduced by Shönfinkel

Lambda calculus deals with single argument functionsWhat about multiple argument functions then?

If F(X, Y, Z) -> N, then

curry(F): X -> (Y -> (Z -> N))

Page 24: Functional Programming - Past, Present and Future

Lambda Calculus - Currying

F(X, Y, Z) = X + Y + Z

F(1, 2, 3) = Fcurried(1)(2)(3)

//apply only one argument at a time

Fcurried (1) = F’curried

F’curried(2) = F”curried

F”curried(3) = 6

Page 25: Functional Programming - Past, Present and Future

OCaml - 1996

• Multi-paradigm• Derived from ML• Static type system helps eliminate runtime

problems• Emphasis on performance – good

optimizing compiler

Page 26: Functional Programming - Past, Present and Future

Currying in OCaml# let plus x y z = x + y + z;;

# plus 1 2 3;;

- : int = 6

# let x = plus 1;;

val x : int -> int -> int = <fun>

Page 27: Functional Programming - Past, Present and Future

Currying in OCaml# let y = x 2;;

val y : int -> int = <fun>

# y 3;;

- : int = 6

Cool, but what’s the use of all this?

Page 28: Functional Programming - Past, Present and Future

Currying in OCamlFunction to add 2 to all numbers of a listlet add2 x = x + 2

List.map add2 [1;2;3;4;5];;

Function to add 3 to all numbers of a listlet add3 x = x + 3

List.map add3 [1;2;3;4;5];;

Page 29: Functional Programming - Past, Present and Future

Currying in OCaml

With currying:let add x y = x + y

List.map (add 2) [1;2;3;4;5]

List.map (add 3) [1;2;3;4;5]

•Better reuse of code•Improved readability

Page 30: Functional Programming - Past, Present and Future

Quiz

What significant event occurred around 1995 in the Programming

Languages space?

Page 31: Functional Programming - Past, Present and Future

Functional Programming on the JVM

(2004 – date)• Groovy - 2003• Scala - 2004• Clojure - 2007• Java 8 - 2014

Page 32: Functional Programming - Past, Present and Future

Scala

• Seamless integration with Java

• Combines object oriented programming and functional programming

• Type inference• Higher order functions• Pattern matchingMartin

Odersky

Page 33: Functional Programming - Past, Present and Future

Scala

Simple functional code to find the length of a list:(no loops in functional programming!)def listLength (list: List[_]): Int = list match { case Nil => 0 case _ => 1 + listLength(list.tail)}

Any problems here?

Page 34: Functional Programming - Past, Present and Future

Scala

listLength(List.Range(0, 100000))

>> StackOverflow

Are loops better than recursive calls then?Has functional programming hit a barrier here?

Page 35: Functional Programming - Past, Present and Future

Scala - TCONo! You have tail recursion and tail-recursion optimization (TCO)def length(as: List[_]): Int = { @tailrec def length0(as: List[_], count: Int = 0): Int = as match { case Nil => count case head :: tail => length0(tail, count+ 1)

} length0(as)

}

Page 36: Functional Programming - Past, Present and Future

Scala - TCOSimplistic essence of tail-call optimization

Execution state

Single, reusablestack frame

Page 37: Functional Programming - Past, Present and Future

Clojure - 2007Our fascination with LISP is never ending!

Rich Hickey

• LISP for the JVM

• Java-Clojure interoperability

• Other implementations – ClojureScript, ClojureCLR

• Used in creative computing!

Page 38: Functional Programming - Past, Present and Future

Clojure(defn fib[n](condp = n 0 1 1 1 (+ (fib (- n 1)) (fib (- n 2)))))

user=> (time (fib 40))

"Elapsed time: 2946.136757 msecs"

165580141

user=> (time (fib 40))

"Elapsed time: 2882.10746 msecs"

165580141

Page 39: Functional Programming - Past, Present and Future

Clojure

Pure functions•Referential Transparency•No side effects – stateless programs•Given an argument, the function must return the same value! (fib 4) is always 3, for example. => Values (fib K) can be reused for all KSpeed up? Caching?

Page 40: Functional Programming - Past, Present and Future

Clojure - Memoization

(def m-fib(memoize (fn [n] (condp = n

0 1

1 1

(+ (m-fib (- n 1)) (m-fib (- n 2)))))))

Page 41: Functional Programming - Past, Present and Future

Clojure - Memoization

user=> (time (m-fib 40))

"Elapsed time: 0.823773 msecs"

165580141

user=> (time (m-fib 40))

"Elapsed time: 0.082013 msecs"

165580141

Page 42: Functional Programming - Past, Present and Future

Java 8 - 2014

The exciting times begin!•Lambdas•Stream Interface – lazy evaluation!•Functional Interfaces•Default methods – for backward compatibilityA mammoth like Java embracing the functional paradigm is a big cue about the times to come.

Page 43: Functional Programming - Past, Present and Future

Lazy Evaluation

Laziness is not always bad

Page 44: Functional Programming - Past, Present and Future

Lazy Evaluation

• Evaluate an expression only when it’s use is encountered

• Values are created only when needed• Reduction in memory footprint• Fast• In combination with memoization, results in

very efficient functional code

Page 45: Functional Programming - Past, Present and Future

Problem

Find the number of first deliveries of overs, when a batsman who scored at least five centuries and hit at least 100 sixes, was out.

Page 46: Functional Programming - Past, Present and Future

Java 8 – Lazy EvaluationallDeliveries.stream()

.filter(d -> d.deliveryNumber() == 1)

.filter(d -> d.wicket())

.map(d -> d.getBatsman())

.filter(b -> b.totalCenturies() >= 5)

.filter(b -> b.totalSixes >= 100)

.count() //terminal operation

•Lambdas•Immutability•Lazy evaluation, terminal operation•Map/filter

Page 47: Functional Programming - Past, Present and Future

Java 8 - ParallelismParallel execution. Almost zero change to your code.allDeliveries.parallelStream()

.filter(d -> d.deliveryNumber() == 1)

.filter(d -> d.wicket())

.map(d -> d.getBatsman())

.filter(b -> b.totalCenturies() >= 5)

.filter(b -> b.totalSixes >= 100)

.count() //terminal operation

Page 48: Functional Programming - Past, Present and Future

Java 8• No intentions of becoming a full blown

functional language• Lambdas and lazy evaluation provide a big

boost• Readability improved – anonymous classes

not needed• Reusability improved – lambdas, functional

interfaces• Java 9 – better Stream interface expected

Page 49: Functional Programming - Past, Present and Future

Idris – A peek into the future

• Data types are first class objects!• You can generate data types, store them, pass

them around• Dependent types were developed by Haskell

Curry to deepen the connection between programming and logic (Curry-Howard correspondence)

• Dependent types – types that depend on values!• Influenced by Agda

Page 50: Functional Programming - Past, Present and Future

Idris – dependent typesListType : (singleton : Bool) -> Type

ListType False = List Nat

ListType True = Nat

sumList : (singleton : Bool)->ListType singleton->Nat

sumList False (x :: xs) = x + sumList False xs

sumList False [] = 0

sumList True x = x

Page 51: Functional Programming - Past, Present and Future

Why Functional Programming• Higher levels of behavioural abstraction –

tell what is to be done, not how to do it• Agile Methodologies - Code reuse,

readability• Correctness• Exploiting massively parallel hardware

Page 52: Functional Programming - Past, Present and Future

Challenges• Paradigm shift in thinking needed• Newer design patterns – no imperative

design patterns • Performance evaluation difficult – recursive

data structures, recursive functions• Runtime performance – garbage collection

critical

Page 53: Functional Programming - Past, Present and Future

Recap

• Lambda Calculus• Lambdas• First-class functions, higher order functions• Algebraic data types• Pattern matching• Currying

Page 54: Functional Programming - Past, Present and Future

Recap

• Tail-call recursion and TCO• Pure functions, referential transparency• Memoization• Lazy evaluation• Parallelism• Dependent data types

Page 55: Functional Programming - Past, Present and Future

A programming language that does not change the way you think is not worth knowing ~ Alan Perlis

Functional programming changes the way you think.

It’s worth knowing!

Page 56: Functional Programming - Past, Present and Future

(Thank you!)

(twitter @pushkar_nk)(github pushkarnk)