43

I have noticed lately that functional programming languages are gaining popularity. I recently saw how the Tiobe Index shows an increase in their popularity in comparison to the last year although most of them do not even reach the top 50 most popular languages according to this index.

And this has been the case for quite some time. Functional programming simply has not become as popular as other models (i.e., object-oriented programming).

I have seen a reborn interest in the power of functional programming, however, and now that multicores are more and more popular, developers have started to show interest in other models of concurrency already explored in the past by languages like Haskell and Erlang.

I see with great interest the fact that despite their lack of significant community acceptance, more and more languages of this sort continue to emerge. Clojure (2007), Scala (2003), F# (2002) are just three examples of the recent last decade.

I have been, myself, investing some time learning Haskell and Scala. And I find great potential in the paradigm which for me was new despite being out there for so long.

And of course, my biggest question is if any of these are going to become popular enough as to consider putting any effort in them, but this is a question that not even Mandrake could answer, despite all the fuss people is making about them.

What I do want to ask is:

  • In which scenarios should I consider a functional programming language better suited to do a given task? Besides the so recently popular multicore problem of parallel programming.
  • If I decided to switch to a functional programming language which would you consider being the biggest pitfalls that I would face? (Besides the paradigm change and the difficulty to evaluate performance due to lazy evaluation).
  • With so many functional programming languages out there, how would you choose the one the better suit your needs?

Any recommendations for further research will be more than welcome.

I have searched the web for opinions, and it appears the all this renew popularity come from the idea that now we're about to hit the wall of Moore's Law and functional programming languages will come and heroically save us. But if this is the case, I would say there are more probabilities of existing popular languages adapting to the paradigm.

Some of you, with more experience working every day with these languages perhaps, can offer more insight on the subject. All your opinions will be better appreciated and carefully considered.

Thanks in advance!

