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.

Is functional programming just different, or is it actually really tougher?

Say someone who have never learned programming at all before, and is taught functional programming. vs someone who have never learned programming at all before, and is taught imperative programming. which will he find tougher? or the same?

My question: say the problem now is to camel-case an input,

such that qwe_asd_zxc_rty_fgh_vbn becomes qweAsdZxcRtyFghVbn

The procedural way is:

  1. split it along the _
  2. loop through the array skipping the first item
  3. for each entry we capitalise the first letter
  4. join the results together

The functional way is:

  1. if cannot find _ return input
  2. cut the input along the first _ (such that we get qwe and asd_zxc_rty_gfh_cvb)
  3. capitalise the first letter of head and concat that with f(tail)

Ok if you have a functional-background AND have substantial experience in procedural-programming, I would like to ask: will it take you longer to figure out the procedural way or will it take longer for you to figure out the functional way?

If you have a procedural-background but have many years of experience with functional-programming, I would like to ask the same question: will it take you longer to figure out the procedural way or will it take longer for you to figure out the functional way?

share|improve this question
5  
Ehrm, the "procedural way" seems perfectly functional to me if we use map for step 3 instead of a mutating loop. The second approach is something I'd only consider if there is no split function in the standard library (in which case it should be compared to an imperative solution which also does not use split). –  sepp2k Jun 10 '11 at 4:58
8  
There's nothing specifically functional or procedural about either of your examples. It sounds to me like you're trying to extrapolate from a faulty understanding of functional programming. No wonder you're getting unusual results. –  Rein Henrichs Jun 10 '11 at 5:12
    
I don't think that functional programming is tough, it's just different. If you have no programming experience either are just as easy to learn, but for some reason once you learn imperative programming, functional programming becomes difficult. –  dan_waterworth Jun 10 '11 at 5:17
1  
I think the distinction between functional and procedural becomes moot, since maintstream languages like JavaScript, C#, Groovy contain more and more functional features. –  user281377 Jun 10 '11 at 7:59
2  
Imperative programming is much more difficult and counter-intuitive for those who had no previous programming experience. An expression like x=x+1 can blow up an unexpecting brain. Functional programming is natural, it is nothing more than pure and convinient strictly mathematical functions. –  SK-logic Jun 10 '11 at 10:35

5 Answers 5

up vote 12 down vote accepted

Just different. Functional programming is much more closely related to mathematics, which most people are familiar with. The whole "immutable variables" thing only comes a shock to imperative programmers where the "mutable" mindset is deeply ingrained.

To newcomers, it is often fairly intuitive that you can't just change the value of something.

Where I studied CS, we were taught a functional language as our very first course. And everyone who'd learned C++ or Java previously struggled with it. Those who were new to programming picked it up fairly easily.

share|improve this answer
    
jalf are you one of those new to programming and picked it up fairly easily? –  Pacerier Jun 10 '11 at 9:36
    
I was somewhere in between. I'd poked around a little bit with C++ and some PHP before then, but not enough to really get used to the imperative mindset. The pattern was pretty clear when you looked at the class as a whole. Also, this was nearly a decade ago, so no, I'm not quite new to programming today ;) –  jalf Jun 10 '11 at 10:05

It's just different

When you program you essentially translate the way you reason into code, the distance between your thoughts and the final solution might be said to be the "cognitive gap". The bigger the gap the harder it'll be for you to bridge it.

If you come from a procedural background you will have trained yourself to think procedurally so the gap will be less then for functional code, and vice versa.

The only way for a programming paradigm to be intrinsically easier than anything else would be if it mapped to something you already knew, like ordinary language, so you'd start off with a shorter gap.

Functional and procedural is a pretty fluid concept anyways and they tend to overlap

share|improve this answer

Yes, functional programming tends to be difficult for many people to comprehend (I'd tend to say, especially those who've already been exposed to procedural programming first).

I'd also say your example of functional programming isn't really a very good example of functional programming though. It's using recursion and just composing a result instead of modifying state, but not much more than that.

To get a better example of functional programming, consider a more general problem: rather than "search for an underscore and convert the next letter to uppercase", consider this as just one special case of searching for a pattern, and executing some arbitrary code when it's found.

