Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am pretty well-versed in imperative paradigms. I learned Java and C++ before I dropped out of university, after which I taught myself Python. My problem is that even beginner tutorials get way far over my head pretty quickly and I'm not sure if there's something specific I'm missing or not understanding or if I just can't quite wrap my head around the whole paradigm just yet. I made it all the way to Section 4.7 of the Haskell Tutorial for C Programmers before I couldn't understand it anymore.

Am I missing something foundational (like those last two years of university)? Or should I just keep going slowly and hopefully it will click? Put another way, what information would help me best bridge the gap between an imperative paradigm and a functional paradigm?

share

migration rejected from stackoverflow.com Sep 26 at 12:03

This question came from our site for professional and enthusiast programmers. Votes, comments, and answers are locked due to the question being closed here, but it may be eligible for editing and reopening on the site where it originated.

closed as off-topic by gnat, GlenH7, Doval, MichaelT, Bart van Ingen Schenau Sep 26 at 12:03

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions seeking career or education advice are off topic on Programmers. They are only meaningful to the asker and do not generate lasting value for the broader programming community. Furthermore, in most cases, any answer is going to be a subjective opinion that may not take into account all the nuances of a (your) particular circumstance." – gnat, GlenH7, Doval, MichaelT, Bart van Ingen Schenau
If this question can be reworded to fit the rules in the help center, please edit the question.

5  
You should have learned how to bend your mind around the unknown in your first year in the university. As well as all the math you'd need (set theory, some basic logic). You must be well equipped already - just try harder. –  SK-logic Sep 14 '11 at 8:07
2  
    
A nice recent article about the topic is functional thinking for the imperative mind –  faif Aug 16 '12 at 17:11
    
You should understand that functional programming is not a silver bullet and although useful in some cases, it has its limitations in other cases. –  m3th0dman Sep 26 at 9:50
    
I too had problems switching to functional programming, i.e. Haskell in my case. Elm was what helped me a lot in this transition. In case you are interested, here is an article I wrote about my experience. –  Dobi Sep 26 at 11:00

10 Answers 10

Nan-in, a Japanese master during the Meiji era (1868-1912), received a university professor who came to inquire about Zen.

Nan-in served tea. He poured his visitor's cup full, and then kept on pouring.

The professor watched the overflow until he no longer could restrain himself. "It is overfull. No more will go in!"

"Like this cup," Nan-in said, "you are full of your own opinions and speculations. How can I show you Zen unless you first empty your cup?"

http://www.ashidakim.com/zenkoans/1acupoftea.html

The hardest thing about learning FP is forgetting what you think you "know". It might be true, but not in this context. Everything is different, so you need to start from the very beginning.

If you know C++, and you want to learn Java, you compare both languages all the time, and this works fine. It's the same with natural languages: If you know English and want to learn Spanish, it's okay to compare both languages all the time, as they follow the same indo-germanic paradigm. But if you want to learn something fundamental different, like Japanese, or Haskell, you have to "unlearn" first. You won't make real progress until you stop comparing.

share

I used to lecture on Haskell and related stuff.

The most important idea IMHO is that functional programming is about data and transformations. A lot of people forget to mention this in their rush to get to complex stuff (and the complex stuff is just about getting more control and power over the basic stuff). Nothing mystical!

I'd also recommend getting up to speed on unix pipes and tools first, eg think about how you'd handle (slightly contrived) examples like the following. Convert the output of ps into a shortlist of memory-hogging processes then into a page of html links with a summary of the info plus a file link into /proc/nnn etc

If you get this, then stuff like "unwords . map reverse . filter (\w -> length w > 3) . words" will not be a mystery

share

FP requires much more abstract thinking to understand as it has more powerful abstraction and works at higher level of abstraction that imperative programming. So I would suggest try to improve your abstract thinking (it will take some time, but when you finally get it you will feel this amazing sensation in your head that you probably never had before). Go slowly through the book if you don't understand some abstract concepts try to go through them more then once or ask questions in here or SO for people to help you understand those concepts.

share

Functional programming is a style, which you can use in many languages, although it's more natural in some than others. Out of those you've listed, Python is the "most functional" (it has first-class functions, built-in support for list/dictionary comprehensions, built-in map/reduce/filter functions, etc.). I recommend that, as well as learning Haskell, you try to apply what you learn to your Python code (when appropriate).

This will do a few things:

  • Make you more familiar with functional programming techniques
  • Give you fresh perspectives on existing code, eg. the similarities and differences betwee OO and functional styles
  • Make you appreciate various functional programming features, by trying to live without them ;)

Most functional programming boils down to defining values rather than performing steps. Some techniques you may want to try in Python are:

  • Ternary operators instead of if/else(/elif). This is much easier with LISP-like cond expressions or pattern-matching case expressions:

#Imperative if valid(x): return x return default

#Functional return x if valid(x) else default

  • Single-assignment variables. Rather than changing the contents of an existing variable (or using a setter method on an object), try defining new variables (or instantiating fresh objects). This is much easier when functions/methods return copies (eg. cons compared to myList.append()):

def imperativeAverage(a, b, c): total = a total += b total += c return total / 3

def functionalAverage(a, b, c): ab = a + b abc = ab + c return abc / 3

  • Recursing instead of looping. This is much easier with tail-call optimisation. Without it, stack overflows force you to limit this to a small, known number of iterations (eg. retrying after a failure):

def imperativeFunc(x, y = None): if y is None: y = makeY(x) return process(x + y)

def functionalFunc(x, y = None): return functionalFunc(x, makeY(x)) if y is None else process(x + y)

  • Separating data processing from control flow. This is easier when datastructures come with higher-order traversal functions (eg. map, fmap, fold) rather than first-order element-getters (eg. generators, iterables). It's also a case for "100 functions on 1 datastructure" vs "10 functions on 10 datastructures":