edalorzo
  • 2,634
  • 1
  • 19
  • 28
  • 4
    It's Erlang, not Earlang (I'd have edited your post, but the System doesn't allow 1-letter edits). – quant_dev Apr 26 '11 at 07:38
  • 6
    Worth saying - there is no hard line between functional and imperative languages. ML family languages are not side-effect free, and support imperative statements and structures and mutable variables. Some imperative languages - off the top of my head Python and Javascript - have significant features taken from functional programming. Personally, I hope to see more functional ideas in mainstream use - especially pattern matching. –  Apr 26 '11 at 13:44
  • @Steve Interesting! Imperative langs have started to adopt things like list comprehension, first class functions and lambda exp. It seems this is a trends and not necessarily FP as a goal. Oracle plans to incorporate some of these feature in JDK8. Evidently they consider it a must for near future. Again, their claim is parallel computing. I daresay this is what is actually becoming a skill worth to acquire. Imperative langs these days arguably want to offer the best of both worlds and they are mutating in that direction (Scala and F#). Pure vs unpure? An interesting discussion, too. – edalorzo Apr 26 '11 at 14:28
  • 1
    Having a few features common to functional languages does not necessarily make a language "functional". Functional programming is as much about a way of thinking and designing programs as it is about specific language features. – mipadi Apr 26 '11 at 14:38
  • @edalorzo - In Haskell, the interactions between lazy evaluation and monads have a lot of potential in terms of implicitly parallel evaluation. Trouble is, I have a big issue with the Haskell philosophy. Most of the ideas are very interesting and promising, but when you work through the implications, it turns out to be a problem when you want a particular algorithm. In simple terms, it's the dark side of the "what you want, not how to compute it" philosophy - an algorithm *is* "how to compute it". –  Apr 26 '11 at 14:41
  • 2
    @mipadi - and therefore you can apply the functional philosophy in any language, to the degree that the available tools allow. You can write functional-style code in Python (within limits), and to that extent Python is a functional language. And you can write imperative-style code in ML, and to that extent ML is an imperative language. This isn't quite the same as the "bad programmers can write Fortran in any language", though obviously that's an easy trap to fall into if you misinterpret my point. –  Apr 26 '11 at 14:45
  • @Steve314: I disagree. I can kinda-sorta write some FP-like code in Python, but the constructs of the language dictate that the design of the program is going to be decidedly imperative. I can apply concepts from FP to code written in C or Java or Objective-C, but the end result isn't really going to resemble an FP program. – mipadi Apr 26 '11 at 14:47
  • @mipadi - yes, that's why I said "to the degree that the available tools allow". IMO, if all imperative and functional tools were available in all languages, the philosophical divide would be more like the old structured programming vs. goto things - a matter of best practice and spotting the rare cases where the rules should be broken, rather than of a choice between religions. For example, pattern matching is a good way to represent many kinds of decisions - and that would apply equally well in C, C++, C# or Java, so long as the syntax didn't get too awkward. Good style, not just functional. –  Apr 26 '11 at 15:11
  • @Steve314 Isn't functional programming a paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data, emphasizing the application of functions, in contrast to the imperative programming style, which emphasizes changes in state. This sounds like something I could do in any programming language if I write the code under the proper mindset. Certainly the language inner workings and libraries most probably will not follow the approach, but my code would. Wouldn't that still be FP? I ask because unpure FP langs would let you do both things, right? – edalorzo Apr 26 '11 at 15:12
  • @Steve314: True, but again, functional programming isn't about a handful of specific language constructs -- it has more to do with a way to think and reason about programs and design them. An imperative language with basic FP constructs still requires one to think and reason about the program in a mostly imperative way. – mipadi Apr 26 '11 at 15:19
  • @edalorzo - yes and no. Even in C, you can write an expression that has no side-effects - functional style to a point. But the functional philosophy has much more to it than just that point, and most functional languages don't even enforce that anyway (impure). Certain language constructs are very important for a language to be considered functional - particularly first class functions. But for "real" functional thinking, it helps to have some background in abstract algebra. A better background than I have, truth told. Trying to apply those principles would be hopeless in C. –  Apr 26 '11 at 15:23
  • 1
    @mipadi - but if the imperative language had all the normal functional constructs, you could do anything with it you could in a functional language - the gap would be closed, and the question would be "what's the best way to do this" rather than "what's the functional/imperative way". The ML family has already closed that gap, really, but because it's *called* functional, we think of its style as functional style rather than simply good style. –  Apr 26 '11 at 15:28
  • @Steve, can you write an answer so we can vote for it. I also grow tired of this artificial distinction between functional/imperative programming. – edA-qa mort-ora-y May 18 '11 at 13:30

7 Answers7

25

In which scenarios should I consider a functional programming languages better suited to do a given task? Besides the so recently popular multicore problem of parallel programming.

Anything that involves creating sequence of derived data elements using a number of transformation steps.

Essentially, the "spreadsheet problem". You have some initial data and set of row-by-row calculations to apply to that data.

Our production applications do a number of statistical summaries of data; this is all best approached functionally.

One common thing we do is a match-merge between three monstrous data sets. Similar to a SQL join, but not as generalized. This is followed by a number of calculations of derived data. This is all just functional transformations.

The application is written in Python, but is written in a functional style using generator functions and immutable named tuples. It's a composition of lower-level functions.

Here's a concrete example of a functional composition.

for line in ( l.split(":") for l in ( l.strip() for l in someFile ) ):
    print line[0], line[3]

This is one way that functional programming influences languages like Python.

Sometimes this kind of thing gets written as:

cleaned = ( l.strip() for l in someFile )
split = ( l.split(":") for l in cleaned )
for line in split:
     print line[0], line[3]

If I decided to switch to a functional programming language which do you consider are the biggest pitfalls that I will face? (Besides the paradigm change and the difficulty to evaluate performance due to lazy evaluation).

Immutable objects is the toughest hurdle.

Often you'll wind up calculating values that create new objects instead of updating existing objects. The idea that it's a mutable attribute of an object is a hard mental habit to break.

A derived property or method function is a better approach. Stateful objects are a hard habit to break.

With so many functional programming languages out there, how would you choose the one the better suit your needs?

It doesn't matter at first. Pick any language to learn. Once you know something, you're in a position consider picking another to better suit your needs.

I've read up on Haskell just to understand the things Python lacks.

S.Lott
  • 45,264
  • 6
  • 90
  • 154
  • @S.Lott This is great information, really helpful. Thanks for taking the time to write such detailed answer. What you describes sounds like the kind of thing "R" is good at. I will certainly research more on this. I see that your experience comes from Python but you have also experimented with Haskell.If you do not mind me asking yet another question. When it comes to functional programming, have you felt more comfortable with weakly-type languages like python than with strongly-type languages like Haskell? – edalorzo Apr 26 '11 at 03:23
  • 5
    @edalorzo: Python's not weakly typed. It's very, very strongly typed. There's no cast operator, so it's more strongly typed than Java or C++. – S.Lott Apr 26 '11 at 09:45
  • 1
    @S.Lott Agree, I was evidently wrong. My intention was actually to ask about type checking in this case: static type checking like in Haskell vs dynamic type checking as in Python. But perhaps this is actually better for another question. Thanks! – edalorzo Apr 26 '11 at 11:54
  • 1
    @edalorzo: Static type checking isn't all that helpful. It doesn't much matter if there's static checking by a compiler or run-time checking. You still write the same amount of code and the same number of unit tests. Haskell's optimizations are very helpful. It's a gap you find if you try to do purely lazy functional programming in Python. – S.Lott Apr 26 '11 at 11:56
  • 5
    @S.Lott - doesn't static type checking help with IDE refactoring tools and intellisense-type stuff? If you have background compilation going, and you're statically checking types, doesn't that mean you can automate more in your tools? I do agree that if you have 100% code coverage in your tests, it'll catch it. You must realize that probably less than 50% of production code in the enterprise actually has unit test coverage though, right? :) There is a real world out there we have to live in. – Scott Whitlock Apr 26 '11 at 13:31
  • @S.Lott - it seems to me like your describing *pure* functional programming with lazy evaluation for the spreadsheet problem stuff. "Strict" (as opposed to pure) functional languages leave the evaluation order mostly to the programmer, so you'd have to handle dependency ordering between the "cells" before evaluating, same as with any imperative language, rather than leave that issue to the compiler. Even some C compilers can re-order some computations and even make them concurrent - what ML and C compilers can do for you isn't hugely different. –  Apr 26 '11 at 13:57
  • 1
    @S.Lott The difference is *when* the type checking is done. I'd rather have it fail at compile time, personally - I don't care about the semantics of what defines "strongly typed". – Michael K Apr 26 '11 at 14:00
  • 1
    @Michael - I agree about failing at compile time, but if you're doing enough unit testing, it isn't a serious issue. After all, static type checking catches *some* errors that fit *some* basic rules. Unit testing, in principle, can catch all those errors and many more. That said, static type checks in the compiler do mean that you don't need to write those particular unit tests. –  Apr 26 '11 at 14:09
  • @Steve314 Absolutely, although it leaves more room for human error (while writing or maybe *not* writing the tests). Although, there ought to be some tools to help with that. New project :)? – Michael K Apr 26 '11 at 14:12
  • @Scott Whitlock: "doesn't static type checking help with IDE refactoring tools and intellisense-type stuff". Some. But that's not really a big impact. 80% of the life of the software is production, not development, where the quality of unit tests matter more than code completion and refactoring. Further, 100% coverage is silly. The *very* few places where you can even make a mistake in Python (or Java) are easily found with simple unit tests. – S.Lott Apr 26 '11 at 14:43
  • 1
    Guys, I think we are falling into the static vs dynamic typing holly war, which is certainly a very interesting topic above all if we can highlight any particularities in functional programming langs, but otherwise I think both models have their pros and cons. – edalorzo Apr 26 '11 at 14:53
  • @edalorzo: Static typing has few pros. Some, but hardly worth worrying about. The functional programming aspect of static vs. dynamic type checking are **exactly** the same as in all other languages. – S.Lott Apr 26 '11 at 14:55
  • @S.Lott - you've obviously never had to maintain a code base written in a weakly typed language that has no unit tests. :) I would love to have stronger static type checking in the VB6 code I have to maintain. – Scott Whitlock Apr 26 '11 at 15:38
  • @Scott Whitlock: Sadly, I have worked with VB code. I'm not easily convinced that static type checking would help. I think that procedural programming is essentially too hard to apply except in very small cases. – S.Lott Apr 26 '11 at 16:02
  • @Scott Whitlock: All good interesting answers, but yours has more upvotes, so I will mark yours as the right answer to the question. – edalorzo Apr 26 '11 at 16:35
  • Thank you all for your detailed explanations and effort to enrich the discussion. It has certainly been enlightening to me. – edalorzo Apr 26 '11 at 16:35
  • 10
    @S.Lott "Static type checking isn't all that helpful. It doesn't much matter if there's static checking by a compiler or run-time checking. You still write the same amount of code and the same number of unit tests." Err, no. The whole point of static type checking is that it catches bugs, consequently, it *massively* reduces the amount of testing required. – J D Feb 27 '12 at 11:22
  • 5
    @S.Lott "Python's not weakly typed. It's very, very strongly typed." Python implicitly casts between numeric types, which is being weakly typed. – J D Feb 27 '12 at 11:26
  • 5
    @Steve314 "After all, static type checking catches some errors that fit some basic rules. Unit testing, in principle, can catch all those errors and many more." No. Static checking proves the correctness of an aspect of a program. Unit testing seeks to disprove correctness but does not prove the correctness of anything. Unit testing is not a substitute for static type checking nor any other kind of proof. – J D Feb 27 '12 at 12:54
  • 4
    @S.Lott "Static typing has few pros. Some, but hardly worth worrying about. The functional programming aspect of static vs. dynamic type checking are exactly the same as in all other languages." ML pattern match compilers prove both exhaustiveness and redundancy, possible solely because closed algebraic datatypes convey the required information. Haskell checks for purity, possible because purity is tracked by its type system. – J D Feb 27 '12 at 12:59
  • @JonHarrop: "Python implicitly casts". Not exactly. It creates new objects from old objects. Different thing entirely. Static type checking only confirms one aspect. And that's trivially spoofed through casts and failing to implement the intent of an override (or abstract) method. I feel that these are factual statements. Moderators have disagreed with me. I'm afraid that I cannot discuss this further because I've been labeled as "aggressive". – S.Lott Feb 27 '12 at 13:49
  • @Jon - static typing proves consistency with annotations in the program that are only added so that you can test consistency with them. The whole point of that consistency check is to catch errors. If it wasn't for catching those errors, adding those annotations would be pointless waste of time - proving that aspect of the program would have academic value at most. The type system is itself basically a programming language, especially in a language like Haskell where the type system is bordering on Prolog - type-checking can even fail to terminate. –  Feb 27 '12 at 14:39
  • @Jon - what I'm pointing out is that there is more than one way to annotate the same basic program with type information. Specifying types is a form of programming in itself. Which errors you catch depends on how you do that, just as it can depends on what unit tests you write. The only aspect of a program you have fully proved only exists as an artifact of how you chose to specify types. You could have chosen to check exactly the same error cases with unit tests instead, though the amount of work involved is clearly different. –  Feb 27 '12 at 14:45
  • @JonHarrop: I think you're responding to Steve314. I didn't mention type annotations. While static languages have them, they can be inferred. – S.Lott Feb 27 '12 at 20:14
  • @S.Lott "It creates new objects from old objects. Different thing entirely." Is the difference observable, e.g. when dividing a float by an int? – J D Feb 27 '12 at 20:19
  • 1
    @Steve314 "static typing proves consistency with annotations in the program". No. Static typing does not require type annotations. Types can be inferred. You don't have to add type annotations. – J D Feb 27 '12 at 20:19
  • 1
    @JonHarrop: (1) You're the only person who suggested correctness was or was not testable. I don't see it in the answer. (2) I cannot discuss this further because the moderators have deemed me too "aggressive". Your points about correctness are good, but don't seem germane to the answer. Only this protracted discussion. Are there words in the answer you're suggesting be changed? If so, which words and to what do you suggest they be changed? – S.Lott Feb 27 '12 at 20:20
  • 4
    @Steve314 "You could have chosen to check exactly the same error cases with unit tests instead, though the amount of work involved is clearly different". No. Unit tests cannot prove correctness. They merely show some examples where a function happens to produce the expected result. Consider a `reduce` function over a sequence of one or more elements that can be represented by a function of the type `('a -> 'a -> 'a) -> ('a * 'a list) -> 'a` in F#. Static type checking prevents you from passing the empty sequence for any `'a`. No finite number of unit tests can give that assurance. – J D Feb 27 '12 at 20:20
  • @S.Lott "Are there words in the answer you're suggesting be changed?". Your answer is fine. I just picked up on the comments... – J D Feb 27 '12 at 20:22
