fc2b5fca36a2d4e226982f7f96239c4a_1303034x - Goiit.com

soilkinkajouInternet and Web Development

Feb 2, 2013 (4 years and 6 months ago)

108 views



Definition of Functional Programming from our friends at Wikipedia:

In computer science, functional programming is a programming paradigm that treats
computation as the evaluation of mathematical functions and avoids state and mutable data. It
emphasizes the application of functions, in contrast with the imperative programming style that
emphasizes changes in state.




Why does Functional Programming matter?

1.

Parallel programming

FP has seen a resurgence of interest due to the upcomming avail
ability of
chips with multiple cores. In the not too distant future our workstations
will have 32 CPUs on them. Also, castoff old PCs or cheap new ones can
be networked together to make a supercomputer. To use them efficiently will require a
retooling of h
ow we program. Functional Programming helps to code in a parallel
manner.

2.

Code Modularity

FP also allows a higher level of
modularity

since functions can now be modules.

3.

Smaller program si
ze

FP programs are typically smaller (by a factor of two to ten). Since they are smaller, they
tend to be less error
-
prone.



Some Characteristics of Functional Style

1.

Focus on "what" should be done, but not necessarily "how".

For example, in a spreadsh
eet we define the values of cells, but do not specify the order
in which the cells are evaluated. Another example is SQL. We do not specify the order of
JOINs, SELECTs, or WHEREs. The SQL engine does all that for us.

2.

Pure Functions


Pure functions use on
ly the variables passed to them and have no
side effects. Pure functions never interact with the outside world
-

no writing to files or communicating with the user. The function
can be called over and over and will always return the same
value.

This is li
ke a mathmatical function. It doesn't matter how many times you evaluate

Area = PI * (R**2)

for a given "R" the answer is always the same. The answer does not depend on what
functions you called before this.

This gives us these benefits:

1.

The order of function invocation does not matter.

2.

Functions can use lazy evaluation.

3.

Functions can be optimized.

4.

Refactoring and testing is easier.

5.

Functions lead to composability (which makes C# query operators more
reusable).

Some imperative languag
e compilers (eg, C++) allow pure functions to be marked as
such for optimization.

Question: Are programs composed entirely of pure functions very useful?



3.

Lambda Expressions

Lambda expressions make code more readable by allowing anonymous inline methods
.

Here's an example from emacs on defining a key, "Meta
-
Control
-
p" to mean insert
"<p></p>" and move the cursor to inbetween the tags. We could have bound the key to a
function with the same code, but it's just faster and clearer to use lambdas.

(define
-
k
ey global
-
map "
\
M
-
\
C
-
p"

'(lambda () (interactive) (insert
"<p></p>")(forward
-
char
-
4)))

4.

Immutable variables

An immutable variable has its value set
once and can never change its value. Like
a brick set in concrete on the left, it's not
going anywhere.
Normal variables are more like pebbles on the right that you can pick up
and move around and change their "state".

Immutable variables makes parallel execution easier, but it's really wierd to us imperative
programmers.

XSLT transformations are an example

of a language with immutable variables.
Spreadsheets are another example of functional programming with immutable variables.

But how can we get rid of state? Here is the traditional imperative programming style to
sum a collection of numbers:

int sum = 0;

foreach(int i in new int[]{1,2,3}) {


sum += i;

}

Console.Out.WriteLine("sum=" + sum); //sum=6

Using recursion in LISP we can accomplish the same thing:

(setq x '(1 2 3))

;; "car" takes the first element of the list

;; "cdr" makes a list of all but t
he first element

(defun add (numbers) "adds a list of numbers"

(if (null numbers) 0

(+ (car numbers) (add (cdr numbers)))

))

(add x) ;=>6



5.

"Higher
-
order" functions

1.

Definition:

Higher
-
order functions take functions as arguments
and/or return functions as results. Functions are first
class members of the program.

Here's a quick example in Ruby of a higher order
function, "select". It returns all items matching a
logical expressio
n that is passed into "select" as an
argument.

numbers = [1,2,3,4,5,6,7];

evens = numbers.select{|x| x % 2 == 0}

puts evens #=> [2, 4, 6]

In early C# versions, the Array.Sort method needed
an object with the IComparer interface. A function
could not
stand alone, it had to be embedded in an
object in this
Kingdom of Nouns
.

string[] names = tmp.Split(' ');

Array.Sort(names,new LengthComparer());

...

public class
LengthComparer: IComparer {

public int Compare(Object obj1, Object obj2)


{


...


}

}

Why not create an anonymous function instead of creating a whole class which
only has one function?

2.

A Common Higher Order Function
-

"Reduce" (aka fold, inject, accumulate)


Produces a single result from applying a function over a
list of objects. (Kinda like those pills that reduce a 12oz
steak, baked potato, chef salad, and cheesecake into a
single p
ill. Shown here to the right
-

you may have to
squint just a little to see steak).

In Ruby the reduce function is called "inject", since you
are injecting an initial value. Note that the function we are passing to the inject
method is sum+prime and product
*prime.

primes = [1,3,5,7,11,13];

#using "inject" to sum. We pass in "0" as the initial value

total = primes.inject(0){|sum,prime| sum+prime}

puts total #=>40

puts primes.inject(1){|product,prime|
product*prime} #=>15015

3.

Another Common Higher Order F
unction "Map"

From
Wikipedia
:

In many programming languages, map is the
name of a higher
-
order function that applies a given function to a sequence of
elements (such as a list)
and returns a sequence of results.

1.

"mapcar" in Lisp:

2.

(setq x '(1 2 3))

3.

(defun multiply_by_three (a)

4.


(* 3 a)

5.

)

6.

(mapcar 'multiply_by_three x) ;produces: (3 6 9)

7.

"select" in C#:

8.

using System;

9.

using System.Linq;

10.

using System.Linq.Expressions;

11.

using
System.Collections.Generic;

12.


...

13.

var values = new System.Collections.Generic.List<int>()
{ 1, 3, 5, 7 };

14.

var foo = values.select(d => d * d);

15.

"map" in the proposed Java 7
BGGA proposal syntax

16.

final Array<Integer>
a = array(1, 2, 3);

17.

final Array<Integer> b = a.map({int i => i + 42});

18.

arrayShow(intShow).println(b); // {43,44,45}

6.

Lazy Evaluation

Definition:

In computer programming, lazy evaluation (or delayed evaluation) is the technique of
delaying a computation until such time as the result of the computation is known to be
needed.

For example, the unix "grep" command will normally find all occurances of a

string. But
if it knows the "head" program will only print the first three, "grep" can stop after the first
three and not find the remaining strings. This is lazy evaluation
-

only the data really
needed is produced.

grep Battlestar movies.txt | head 3

7.

Ot
her Characteristics and Topics

Not mentioned here are many aspects of FP that are worth your investigation: pattern
matching, currying, closures, and monads.



Example of a Functional Style in the Real World
-

MapReduce



Google's
MapReduce

framework is used
to process 20 petabytes of data a day.
MapReduce is a way of creating a
massive supercomputer from vast farms
of humble PCs. Although it is

written in
C++, the philosophy behind MapReduce
is functional: "Our abstraction is inspired
by the map and reduce primitives present in Lisp and many other functional languages."
-
Jeffrey
Dean and Sanjay Ghemawat

MapReduce was originally used to create an

inverted index of the web.



A programmer specifies a "map" function

map (in_key, in_value)
-
> list(out_key, intermediate_value)

and a "reduce" function.

reduce (out_key, list(intermediate_value))
-
> list(out_value)

1.

The MapReduce framework splits a large task into N chunks and spawns N "map"
processes, typically on different machines, to process those chunks.

2.

The "map" function reads a set of key/value pairs, processes them in any way it deems fit,
and produces inter
mediate (key, data) data structures.

3.

A splitter function, typically a hashing function, groups the (key, data) objects into M
buckets and writes each bucket to a separate file. During the map phase N*M files are
created.

4.

The framework periodically checks

to make sure all the "map" functions are running. The
framework can detect failures and reassign work if a process is thought to have gone
rogue.

5.

After all the "map" functions have finished, the framework spawns M "reduce" processes
to read the intermedi
ate values. Each "reduce" process reads N bucket files, one from
each of the "map" processes, and sorts them by the key. The "reduce" process then calls
the user's reduce function with the key and a list of intermediate values. It then creates the
final pr
oduct.

Oversimplification of page rank algorithm:

map(string page_url, string pagecontents)
-
>


(target_url1, page_url),(target_url2, page_url),...


reduce(target_urlX, list(start_url))
-
>


(target_urlX, weight)



Purity

"Purely functional" langua
ges follow the rules. Examples of these are Haskell, Erlang, ML, and
XSLT. Most commercial functional langauges are multi
-
paradigm, having some aspects of
functional programming, but not pure. Examples of these are LISP, Ruby, C# 3.0 and F#.



Value of th
e Functional Approach

From
Joel on Software

Without understanding functional programming, you can't invent MapReduce, the algorithm that
makes Google so massively scalable. The terms Map
and Reduce come from Lisp and functional
programming. MapReduce is, in retrospect, obvious to anyone who remembers from their 6.001
-
equivalent programming class that purely functional programs have no side effects and are thus
trivially parallelizable. The

very fact that Google invented MapReduce, and Microsoft didn't,
says something about why Microsoft is still playing catch up trying to get basic search features
to work, while Google has moved on to the next problem: building Skynet^H^H^H^H^H^H the
world'
s largest massively parallel supercomputer. I don't think Microsoft completely understands
just how far behind they are on that wave.



The ugly side of functional programming

1.

Memory

FP will often take more memory than imperative programming.

2.

Speed

Hand
-
coding in C can give faster code

3.

Learning Curve is steep

Not many programmers are trained in functional programming and it can take a while to
grasp the concepts and use them well.