Functional Programming Scott Sauyet

An Overview of Functional Techniques

(for non FP'ers) using Javascript Agenda What is Functional Programming?

How Functional Programming Differs From Other Paradigms

Functional Programming in Javascript

Advantages and Disadvantages of Functional Style

Interaction of Functional and Object-Oriented Styles

What is Functional Programming? No Single Definition There is no clear, widely-accepted definition of Functional Programming. It is a collection of related featues which cohere well into a very useful style of programming. Some of these features are readily available in Javascript.

Others can be used if care is taken.

And some are essentially impossible at the language level.

Chief difference between OOP and FP Reg Braithwaite has a good description of the central difference between these two paradigms. OO focuses on the differences in the data, while FP concentrates on consistent data structures. Object-Oriented Data and the operations upon it are tightly coupled

Objects hide their implementation of operations from other objects via their interfaces

The central model for abstraction is the data itself

The central activity is composing new objects and extending existing objects by adding new methods to them Functional Data is only loosely coupled to functions

Functions hide their implementation, and the language’s abstractions speak to functions and the way they are combined or expressed

The central model for abstraction is the function, not the data structure.

The central activity is writing new functions

What does this mean in the business environment? Is one of these techniques the clear-cut winner in the business world? Is it functional or object-oriented? Are you sure?

How much business logic is written like this? SELECT orders.order_id, orders.order_date, suppliers.supplier_name FROM suppliers RIGHT OUTER JOIN orders ON suppliers.supplier_id = orders.supplier_id WHERE orders.order_status = 'INCOMPLETE' ORDER BY orders.order_date DESC;

SQL is very similar to functional languages, and it permeates business. It uses a consistent data structure (tables with records organized into columns) and a few basic functions that can be combined into arbitrary queries. And it shares one other important feature with functional languages: it is declarative.

Declarative vs Imperative Programming One main distinguishing characteristics of functional programming languages is that they describe what they want done, and not how to do it. OO, inside its methods, still uses mostly imperative techniques. Imperative style var sumOfSquares = function(list) { var result = 0; for (var i = 0; i < list.length; i++) { result += square(list[i]); } return result; }; console.log(sumOfSquares([2, 3, 5])); Functional style var sumOfSquares = pipe(map(square), reduce(add, 0)); console.log(sumOfSquares([2, 3, 5]));





Functional Features in Javascript Easily available in Javascript First-class functions

Lambdas/Anonymous Functions with closures

Compact, even terse, functions Possible to accomplish in Javascript with some care Mostly stateless processing

Side-effect-free function calls

Not available in current versions Javascript Performant recursion through tail call optimization

Pattern matching (Haskell, Erlang)

Lazy Evaluation (Miranda, Haskell)

Homoiconicity (mostly LISP-like languages?) We will take a look a brief look at these functional programming features of other languages first, then turn our focus to those things we can actually accomplish in Javascript.

Shared Example Following an example from Paul Barry we will use the example of the chances of winning a lottery. This calculates the odds of choosing the correct `n` numbers out of the `p` possibilities. Here is an iterative version of the code: function odds(n, p) { var acc = 1; for(var i = 0; i < n; i++) { acc *= (n - i) / (p - i); } return acc; } console.log(odds(3, 10)); //=> (3/10) * (2/9) * (1/8) => (1/120) => 0.008333...



Recursive Version This is similar, but written recursively: // Recursive version function odds(n, p) { return (n == 0) ? 1 : (n / p) * odds(n - 1, p - 1); } console.log(odds(3, 10)); //=> (3/10) * (2/9) * (1/8) => (1/120) => 0.008333...

There are many reasons that functional programmers prefer recursion, but one very simple one is that recursive functions are often much more elegant than their iterative cousins. It's easier to reason about them. Unfortunately, they often don't perform as well. All the overhead of creating stack contexts for function calls tends to add up. But certain kinds of recursive calls can be easily optimized.

This code in tail-call formulation: var odds = (function(){ var odds1 = function(n, p, acc) { return (n == 0) ? acc : odds1(n - 1, p - 1, (n / p) * acc); } return function(n, p) { return odds1(n, p, 1) } })();

Note that the recursive call in odds1 is the last statement in its branch of the function. If this is true for all recursive calls, then the function is tail-recursive , and the compiler can replace the entire set of nested calls with simple JUMP operations. Such optimizations are required by many functional languages. This is slated to become required in the next version of the specification for Javascript, but it won't be consistently available client-side for some time.

Pattern Matching Some languages make use of an interesting techniqe to define functions: pattern matching. Rather than use if-blocks in the body of the function, parameter-matching is used to choose which of a collection of related functions should be called. Here we can see it in Erlang. Simple recursive version odds(0, _) -> 1; odds(N, P) -> (N / P) * odds(N - 1, P - 1).

Tail-call version -export([odds/2]). odds(N, P) -> odds(N, P, 1). odds(0, _, Acc) -> Acc; odds(N, P, Acc) -> odds(N - 1, P - 1, (N / P) * Acc).

Lazy Evaluation Many of us are most familiar with languages that evaluate their expressions as soon as they're encountered. But there are some that wait until the last possible instant. This can have some real benefits. We'll switch examples here, as there's not much call to do lazy evaluation for lottery odds. We will follow a Haskell example from Chris Eidhof quickSort [] = [] quickSort (x:xs) = quickSort (filter (< x) xs) ++ [x] ++ quickSort (filter (>= x) xs) minimum ls = head (quickSort ls)

Note that the right half of quicksort is not calculated in finding the minimum. (Also note the pattern matching here too!) One very interesting comparison is that lazy evaluation is to the CPU what garbage collection is to memory. The garbage collector allows you to pretend that you have infinite memory; lazy evaluation allows you to pretend that you have infinite processing power. But there are many reasons to like lazy evaluation. It allows you to operate on theoretically infinite data structures, calculating only those parts you need. And it allows you to define your own efficient control structures inside the language instead of only at the level of the language syntax.



Homoiconicity No groaning. At one time you had to learn what polymorphism meant, too! homoiconicity homo: from the Greek homo, same

icon: from the Greek eikon, likeness, image, portrait

icity: from the Greek icit, extra letters to make words more pretentious

Homoiconicity in LISP-like languages Homoiconicity has to do with the fact that in some languages, programs are written in a format easily interpreted also as a data structure. In Scheme, the following is just a quoted list of three items, define , (square x) (itself a list), and (* x x) (another list) '(define (square x) (* x x))

But the following, which looks almost identical, is a function definition: (define (square x) (* x x))

LISP-like languages can use this feature to build very powerful domain-specific languages. Many would claim that this is the key feature that has allowed LISP to become the oldest language still in widespread use.

Functional Programming in Javascript With first-class function, closures, and anonymous functions, Javascript allows us to do a great deal of functional programming, even if we don't have things like pattern matching and homoiconicity. There are some tools built in to modern Javascript environments, and it's straightforward to roll your own. For the remainder of this talk, we will use the Ramda library that Michael Hurley and I have been developing. But there are a number of interesting alternatives available: allong.es is a fairly new functional combinators and decorators library

Lemonad is a general-purpose functional programming library

Lazy and Lz are libraries for lazy list processing

Underscore and its more performant clone, Lo-Dash, are general utility libraries with a number of functional capabilities

Functional Javascript, although perhaps outdated today, was the very first successful functional programming library for Javascript

Using Functional Techniques in Javacript We will approach functional programming by converting an imperative example into a functional one. We will also briefly examine an object-oriented approach, but we'll see that the code that we would like to address is very similar to the imperative one, just organized differently. Our example will be a Task List application, fetching something like the following data from the server: var data = { result: "SUCCESS", interfaceVersion: "1.0.3", requested: "10/17/2013 15:31:20". lastUpdated: "10/16/2013 10:52:39", tasks: [ {id: 104, complete: false, priority: "high", dueDate: "11/29/2013", member: "Scott", title: "Do something", created: "9/22/2013"}, {id: 105, complete: false, priority: "medium", dueDate: "11/22/2013", member: "Lena", title: "Do something else", created: "9/22/2013"}, {id: 107, complete: true, priority: "high", dueDate: "11/22/2013", member: "Mike", title: "Fix the foo", created: "9/22/2013"}, {id: 108, complete: false, priority: "low", dueDate: "11/15/2013", member: "Punam", title: "Adjust the bar", created: "9/25/2013"}, {id: 110, complete: false, priority: "medium", dueDate: "11/15/2013", member: "Scott", title: "Rename everything", created: "10/2/2013"}, {id: 112, complete: true, priority: "high", dueDate: "11/27/2013", member: "Lena", title: "Alter all quuxes", created: "10/5/2013"} // , ... ] };



Our Goal tasks: [ {id: 104, complete: false, priority: "high", dueDate: "11/29/2013", member: "Scott", title: "Do something", created: "9/22/2013"}, {id: 105, complete: false, priority: "medium", dueDate: "11/22/2013", member: "Lena", title: "Do something else", created: "9/22/2013"}, // , ... ]

The goal will be a function that accepts a `member` parameter, then fetches the data from the server (or from some application cache), chooses the tasks for that member that are not complete, returns their ids, priorities, titles, and dues dates, sorted by due date. Since the fetch from the server will likely be asynchronous, we'll hook everything together with promises, and our function will return a promise that should resolve to an array of objects with the required properties. For our illustrative purposes, we will ignore all error-checking concerns. Obviously in a production system, we would need to consider server-side failures, and bad data scenarios.

Sample Imperative Approach var getIncompleteTaskSummariesForMember_imperative = function(memberName) { return fetchData() .then(function(data) { return data.tasks; }) .then(function(tasks) { var results = []; for (var i = 0, len = tasks.length; i < len; i++) { if (tasks[i].member == memberName) { results.push(tasks[i]); } } return results; }) .then(function(tasks) { var results = []; for (var i = 0, len = tasks.length; i < len; i++) { if (!tasks[i].complete) { results.push(tasks[i]); } } return results; })

(continued on the next slide.)

Sample Imperative Approach (continued) .then(function(tasks) { var results = [], task; for (var i = 0, len = tasks.length; i < len; i++) { task = tasks[i]; results.push({ id: task.id, dueDate: task.dueDate, title: task.title, priority: task.priority }) } return results; }) .then(function(tasks) { tasks.sort(function(first, second) { return first.dueDate - second.dueDate; }); return tasks; }); };

Similar Object-Oriented Approach // main method var getIncompleteTaskSummariesForMember_objectOriented = function(memberName) { return fetchData() .then(function(data) { var taskList = new TaskList(data.tasks); taskList.chooseByMember(memberName); taskList.chooseByCompletion(false); var newTaskList = taskList.getSummaries(); newTaskList.sort(new TaskListSorter("dueDate")); return newTaskList.tasks; }); };

(continued on the next slide.)

Object-Oriented Approach (continued) var TaskList = (function() { var TaskList = function(/*Task[]*/ tasks) { this.tasks = tasks; }; TaskList.prototype.chooseByMember = function(memberName) { var results = []; for (var i = 0, len = this.tasks.length; i < len; i++) { if (this.tasks[i].member === memberName) { results.push(this.tasks[i]); } } this.tasks = results; }; TaskList.prototype.chooseByCompletion = function(completion) { var results = []; for (var i = 0, len = this.tasks.length; i < len; i++) { if (this.tasks[i].complete == completion) { results.push(this.tasks[i]); } } this.tasks = results; };

Object-Oriented Approach (continued) TaskList.prototype.getSummaries = function() { var results = [], task; for (var i = 0, len = this.tasks.length; i < len; i++) { task = this.tasks[i]; results.push({ id: task.id, dueDate: task.dueDate, title: task.title, priority: task.priority }) } return new TaskList(results); }; TaskList.prototype.sort = function(/*TaskListSorter*/ sorter) { this.tasks.sort(sorter.getSortFunction()); }; return TaskList; }());

(continued on the next slide.)

Object-Oriented Approach (continued) var TaskListSorter = (function() { var TaskListSorter = function(propName) { this.propName = propName; }; TaskListSorter.prototype.getSortFunction = function() { var propName = this.propName; return function(first, second) { return first[propName] < second[propName] ? -1 : first[propName] > second[propName] ? +1 : 0; } }; return TaskListSorter; }());

We could continue by defining Task and MinimalTask , but that's probably overkill in Javascript. It's important for our point to note that the difference between the plain imperative code and the Object-Oriented code, outside a number of ` this ` keywords, is mostly just organization. The contents of the functions are much the same; it's the way they are organized that varies. This means that for our purposes, we can focus on the slightly simpler imperative code.

Converting to Functional Code The process for the remainder of this talk will be to convert this code into concise, readable, functional code, one block at a time, explaining some of the basic building blocks of functional programming as we go. First up is this little function: .then(function(data) { return data.tasks; })

Functional Version .then(get('tasks'))

So the obvious question, then, is, what is the get function?

The get Function This is the definition of the get function in the Ramda library: var get = curry(function(prop, obj) {return obj[prop];});

Ignoring the curry wrapper, this is pretty simple. get (which also goes by the alias of prop ) is a function which accepts a property name and an object, and returns the property of the object with that name.

Our then call needs a function, so curry must be doing something interesting with this function, which should return an object propery, to instead returning a new function. So we need to take a detour to discuss curry a bit.

Curry

Very sorry, no delicious spicy food here.

Currying Functions Currying is the process of converting functions that take multiple arguments into ones that, when supplied fewer arguments, return new functions that accept the remaining ones. var add = curry(function(a, b) {return a + b;}); var add42 = add(42); console.log(add42(10)); //=> 52 console.log(add42(7)); // 49

Currying multiple arguments Different version of currying work slightly differently. In Ramda, you can pass any of the arguments at any time to a curried function. If the total arguments passed have not yet reached the required number, then you will get back a new function. If you reach (or exceed) that number, you will get back the final result. var formatName = curry(function(first, middle, last) { return first + " " + middle + " " + last; }); var f = formatName("James"); // returns a function var g = f("Earl"); // returns a function g("Jones"); //=> "James Earl Jones" var h = formatName("James", "Earl"); // returns a function h("Jones"); //=> "James Earl Jones" // Note that g and h are equivalent functions formatName("James", "Earl", "Jones"); //=> "James Earl Jones"

Some insist that this is not truly currying, but should be called partial application . They can feel free to call it what they like. It serves the same role as currying does in a more strongly typed language.

Back to get Remember the definition of get : var get = curry(function(prop, obj) {return obj[prop];});

Now that we understand curry , we can see that a manually curried version of this function might look like this: var get = function(prop) { return function(obj) { return obj[prop]; }; };

And that means that our new get('tasks') is equivalent to function(obj) { return obj['tasks']; }

Filtering So far, we've been able to replace this block: .then(function(data) { return data.tasks; })

with this one: .then(get('tasks'))

The next block to replace looks like this: .then(function(tasks) { var results = []; for (var i = 0, len = tasks.length; i < len; i++) { if (tasks[i].member == memberName) { results.push(tasks[i]); } } return results; })

What we're doing is running a filter on the input list, keeping only those that have the correct member property. Let's see how we would do this in a functional paradigm.

Functional Filtering Many functional libraries come with a filter function, which accepts a predicate function and a list, and returns a new list consisting of those elements of the original list for which the predicate function returns true . Ramda has one, called filter , and like pretty much every function of more than one parameter, it's curried, with the signature, filter(predicate, list) . Remembering that the then block will pass the list of tasks to us, we really want to call filter with a predicate, getting back a curried function that will accept a list. Here's a first pass: .then(filter(function(task) { return task.member == memberName; }))

(Remember that memberName was a parameter to our original function.)

Focused Code So, for one thing, we've reduced the weight of our custom code: Original code .then(function(tasks) { var results = []; for (var i = 0, len = tasks.length; i < len; i++) { if (tasks[i].member == memberName) { results.push(tasks[i]); } } return results; })

Functional version .then(filter(function(task) { return task.member == memberName; }))

But we've done something more important too: We've moved the focus from iteration and updating the state of a local collection to the real point of this block: choosing the tasks with the proper member property. One of the most important features of functional programming is that it makes it easy to shift focus in this manner.

Rejecting elements The next block is similar, except that instead of using filter , we will use reject , which behaves exactly the same except that it chooses those members of the list that don't match the predicate. We replace this code: .then(function(tasks) { var results = []; for (var i = 0, len = tasks.length; i < len; i++) { if (!tasks[i].complete) { results.push(tasks[i]); } } return results; })

with this: .then(reject(function(task) { return task.complete === true; )))

Refactoring... already A reasonable question would be why with didn't do this instead, which would work equally well: .then(filter(function(task) { return task.complete !== true; ))

The reason is that the similarity between these two blocks will offer us a chance to refactor our code into something still more descriptive: function(task) { return task.member == memberName; }

function(task) { return task.complete === true; ) Both of these functions accept an object and return a boolean that describes whether a particular property of the object has a given value. Perhaps a good name for a function that generates such functions would be propEq . Let's implement that.

Implementing propEq Simplest Approach var propEq = function(prop, val) { return function(obj) { return obj[prop] === val; }; }

This works, and we could leave it there, but we're going to take another detour into a popular style of functional programming known as points-free coding. The name has nothing to do with '.' characters. It derives from mathematics and has something to do with homomorphisms on topological spaces.

Don't worry… This won't be on the test.

Points-free definitions With the functions add (which adds two numbers) and reduce (which runs the supplied function against an accumulator and each element of the list, feeding the result of each call into the next one and returning the final result), we can easily define a sum function like this: var sum = function(list) { return reduce(add, 0, list); };



Because of the automatic currying, though, the following is entirely equivalent: var sum = reduce(add, 0);

This is the points-free style, defining functions without ever making direct reference to their arguments. There are plenty of reasons to like it, but the most important one might just be the simplicity. There is a great deal to be said for elegant, readable code.

A points-free version of propEq Can we redefine the following in a points-free style? var propEq = function(prop, val) { return function(obj) { return obj[prop] === val; }; }

Here's a version that is closer to points-free, removing the direct reference to obj : var propEq = function(prop, val) { return compose(eq(val), get(prop)); }

Huh? What? compose ? eq ? eq is easy: like all good functions of multiple parameters, it's curried, and it simply reports whether its two arguments are equal. So eq(val) is a function which reports whether its parameter has the same value as does val . But now we need to discuss compose .

Functional composition I have another short talk dedicated entirely to techniques of functional composition. This is a very brief overview: In mathematics f ∘ g (pronounced "f composed with g") is the function that given x , returns f(g(x)) . So if we follow the mathematical model compose(add1, square)(x) should equal add1(square(x)) .

Simplest Implementation var compose = function(f, g) { return function(x) { return f(g(x)); }; };

Note that Ramda also defines pipe , which does much the same thing, but runs the functions in the opposite order. So pipe(add1, square)(x) equals square(add1(x)) . Both styles have their uses.

Back to propEq So now this definition makes sense: var propEq = function(prop, val) { return pipe(get(prop), eq(val)); }

Note the switch from compose to pipe . This gives us a further way to clean it up, and make it entirely points-free, using a useful feature of Ramda we haven't seen implemented in other libraries, which we call (for now) use-over . Used like use(func).over(transformer1, ... transformerN) , this returns a function which accepts N parameters, feeds them to the respective transformers, and then calls func using the results of all these. This gives us the final version of propEq: var propEq = use(pipe).over(get, eq);

Using our new function This function seems quite useful, and we might want to fold it into Ramda one day, but it's not there now. Still, all these explanations aside, it was only a minute or two of work to do this refactoring and arrive at a fairly simple version of propEq . We would plug it back in like this: var propEq = use(pipe).over(get, eq); // ... .then(filter(propEq('member', memberName))) .then(reject(propEq('complete', true)))

New objects from old The next block we wanted to update looked like this: .then(function(tasks) { var results = [], task; for (var i = 0, len = tasks.length; i < len; i++) { task = tasks[i]; results.push({ id: task.id, dueDate: task.dueDate, title: task.title, priority: task.priority }) } return results; })

Functional version: .then(map(pick(['id', 'dueDate', 'title', 'priority'])))

You're a smart bunch, right? I probably don't even have to explain what pick does, right? Good, then we can move on to discuss map .

The map function It is not down in any map; true places never are. – Herman Melville

One of the most fundamental functions used in FP is map , which is used to convert one list into a related one by running the same function against each member. var fiveSquares = map(square, [1, 2, 3, 4, 5]); // => [1, 4, 9, 16, 25]; var shouts = map(toUpperCase, ["oy", "vey"]); //=> ["OY", "VEY"]

There isn't much more to say about map , but it's important to point out that this function and reduce , which we mentioned briefly earlier, are among the most important functional programming tools around.

Partial clones of our objects. We used map like this: .then(map(pick(['id', 'dueDate', 'title', 'priority'])))

The magic of currying is again at work here: pick accepts a list of properties and an object and return a partial clone, copying those properties from the original. Since we just pass in the properties, this curried function returns a new function that accepts an object and returns that partial clone.

accepts a list of properties and an object and return a partial clone, copying those properties from the original. Since we just pass in the properties, this curried function returns a new function that accepts an object and returns that partial clone. map accepts a function and a list an applies the function to the list. But because it's curried, and because we supply only the function generated by the curried pick , this one also returns a new function which will accept a list and create these partial clones of each element in the list.

accepts a function and a list an applies the function to the list. But because it's curried, and because we supply only the function generated by the curried , this one also returns a new function which will accept a list and create these partial clones of each element in the list. This function is passed to then , which will simply pass along its parameter (whenever that becomes ready) to our function and "return" the result of running our function against it. (We simply know because of the way prior calls have been built that this will be a list of tasks.)

A final task of some sort The last segment we wanted to convert looked like this: .then(function(tasks) { tasks.sort(function(first, second) { return first.dueDate - second.dueDate; }); return tasks; });

We won't discuss the implementation of sortBy , but the basic idea is that it returns a new list made from an old one by sorting the elements according to keys generated by the function passed to it. For instance: sortBy(function(person) { return person.lastName + "," + person.firstName; }, people);

Again with the curry Again, we take advantage of the fact that our important functions are curried, and use get('dueDate') . This creates a function that, fed one of our task objects, returns its due date. We can feed this into sortBy to get the following: .then(sortBy(get('dueDate')))

While this is not a lot less code than the original: .then(function(tasks) { tasks.sort(function(first, second) { return first.dueDate - second.dueDate; }); return tasks; });

it clearly is a savings. However, much more importantly, the code is all clearly aimed at our problem. The new code is much closer to a direct translation of the English specifications than is the original.

Recap – Imperative var getIncompleteTaskSummariesForMember_imperative = function(memberName) { return fetchData() .then(function(data) { return data.tasks; }) .then(function(tasks) { var results = []; for (var i = 0, len = tasks.length; i < len; i++) { if (tasks[i].member == memberName) { results.push(tasks[i]); } } return results; }) .then(function(tasks) { var results = []; for (var i = 0, len = tasks.length; i < len; i++) { if (!tasks[i].complete) { results.push(tasks[i]); } } return results; }) .then(function(tasks) { var results = [], task; for (var i = 0, len = tasks.length; i < len; i++) { task = tasks[i]; results.push({ id: task.id, dueDate: task.dueDate, title: task.title, priority: task.priority }) } return results; }) .then(function(tasks) { tasks.sort(function(first, second) { return first.dueDate - second.dueDate; }); return tasks; });

Recap – Functional var propEq = use(pipe).over(get, eq); // TODO: move to library? var getIncompleteTaskSummariesForMemberFunctional = function(memberName) { return fetchData() .then(get('tasks')) .then(filter(propEq('member', memberName))) .then(reject(propEq('complete', true))) .then(map(pick(['id', 'dueDate', 'title', 'priority']))) .then(sortBy(get('dueDate'))); };

Not the Library It's important to note that nothing in here is meant to promote the Ramda library in particular. While I'm certainly partial to it, the only thing that we used in here that was not entirely common to the majority of functional programming libraries (across many languages, in fact) was the use().over() construct, and all that really gained us was to turn a short function into a points-free one-liner. Certain libraries make things easier than others, though. The equivalent code using Underscore or LoDash, which don't curry their functions by default, and which choose a different default parameter order, would involve significantly more boilerplate.

Most Important Functions We've seen what are probably the most important functions in functional programming: map

reduce

filter

compose

curry There's one that to some might be conspicuous by it's absence: forEach I would argue that this is not actually appropriate to functional programming, as its main purpose is to help you achieve side-effects. But many libraries do include one.

What We Gain from FP Style Elegance and simplicity

Easier decomposition of problems

Code more closely tied to the problem domain And through these, we can also achieve Straightforward unit testing

Easier debugging

Simple concurrency

Questions?

/