functional programming concepts for imperative programmers

of 36 /36
IMPERATIVELY FUNCTIONAL Functional Programming Concepts for Imperative Programmers chris lewis / http://twitter.com/burningodzilla http://github.com/chrislewis

Post on 12-May-2015

3.164 views

Category:

Technology

Embed Size (px)

DESCRIPTION

Inaugural presentation on functional programming for the JaxFunc meetup.

TRANSCRIPT

IMPERATIVELY FUNCTIONAL

Functional Programming Concepts

for Imperative Programmers

Origins: The λ-Calculus

Origins: The λ-Calculus

Developed at Princeton in the 1930s by Alonzo Church (and others).

Formal system for function definition, application, and recursion.

Not focused on the physical world, but abstract problems about computation.

Origins: The λ-Calculus

Functions may receive functions as parameters and return functions as results.

A lambda may “close” over free variables to create a closure.

Turing complete.

Origins: The λ-Calculus

Functions may receive functions as parameters and return functions as results.

A lambda may “close” over free variables to create a closure.

Turing complete.

true := λxy.xfalse := λxy.yif-then-else := λpab.p a b

Origins: Lisp

Developed at MIT by John McCarthy. An Implementation of the λ-calculus. Uniform treatment of data and functions;

higher-order functions.

Origins: Lisp

Extensive use of lambda expressions, closures, and recursion.

In Lisp, as any programming language supporting them, lambdas are functions.

Origins: Lisp(define (is-even? x) (= 0 (modulo x 2)))

(define (when-even x f1 f2) (if (is-even? x) (f1 x) (f2 x)))

(define (down-to-one x) (if (<= x 1) x (down-to-one (- x 1))))

(when-even 4 down-to-one (lambda (x) (+ x 1)))

There are many facets of functional programming.

We will focus primarily onhigher-order functions and thetreatment of functions as data.

Functions are Datavar increment = function(i) { return i + 1;}

var square = function(i) { return i * i;}

function doSomething(i, f) { return f(i);}

Functions are DatadoSomething(5, increment);// -> 6

doSomething(5, square);// -> 25

Functions are Dataval increment = (i: Int) => i + 1

val square = (i: Int) => i * i

def doSomething[A, B](x: A, f: A => B) = f(x)

doSomething(5, increment)// -> 6

doSomething(5, square)// -> 25

Notes on Lambdas A lambda is an anonymous function; a

function without an identifier. A closure is a function whose definition

“closes” over free variables.

Notes on Lambdas A lambda expression that doesn’t close

over free variables isn’t a closure, strictly speaking.

A closure isn’t necessarily anonymous! Closures enable function composition …

… and that’s a big deal!

λ: In Programming Languages

JavaScript has named and anonymous function expressions, as well as Function objects (with a constructor).

Ruby most notably has blocks, but also lambdas (keyword) and procs!

Scala has methods, function traits, and shorthand yielding trait instances.

How a programming language refers to such a construct is entirely preferential.

Function Composition

com·po·si·tion -noun1. the act of combining parts or elements to form a whole2. the resulting state or product3. manner of being composed;structure: This painting has an orderlycomposition.

com·po·si·tion -noun1. the act of combining parts or elements to form a whole2. the resulting state or product3. manner of being composed;structure: This painting has an orderlycomposition.

Let’s glance back at the math…

Function Composition

y = f(x) or f: x → y “y is a function of x”

The value of y depends on x; a simple mapping from one value, x, to another, y.

Function Composition

y = f(x) or f: x → y “y is a function of x”

The value of y depends on x; a simple mapping from one value, x, to another, y.

f: x → y and g: y → z The domains of these functions are

suitable for composition.

Function Composition

We can combine functions with compatible domains.

Function Composition

We can combine functions with compatible domains.

(g . f) = g(f(x)) or (g f) = g(f(x))∘ Combine the functions g and f into

a new function that applies g to the result of applying f to x.

Function Composition

We can combine functions with compatible domains.

(g . f) = g(f(x)) or (g f) = g(f(x))∘ Combine the functions g and f into

a new function that applies g to the result of applying f to x.

Back to the code!

In JavaScript:

function compose(f, g) { // a closure, closing over the free // variables f and g return function(x) { return g(f(x)); }}

// recursive implementation:// http://gist.github.com/366614

In Scala:

def compose[A, B, C](g: B => C, f: A => B) = (x: A) => g(f(x)) // the closure

Higher-Order Functionsand Lists A function that takes another function as

an argument and/or returns a function as its result.

Ruby, via Rails, brought higher-order functions that operate onlists mainstream.

Higher-order rockstars:each, map, filter, fold many more!

Because we know how to pass functions around, we know how to implement these …

Because we know how to pass functions around, we know how to implement these …

… but we’ll probably duplicate code.

Because we know how to pass functions around, we know how to implement these …

… but we’ll probably duplicate code.

In JavaScript:

function foldr(list, init, f) { if(list.length == 0) return init; else { return foldr(list.slice(1), f(init, list[0]), f); }}

In Scala:

def foldr[A, B](list: List[A], init: B, f: (B, A) => B): B = list match { case Nil => init case head :: tail => foldr(tail, f(init, head), f) }

Some List Functions That can be Defined in Terms of Folding

sum = foldr (+) 0 product = foldr (*) 1 anytrue = foldr ( ) false∨ alltrue = foldr ( ) true∧ map = foldr (cons . f) []

By partially applying folds, we can define new list functions with very little programming!

Real-World Examples

Higher-order functions pay dividends (strategy pattern, factory, factories of factories, …)

“loan” pattern. Event handling in the Lift framework. List tasks (partitioning, filtering,

transforming).

What we Didn’t Cover

Currying Pattern matching Type inference, higher-kinded types,

and general type systems Partial function application Monads Lazy vs strict evaluation MORE!

Questions?

Sample code available at http://github.com/chrislewis/JaxFunc_0_ImperativelyFunctional

Thanks!