31

As a Java/C#/C++ programmer I hear a lot of talk about functional languages, but have never found a need to learn one. I've also heard that the higher level of thinking introduced in functional languages makes you a better OOP/procedural language programmer.

Can anyone confirm this? In what ways does it improve your programming skills?

What is a good choice of language to learn with the goal of improving skills in a less sophisticated language?

4
  • 3
    If you're coding in C#, you already know one. LINQ is quite a functional thing.
    – SK-logic
    Commented Feb 8, 2011 at 11:08
  • I think OOP is better for modeling real life objects. Commented Jul 2, 2013 at 17:27
  • 1
    @user61852 Most OO design patterns don't model anything about "real life" objects, but actually highly abstract concepts.
    – Andres F.
    Commented Jul 2, 2013 at 17:29
  • Be more than a Java/C#(+C++) programmer. There's a difference between a gigantic swiss army knife with a not-so-little pamphlet that outlines why you'd select blade X out of 40 and a blade you can carve out damn near anything you please with because it's both damn sharp and curves just right such that you can apply it's cutting power to a wide variety of circumstances without much thought. (with a bottle-opener in the handle of course) Commented Jul 3, 2013 at 2:57

6 Answers 6

35

I basically agree with FrustratedWithFormsDesign's answer, but you also asked how learning the new paradigm helps develop one's skills. I can give a couple of examples from my own experience.

Since learning functional programming, I'm much more conscious about which concepts I work with are more naturally considered as "objects" (generally where mutation makes sense) and which are more naturally considered as immutable "values" (I think there's an important distinction, touching on where OO makes sense vs. when FP makes sense, but that's just my opinion).

I notice where my code includes side effects, and I'm more careful to isolate those places, making more of my functions "pure" functions. This greatly improves the testability of my OO code.

I'm more conscious about cycles in my data representation. (For example, I don't think you can write a function to convert a linked-list into a doubly-linked list in Haskell, so you do notice cycles quite a bit more in that language.) Avoiding cycles reduces the amount of synchronization you need to perform for your data structures to be internally consistent, easing the burden in sharing these structures between threads.

