Functional Programming (FP) was one of the issues we went over during the Scala demo I gave last Tuesday.

The resolution of that discussion was't to my satisfaction, not to mention following community entries that may picture FP as a concept that is open for personal interpretations. So, following are some clarifications about FP and its place in Scala.

 

Functional Programming:

FP has its roots in the Lambda Calculus, a formalism for representing functions and ways of combining functions, invented around the 1930s by mathematician (logician) Alonzo Church. Languages like Lisp and Haskell (named after Haskell Brooks Curry, a logician whose work is closely related to the Lambda Calculus) are considered "pure functional functional programming languages" and are influenced by this region of mathematics.

 

From Haskell's wiki: "Functional Programming means that programs are executed by evaluating expressions. This contrasts with imperative programming where programs are composed of statements which change global state when executed. Functional programming, on the other hand, avoids using state and mutable data."

 

This is it. No space for personal thoughts or considerations of any kind.

 

 

 

FP & Scala:

This is how the creators of Scala described it: "Technically, Scala is a blend of object-oriented and functional programming concepts in a statically typed language. The fusion of object-oriented and functional programming shows up in many different aspects of Scala; it is probably more pervasive than in any other widely used language. The two programming styles have complementary strengths when it comes to scalability. Scala’s functional programming constructs make it easy to build interesting things quickly from simple parts. Its object-oriented constructs make it easy to structure larger systems and to adapt them to new demands. The combination of both styles in Scala makes it possible to express new kinds of programming patterns and component abstractions. It also leads to a legible and concise programming style. And because it is so malleable, programming in Scala can be a lot of fun."

 

 

9

Comments

Ok, I reallise how my post may have been misinterpreted. It was a 10 minute writeup to express my opinion. Anyway, I've updated it now to be more accurate.

So, In FP the program execution is just an evaluation of a (large/composed) function without mutable variables (hence no state)? That is cool, but I am trying to figure out how would it simplify our lives. Maybe we can look at "Functional Design Patterns" that would demonstrate some reusable functions. see http://www.cwi.nl/~ralf/dp-sf.pdf, but I must warn you that this is about "Strategic FP".

It's not that there's no state. There's no mutable state. For example: Assume I have list of tasks (in Erlang like style): Tasks = getTasks(). Tasks cannot be declared and later initialized. It all happens at once. Now, say we want to filter out non urgent tasks. We call a method that accepts Tasks as an argument and have the result set into a new variable: UrgentOnly = filterUrgent(Tasks).. This, on the other hand, might be illegal: Tasks = filterUrgent(Tasks). (Why might? keep reading...). This is generally how you manipulate state in "pure" languages. The trick is to understand that the equal sign '=' isn't what we are used to in imperative programming. It's actually a matcher. It make sure that in A = B, the content of A matches the content of B. So Tasks = filterUrgent(Tasks). is illegal only if the output of filterUrgent doesn't match Tasks. This immutability feature is the "secret" behind concurrency efficiency.

In addition to Adi's comment, I'd say that the state is the arguments to the function. When you need to change state, you just call the function again with the new state. This is why tail recursion is an important part of any FP language. For example, how would you reverse a list? With imperative programming, you keep a result list variable and add items to the list until it is constructed, then return it. With FP the pseudo code is: reverse(list) { reverse_inner(list, result) { if (list.empty) return result else return reverse_inner(list.tail, result + list.head) } reverse_inner(list, []) } so the state (result) does change, but not in the method. the benefits i can think of are localisation and parallelism. localisation means that when you see foo(bar), you know foo did not change any global variables, or any other variables in scope. there are no surprises. prallelism is because if there's no mutable data, then two threads cannot change each other's state.

Speaking of recursion, Scala compiler can optimize tail-recursive functions by turning them into a loop. Since it is sometimes tricky to write tail-recursion, version 2.8 supports @tailrec annotation. This will make the compiler check if it's actually one.

Talking about Erlang this is also nice: http://yarivsblog.com/articles/2008/05/18/erlang-vs-scala/

Yup. A bit outdated but still good. I generally like reading Yariv's stuff (blogs/twitts/etc.). It's are usually accurate and tasteful.