24

"Functional" is a bunch of different features, each of which is independently useful, and I find it more useful to look at each individually.

Immutability

Now that I'm familiar with it, any time I can get away with returning an immutable result, I always try to do that, even in an object oriented program. It's easier to reason about the program if you have value-type data. Usually you need mutability for things like GUIs and performance bottlenecks. My entities (using NHibernate) are also mutable (which makes sense because they're modeling data stored in a database).

Functions as First Class Types

Whatever you want to call it, passing around delegates, actions, or functions, is a really handy way to solve a whole class of real world problems, like the "hole in the middle pattern". I've also found that passing a delegate, action, or function to an object is cleaner than having that class declare an event and hooking that event (assuming there's normally only one "listener"). When you know there's one listener, then the callback action can be passed as a constructor parameter (and be stored in an immutable member!)

Being able to compose functions (for instance turning Action<T> into just an Action is also quite useful in some scenarios.

We should also note Lambda syntax here, because you only get Lambda syntax when you promote functions to first class types. Lambda syntax can be very expressive and concise.

Monads

Admittedly, this is my weak spot, but my understanding is that computational workflows in F#, such as the async workflow, is a monad. This is a subtle but very powerful construct. It's as powerful as the yield keyword used to create IEnumerable classes in C#. Essentially it's building a state machine for you under the covers, but your logic looks linear.

Lazy Evaluation & Recursion

I put these together because while they're always lumped in as features of functional programming, they've made their way so quickly into otherwise-imperative languages that it's hard to call them functional anymore.

S-Expressions

I guess I'm not sure where to put this, but the ability to treat the un-compiled code as an object (and inspect/modify it), such as Lisp S-Expressions, or LINQ Expressions, is, in some ways, the most powerful tool of functional programming. Most new .NET "fluent" interfaces, and DSLs, use a combination of lambda syntax and LINQ Expressions to create some very concise APIs. Not to mention Linq2Sql/Linq2Nhibernate where your C# code is "magically" executed as SQL instead of as C# code.

That was the long answer to the first part of your question... now...

If I decided to switch to a functional programming language which do you consider are the biggest pitfalls that I will face? (Besides the paradigm change and the difficulty to evaluate performance due to lazy evaluation).

The biggest pitfall I faced was trying to find the line between using functional solutions vs. imperative solutions. However, after trying both approaches a few times, you start the get a feel for which will work better.

With so many functional programming languages out there, how would you choose the one the better suit your needs?

If you are familiar with .NET, I highly suggest F#. On the other hand, if you're more familiar with the JVM, there is always Clojure. If you're more academic than practical, then I'd go with Common Lisp or Scheme. If you already know Python, I believe there are lots of functional constructs already available there.

Scott Whitlock
  • 21,874
  • 5
  • 60
  • 88
  • @Scott Thanks for your detailed explanation. I guess what you describe as the biggest pitfall would be taken out of the equation by using a pure functional programming language like Haskell. That's why I have started with it, because I have been an imperative programmer all my life, and I do not want to star with an impure programming language and risk not learning the good way. If you do not mind me asking another question: Two things that worries me are tools and libraries. How good is the integration of F# with other .Net tools and libraries? – edalorzo Apr 26 '11 at 03:34
  • I don't understand why you lump code at runtime and runtime code generation and inspection with functional programming. The two have no relation to each other. The metaprogramming capabilities that you describe can be added to almost any language, functional or not. I think lisp started the code as data trend but it's now available in ruby and other non-functional languages. –  Apr 26 '11 at 09:17
  • 1
    @edalorzo - F#'s integration with .NET is very good, with only one minor exception: no GUI designer. You get around that by designing your GUI in a C# assembly and referencing it from F#, or by generating the GUI inside F# only in code (not with a designer). – Scott Whitlock Apr 26 '11 at 13:24
  • @davidk01 - good question about meta-programming. I just find that lambda syntax and meta-programming build off one another, but you're right, they could be separated. It just seems like you're more likely to get meta-programming with a functional language. – Scott Whitlock Apr 26 '11 at 13:27
  • 1
    @Scott: I think in many ways it's easier - for example, when you don't have to worry about side effects you can modify a section of code on the fly with much more confidence - it limits what you have to change. – Michael K Apr 26 '11 at 14:22
  • @Michael - I would say unit tests give you the confidence, but immutability gives you a useful tool for making changes to existing code. – Scott Whitlock Apr 26 '11 at 15:36
  • @ScottWhitlock You probably want to distinguish between homogeneous and hetereogeneous metaprogramming. Lisp had the former, meaning it could do run-time generation, compilation and execution of Lisp code. MLs are descendants of Lisp and ancestors of F# but they tend not to do metaprogramming over themselves but, rather, were design for metaprogramming over other languages, i.e. writing interpreters, compilers and theorem provers. They sometimes have related capabilities (e.g. camlp4 for OCaml and quotations in F#) but not the same kind of metacircular evaluation that Lisp had. – J D Feb 27 '12 at 13:05
15

And this has been the case for quite some time. Functional programming simply has not become as popular as other models (i.e object oriented programming).

This is true if you count programs developed by professional programmers (or at least people seeing themselves as such). If you spread your net wider to include programs developed by people not considering themselves as such, FP (or at least programming in a functional style) is pretty close to OO (Excel, Mathematica, Matlab, R... even 'modern' JavaScript).

In which scenarios should I consider a functional programming languages better suited to do a given task? Besides the so recently popular multicore problem of parallel programming.

My personal opinion is that multicore is not the killer feature of FP (at least until Haskell, Scala, Clojure, F# compilers solve the cache locality issue). The killer feature is map, filter, fold and friends which allow a more succinct expression of a large group of algorithms. This is compounded by FP languages having a more concise syntax than most popular OO counterparts.

Additionally FP being closer to the relational model reduces the impedance mismatch with RDBMS... which is - again at least for non-programmers - very nice.

Also when you have particularly difficult to satisfy 'correctness' requirements - in a form that that is difficult to test (common in scientific computing/large data analysis where the goal is to get previously unknown and as such un-specifiable results) FP can offer advantages.

If I decided to switch to a functional programming language which do you consider are the biggest pitfalls that I will face?

  • lack of tool support (F# and some Lisps being the exception, Scala being on the way)
  • harder to squeeze out the last bit of performance from your hardware
  • communities often focusing on different issues than these faced by a large group of commercial software development projects
  • very few developers experienced in the use FP in an industrial setting and if you can find them you probably have to compete with the salary and benefits the financial industry can offer
  • functional style of programming tends to be harder to debug; i.e. observing in between results in a long chain of composed functions is usually not possible in most (all?) debuggers

With so many functional programming languages out there, how would you choose the one the better suit your needs?

  • How many of your issues can be solved by already exiting libraries/frameworks on which platform (e.g. JVM or .Net) how many are brand new? Are there language constructs capable of expressing these problems directly?

  • How much low level control do you need over space and time performance of your application?

  • How strict are your "correctness" requirements?

  • Can you afford to retrain developers and/or compete with the benefits offered by some highly profitable niches in SW development?

Alexander Battisti
  • 1,622
  • 11
  • 11
  • +1 @Alexander this is certainly one of the best answers in this discussion. You brought a new dimension of arguments to the discussion by introducing the human factor, the difficulty to find skilled developers and keep them motivated. I totally agree with your vision of the killer features of FP langs, because every day I see more imperative languages adopting them as well. But your post has opened my eyes to realize there are many things I still do not know about FP. Finally, your point of basing on a existing platform like .Net or Java is certainly very valid and totally sensible. – edalorzo Apr 26 '11 at 12:15
9

If I decided to switch to a functional programming language which do you consider are the biggest pitfalls that I will face? (Besides the paradigm change and the difficulty to evaluate performance due to lazy evaluation).

Assuming you're a C++/C#/Java dev in industry...

Be prepared for grumpy peers who don't want to learn anything. Be prepared for pointy-haired bosses imposing bad language choices "because they were a coder once". Be prepared for pithy academics on forums patronizing you about monoids. Be prepared for endless language wars because Scala doesn't even have tail call elimination and Clojure really requires foot pedals for all the brackets and don't get me started on Erlang.

If you're a web programmer then the biggest pitfall will probably be your hair.

With so many functional programming languages out there, how would you choose the one the better suit your needs?

I'd start with platform:

  • OCaml is great on Linux and awful on Windows.
  • F# is great on Windows and awful on Linux.
  • Scala and Clojure are great on the JVM.
J D
  • 2,332
  • 24
  • 17
  • 1
    When I read "Be prepared for grumpy peers who don't want to learn anything." I wanted to yell: "So true! So damn true!" but it's really sad. – Zelphir Kaltstahl Jan 24 '17 at 16:08
3

For one (admittedly biased) perspective on this question, you might check out Bob Harper's blog, Existential Type. Carnegie Mellon has recently reworked their CS curriculum to teach functional programming first, with other paradigms being taught only once a firm grounding in functional programming has been established, and Harper is giving a blow-by-blow as the new curriculum is rolled out in practice.

Harper is one of the principal developers of the Standard ML programming language, so it's fair to say his own opinion on the matter can be guessed in advance, and he certainly doesn't shy from controversial statements in arguing for this position, but he makes his case well.

jimwise
  • 7,433
  • 1
  • 30
  • 32
  • 1
    +1 This article is certainly very interesting and I will keep it in my favorites from now on. I think that teaching FP first is certainly a nice approach, because it is really difficult to get rid of the imperative thinking if you do it otherwise, and above all if you do not use a purely functional programming language it is difficult to break the old habits. I also see that major OOP languages are incorporating functional features and therefore acquiring the skills and the state of mind of a functional programmer must really be handy in the near future. Interesting insight, thanks! – edalorzo Apr 26 '11 at 14:12
  • @jimwise: +1 for Harper's article. I find his approach very appropriate. @edalorzo: When you start to think functionally, you get to see the imperative paradigm as some last resort that you have to apply to optimize your program when it is not fast enough. I have been writing some small tools in Scala recently, not very big but non trivial ones and with some real functionality. To my astonishment I haven't used `var` or any mutable collection one single time. So, imperative thinking is IMO some kind of premature optimization which, as we all know, is the root of all evil. – Giorgio Oct 30 '12 at 18:36
2

In which scenarios should I consider a functional programming languages better suited to do a given task? Besides the so recently popular multicore problem of parallel programming.

There is no magic formula that tells you when to use functional programming. It's not like object oriented programming is suited to our current programming situations any better. It's just another way of structuring programs in terms another set of abstractions.

If I decided to switch to a functional programming language which do you consider are the biggest pitfalls that I will face? (Besides the paradigm change and the difficulty to evaluate performance due to lazy evaluation).

Functional programming has nothing to do with laziness. ML and OCaml are functional and strict languages. The biggest hurdle you'll face is structuring things in terms immutable values and wrapping your head around whatever abstraction is used in the type system for side-effects. Functional languages are better suited for optimization because of the fact that they make side-effects very explicit in the type system. Haskell uses monads but there are other approaches to using effects in pure functional languages. Clean has uniqueness types and some other languages in development have other things.

With so many functional programming languages out there, how would you choose the one the better suit your needs?

Among the programming languages I'm aware of I would say only Haskell and Clean can be called functional languages. All the other ones allow side-effects without making those effects explicit in the type system. So if you're going to devote time to learning functional programming then Haskell is probably the only one that suits the bill. All the other ones I know, Erlang, Scala, Clojure, etc. just provide functional abstractions on top of an imperative language. So if you want to approach the functional paradigm in bits then I'd recommend Scala or Erlang and if you want to tackle everything at once and possibly give up in frustration then you should go with Haskell.

  • @Dadivk01 +1 I like the reasoning that FP langs are just a competitive tool like any other and can be used to solve the same problems as those solved with other models. Why do you think they are less popular, then? And, would you still agree that they are better suited to solve the parallel computing issue than for instance most OOP langs? Would you say that immutable data type have any influence on memory footprint and performance when compared to imperative langs? I was giving it a chance to Haskell, why would you say "give up in frustration", you're frightening me, dude :) – edalorzo Apr 26 '11 at 12:26
  • @edalorzo: I don't think functional programming is any better for parallel algorithms. People confuse declarative programming with functional programming. What functional programming has going for it is its declarative nature and a bunch of really smart people writing excellent compilers to translate declarative code to machine code. Any other language that leans more towards describing problems instead of explicitly spelling out minor details will be just as good for parallel programming. –  Apr 26 '11 at 17:29
  • @edalorzo: As for "giving up in frustration" I say that because if imperative programming is all you know then haskell's type system and its monadic approach to describing effects might be a little too much. I think it's better to start with a language that takes a more pragmatic approach to side-effects like Erlang and Scala. –  Apr 26 '11 at 17:32
0

I would attribute current rise of interes in functional languages to the fact that they are ideal for parallel computing. For example whole idea of map-reduce is based on functional paradigm. And there is no doubt that parallel computing will be on the raise, as it's clear that currently scale-out is way easier and cheaper, than scale-up. Even on consumer market CPUs get more cores, not more GHz.

EDIT: since it's not obvious to all.

In pure functional programming a function takes input, produces output and has no side-effects. Having no side effect, means that it has no shared state, thus no need of synchronization mechanisms, which otherwise would be necessary while running concurrently. Synchronization is the most difficult part of any concurrent/parallel software, thus doing it purely functional, you basically don't have to deal with the hardest part at all.

As for map-reduce, even the name comes from functional programming (both mapping and reducing are typical operations in functional paradigm). Both steps of map-reduce are functions, which run in parallel, take input, produce output and have no side effect. So this is exactly the pure functional programming idea.

Few examples of FP used for parallelism:

  • CouchDB - build on Erlang
  • Facebook chat -- build on Erlang
  • Twitter -- large part build on Scala
vartec
  • 20,760
  • 1
  • 52
  • 98
  • 3
    Everybody makes the parallel programming claim but there is very little data to back it up. If you're aware of any such sources then you should cite them. Complex computations often have complex data dependencies and if you use a functional programming paradigm the inherent data interdependency of some models doesn't magically disappear. GPU programming is as parallel as it gets but they get by using imperative languages just fine because the models they work with have parallelism built in. –  Apr 26 '11 at 11:23
  • @david: map-reduce is well know, and if you don't know it, you can always read up in Wikipedia. As for GPU it's vector computing, which is not the same as generic parallel computing. And btw, didn't it occur to you that if everybody says something, that might be because it's actually true? – vartec Apr 26 '11 at 11:39
  • 4
    @vartec: In the interest of objectivity it would still be nice if you could provide a reference which backs up your claims. It would help the ignorant readers far more than a counter-question... – blubb Apr 26 '11 at 13:51
  • @vartec +1 So, basically your statement is that what is actually becoming popular is parallel computing due to the physical constraints preventing frequency scaling and functional programming has won certain unusual interest lately due to their non-classical concurrency models that simplify the writing of parallel algorithms. Based on your statement, I reinforce the idea that what is worth learning is parallel computing and what concurrency models of FP contribute to implement it more easily rather than learning FP as a goal. Is this what you implied? – edalorzo Apr 26 '11 at 14:44
  • @edalorzo: basically yes – vartec Apr 26 '11 at 14:49
  • 1
    @vartec: Actually no, it never occurred to me that a lot of people making some claim made it true. I blame my mathematics training but hey not all of us believe in things like hard facts and concrete justifications for our claims and your edit still doesn't address my comment. –  Apr 26 '11 at 17:36
  • @david: well, then I'm sorry, but I can't put it any way simpler. If I'd put Q.E.D. at the end of my answer, than you'd understand? – vartec Apr 26 '11 at 21:32
  • 1
    @vartec You could put a reference to a credible source backing your claims. – quant_dev May 18 '11 at 13:20
  • 2
    +1 @davidk01 "Everybody makes the parallel programming claim but there is very little data to back it up". I'm aware of a huge amount of evidence to the contrary. For example, the Cilk papers describe how in-place mutation is essential if you want good cache complexity which is a requirement of scalable parallelism on a multicore. – J D Feb 28 '12 at 12:02
  • 1
    @vartec: "map-reduce is well known". Bad example and the second paragraph on the Wikipedia page you cited actually explains why. Google's map reduce bears little resemblance to `map` and `reduce` from functional programming. It isn't even deterministic... – J D Feb 28 '12 at 12:11
  • 1
    @vartec "Having no side effect, means that it has no shared state, thus no need of synchronization mechanisms". Actually, the exact opposite is true. Lazy evaluation makes everything mutable internally because evaluation mutates thunks in-place into values. Consequently, if two threads race to evaluate a shared thunk then they must either duplicate the evaluation or synchronize. So having no side effects means a potentially huge amount of shared mutable data and synchronization which is one of the reasons why purely functional programming has such unpredictable performance characteristics. – J D Feb 28 '12 at 12:20