I'm more likely to rely on recursion (scheme's recursive looping constructs are things of beauty). Dijkstra touched on the importance of this in Notes on Structured Programming - recursive algorithms map very directly to mathematical induction, which he suggests is the only means to intellectually prove our loops correct. (I don't suggest that we must prove our code correct, but that the easier we make it for ourselves to do so, the more likely it is that our code is correct.)

I'm more likely to use higher-order functions. John Hughes' paper, Why Functional Programming Matters. It emphasizes the composability you get from employing functional programming techniques, higher-order functions playing a major role.

Also, as touched on in Jetti's answer, you'll find that a lot of FP ideas are being incorporated into newer OO languages. Ruby and Python both provide many higher-order functions, I've heard LINQ described as an attempt to bring support for monadic comprehensions into C#, even C++ now has lambda expressions.

6
  • @Aidan: wrt lambdas in C++0x, at any rate the new C++ compilers have incorporated them already. Commented Feb 8, 2011 at 7:34
  • 1
    "Object" as "thing that holds mutable state" is very common, but the Value Object pattern's been around for many years. Commented Feb 8, 2011 at 9:34
  • @Matthieu, thanks, I've updated the text to reflect that. Commented Feb 8, 2011 at 15:14
  • @Frank: thanks for the pointer. I didn't include this in the answer, but the main objection I have to making Values into Objects has to do with the distinction b/w object interfaces (which are owned by objects) and operations (in which the relationships between objects are more primary than the objects themselves). 1 + 2 is mathematically equivalent to 2 + 1, but 1.+(2) is implemented differently than 2.+(1). There exist a number of SW problems than can be understood more naturally using operations than using object interfaces. Commented Feb 8, 2011 at 15:29
  • 1
    @Aidan Have you read William Cook's "On Understanding Data Abstraction, Revisited"? It delves into the differences between objects and ADTs, which is what you're hinting at. Commented Feb 8, 2011 at 16:23
33

I wouldn't say it's guaranteed to make you a better OOP programmer, but it will introduce you to a new way of thinking, and that could make you better at problem-solving in general, not just in terms of OOP.

1
  • 3
    Given that objects are actually higher order functions, I found that learning FP stuff did help directly with my OOP. It is, as you say, more generally applicable/helpful though. Commented Feb 8, 2011 at 9:18
12

Learning a functional language - Lisp for me - really helps when building parallel applications. Functional methods (state based, no side effects) are much easier to synchronize, and are easier to make thread safe since they only depend on their input. That means the only data you need to watch for a given area of code is the parameters you pass in. This also makes it easier to debug.

5
  • You'll find it also helps with threading libraries, which tend to expect pure functions as their tasks. It can also help indirectly, there are places where I'll write OO code in a kind of "functional style" where there's an "owning parameter" that has an implicit lock on a bunch of objects that it references and are used by the function. As long as you document your expectations (and unit test them) this can give you better multithreaded code with few locking issues. And few explicit locks.
    – Мסž
    Commented Feb 8, 2011 at 3:50
  • I've never heard of Prolog being called a functional language. If I squint enough I can vaguely see how (parts of) Prolog could help with FP. Commented Feb 8, 2011 at 9:17
  • 1
    Prolog isn't a functional language. It's a logic language. If you want a Prolog-like logic language that's integrated functional programming as well, mind, you can grab a gander at Mercury. Warning: It will hurt your brain a little even if you know Prolog already. Commented Feb 8, 2011 at 10:56
  • @JUST MY correct OPINION: Yes, I think you're right.Guess I need to learn more about functional languages!
    – Michael K
    Commented Feb 8, 2011 at 14:03
  • 1
    @moz: Yeah, I wish Java had lambdas. Anonymous Threadobjects are...clumsy.
    – Michael K
    Commented Feb 8, 2011 at 14:06
9

Learning any other paradigm of programming will improve your programming skills in general. Programming, when it's not academic research-grade stuff (and even then, often), is basically problem-solving. Thinking, in a word. The various paradigms are different ways of thinking about problems and their solutions. So don't just think of it as "learning a functional language". Think of it as "learning a different way to think about problems and their solutions". Then you'll see the benefits of learning a language even if you never actually use it.

To address your specific question, I was a C++ programmer back in the days of yore (back before there was a standard for C++). I followed all the usual stuff with objects holding state manipulated by methods, etc. etc. etc. Then I stumbled across Haskell and learned (much of) it. (I don't think anybody ever truly learns Haskell.) The exercise seemed a bit wasted at the time until one of my colleagues, the tester assigned to my group, made an off-hand comment that my code was getting easier to test.

What had happened was that I'd started making my objects more and more immutable. Classes with complex mutable state started getting replaced with classes that cloned themselves with changes, returning the new objects. Shared objects started getting replaced with objects that had copy-on-write semantics (thus giving the illusion of lots of object clones without the memory overhead). Functions had no side effects unless absolutely necessary; the pure, mathematical definition of "function" was more and more the norm. All of this started happening in my code naturally -- no conscious thought got involved -- as I explored more and more of the functional programming space.

Now I make it a goal to learn at least one new programming paradigm every two years (even if it's only a minor extension paradigm like AOP) and at least two new languages within each paradigm (one as pure as possible, one more hybrid/practical). Each one has given me new intellectual tools to apply to all of my programming in any language, so the time spent learning them has not, in my opinion, been even slightly wasted.

3

I've said it before and I'll say it again, learning functional languages definitely improved my C#. It helped me understand lambdas (and helped me love them). It also made me realize how much I prefer functional programming (F#) when working with Asynchronous operations!

3

Machine code is nothing more then a list of side effects - commands that are directly executed by the processor. The side effects in C are different, rather then handling the registers and the physical hardware, you deal with a set of a abstractions and let the compiler do all the dirty work. C also lets you structure your side effects in loops and if then statements. C++ improves upon C by adding OOP and some much needed features to the language. Java and C# add garbage collection, and Python adds dynamic typing.

Even with all these features - dynamic typing, garbage collection, etc programs in these languages are still entirely based upon side effects. Functional programming languages, like Scheme, Clojure, Haskell, and ML are something different entirely, these languages are closer to math then to machine code. Rather then using side effects you pass values around functions.

What is a good choice of language to learn with the goal of improving skills in a less sophisticated language?

I recommend Scheme, it is minimal and it was used in MIT's old introductory programming classes. The other functional programming languages are much harder to learn. Clojure brings along all the intricacies of Java with it, ML brings along a complicated static type system, Haskell is sometimes referred to as an academic language - it is not ideal for beginners, and so on. Scheme on the other hand is easy to learn and understand.

In what ways does it improve your programming skills?

Almost all high level programming languages have functions and recursion - the concepts upon which functional programming is based upon. As such your knowledge of FP should be helpful almost everywhere, however, if you really want to program functionally you should use a language where it is a natural and efficient rather then trying to bend someone else's language design to your liking, that is to say you should use a functional programming language to do functional programming.

Not the answer you're looking for? Browse other questions tagged or ask your own question.