A lot of languages support that, but to do so they require that we specify the pattern as something like a regular expression. Regular expressions, however, are nothing more or less than a special-purpose programming language, and an RE implementation is a compiler and/or interpreter for that language. The result of compiling the RE is basically a function that executes (in a special RE virtual machine) to match the expression against some input.

In something like Perl, you use a special language to specify the pattern, and a special compiler to convert that string to some sort of function-like thing, and a special interpreter to take that function-like thing an execute it. In a functional language, you'd typically use the language itself to specify the pattern, and use the language's own compiler to produce a real function. We can generate that function on the fly (about like we can compile an RE when we want), but when we do, the result can execute like any other function in the language instead of needing special RE stuff to do it.

The result is that we can generalize the problem above relatively easily. Instead of hard-coding the '_' and "upper-case" directly into the transformation, however, we can have something like:

s&r(pattern, transform, string) {
    if (!pattern(string))
        return string
    else
        return transform(matched part of string) + s&r(rest of string);
}

But, unlike something where we specify the pattern as an RE, we can specify the pattern directly as a real function, and still use it, something like:

my_pattern(string) return beginning(string) == '_';

And then we pass that function to the s&r. Right now, it's a pretty trivial function, and we've encoded it entirely statically. A functional language largely becomes interesting when we use it like we can REs, and generate an entirely new function on the fly based on something like user input, but unlike an RE that function doesn't need a special RE interpreter to run -- it's just a normal function like any other.

share|improve this answer

Here's the complete code in Racket:

;; camelize : string -> string
(define (camelize str)
  (let ([parts (regexp-split #rx"_" str)])
    ;; result of regexp-split is never empty
    (apply string-append
           (first parts)
           (map string-titlecase (rest parts)))))

(camelize "qwe_asd_zxc_rty_fgh_vbn")
;; => "qweAsdZxcRtyFghVbn"

As a functional programmer with procedural experience, I don't think it would take me longer to "figure out" a procedural solution, but it would certainly take me longer to type it.

BTW, the example expected result in the original post is wrong: it's missing an "h" near the end.

share|improve this answer
    
gd for pointing that out. edited –  Pacerier Jun 10 '11 at 8:02

My pet theory is that programming models are easier to understand the closer they are to the actual working of computers. Pointers are hard to understand until you realize that they are essentially machine addresses. Recursion is hard to understand until you have consciously stepped through a small example, seen the stack frames, and realized where the different values of the same variable are stored. That doesn't mean that assembler programming is easier than high-level programming, but having seen how it's done does wonders for the mental model that is key to proficiency - whether in programming or in general usability.

Now, the procedural model is somewhat closer to the usual machine architecture: assignments are memory (or register) writes. Procedure calls are really just fancy jumps, an if is actually a conditional jump, etc. But in Lisp, for example, there is no simple low-level equivalent to a lexical binding or a lambda expression. Understanding it requires you to imagine a completely separate abstract functional machine between the language level and the physical machine, because and apparently most people never get that far.

(I am familiar with the idea that the von Neumann architecture is ultimately arbitrary, and we shouldn't prejudice beginner's minds with such irrelevant details of machine architecture, and instead directly introduce them to the semantics of programming languages. In fact, I've taught a few such courses myself. But increasingly I feel that this a noble but misguided goal; people learn programming by building understanding from the bottom up, and the way to functional programming is simply a bit longer.)

share|improve this answer
7  
By that logic Assembler should be the easiest of all languages to learn :) –  konrad Jun 10 '11 at 7:19
4  
Functional programming is quite easy to understand if you come at it from the right direction. The "abstract functional machine" you mention is simply algebra. Evaluation is done by term rewriting; function application is done by substitution. Programmers learn to solve problems using the same tools they've already seen in years of math clases. If they pursue CS, there's time enough to meet the stack of turtles later; if not, they've still learned useful problem-solving skills and design principles. Take a look at How to Design Programs. –  Ryan Culpepper Jun 10 '11 at 7:40
2  
@mko No, by this logic the actual bytecodes 011011001001101... would be the easiest language to learn! –  MarkJ Jun 10 '11 at 12:09
1  
@konrad: RISC assembler IS probably the easiest language to learn. To know how to make it do something useful is another story all-together... –  insta Jan 25 '12 at 20:57

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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