#Imperative result = [] for elem in collection: result.append(len(str(elem + 10)))

# Functional def process(elem): return len(str(elem + 10))

result = map(process, collection)

  • Separating calculation from actions. This is easier when we have action-combining functions like <*> (from Applicative), >>= (from Monad), etc. and derivatives (like sequence).

def imperativeFunc(x): if len(x) is 0: print "empty" return 1 if len(x) > 10: print str(len(x)) print "recursing" return sum(map(imperativeFunc, x))

val = imperativeFunc(...)

def functionalCalc(x): big = [str(len(x))] if len(x) > 10 else [] recursed = map(functionalCalc, x) return (["empty"], 1) if len(x) is 0 else (big + ["recursing"] + [s for (s, i) in recursed], sum([i for (s, i) in recursed])

(s, val) = functionalCalc(...) map(sys.stdout.write, s)

  • Use dictionaries of functions instead of switch/elif statements and classes. Features like Haskell-style type-classes, ML-style modules and Scala/Agda-style implicits make this easier:

def imperativeProcess(x): if thing(x): return doThing(x) elif stuff(x): return doStuff(x) elif blah(x): return doBlah(x) return doDefault(x)

def functionalProcess(x): funcs = {thing(x): doThing, stuff(x): doStuff, blah(x): doBlah} return funcs[True](x) if True in funcs else doDefault(x)

share

Seconding Landei, I want to add:

From my own experience I know that an imperative programmer automatically tries to map a programming problem into a problem of how to modify variables, store intermediate results, etc. hence onto an already very low abstraction level.

It takes some time until oneself notices how inappropriate this is in the context of pure FP. There you ask what a certain function IS, not what it DOES.

share

I think your problem is that a lot of the FP literature is the product of academia, and so the classical academic style of language is used - inventing new terms and making them complex so that everything can be worded very precisely and unambiguously.

You'll just have to keep with it until you get used to the funny language. Its kinda like calculus - its easy to teach and understand when you talk about slopes, areas, rates and such for the simpler things - concepts most people become familiar with at a young age and which have everyday relevance. Start talking about calculus, integrals and derivatives and people will get lost even though you are talking about exactly the same things - however a more precise language is necessary to move on to more advanced concepts.

Think about how many people cite calculus as a example of something with no everyday usage, but wouldn't dream to make the same statement about speeds, slopes, areas and such - despite the fact that they are identical.

I reach this conclusion based on where you get stuck in the guide for C programmers.

Stick with it. The beautiful thing about the human brain is that provided there is positive/negative stimulus it will learn anyway - even if you don't understand it or consciously think about it.

share

There is nothing you have to learn. Haskell is just hard.

In order to get Haskell, your brain will have to get seriously rewired, keep trying until that happens.

The one thing you might want to learn is recursion, but you can just do that by writing some Haskell.

share
1  
Well, all those while loops that one writes in imperative languages are also a form of recursion. So, nothing new to learn, just a different way of looking at it. –  Giorgio Feb 25 at 18:10

According to the 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

To program functionally you basically need two know two things:

  • Everything is a constant. Nothing is mutable.
  • No side effects: your functions must only use the arguments you passed, no globals or anything.

Your program just

output = f(input)

So if you pick your favorite programming language and never assign a variable twice, you essentially programming functionally.

share
    
If your language doesn't support a lambda or delegate feature, then how do you write the Map function? Functional programming is more than just immutability. –  Scott Whitlock Sep 25 at 20:21
    
@ScottWhitlock Every sane imperative language have the concept of function pointers or anything like that can be used to pass a function as parameter. It's supported by very old languages like PL/1, COBOL, C, Pascal, etc... Using these you can write mapping functions. –  Calmarius Sep 26 at 9:49

One stepping stone to fully functional programming is learning a language that has functional concepts built in. You mentioned knowing python, which does have some functional concepts (higher order functions, lambdas, etc.) so it should give you a bit of a jumpstart.

For me C# (and LINQ in particular) helped me open my mind to a lot of functional concepts so that when it came time to sit down with a truly functional language (in my case it was erlang), most of the concepts were pretty familiar already. The rest just took me looking at things from a different angle.

That being said, I agree with what others have stressed, approach the new paradigm with fresh eyes, unlearn what you "know", and embrace learning anew.

share

For me, haskell just didn't work. I tried two times to 'get' haskell, but I never did.

First when I learned Common Lisp (using the book Land of lisp which uses functional programming), I finally got it. I later moved to Clojure which works even better.

For me, simplicity is very important, and functional programming is a simplistic paradigm. Haskell with it's syntax and enforcing pure functions, isn't. That makes haskell inadequate for me as a functional language.

Learning functional programming is therefore preferably not done in haskell, since the syntax is always in the way.

share
    
I agree Haskell is hard, but out of curiosity, what do you mean "the syntax is always in the way"? I find purity and laziness are the real difficulties (and of course, Monads, Applicatives, etc.), not so much the syntax. –  Andres F. Nov 13 '11 at 21:23
    
In lisp, you have a list, values and some syntax that changes the interpretation of those lists. With a bit of simplification, that's it. When I say that the syntax is in the way, I mean that it's overly complicated, compared to lisp syntax. –  odyssomay Nov 14 '11 at 21:30
3  
-1, "I don't understand Haskell, therefore no one else can and you shouldn't either". –  dan_waterworth Aug 16 '12 at 18:39
    
+1: Discouraging Haskell as a starting point is a valid point of view. There are other, more forgiving languages for someone with imperative background, you don't need to go 'all pure' to get a taste of FP. –  scrwtp Sep 26 at 13:39