What are some pros and cons to learning functional programming before other paradigms?
One major problem is that if you start with a language like Haskell everything else will seem just substandard.
Honestly I think starting with a language like Haskell or scheme would be a great idea.
(I admit I am functional language addict) EDIT:
OK what I like about both languages:
Scheme takes a very simple language and build out of it a wonderfully robust language for development. Also SICP is written about scheme which makes it worth learning right there. Scheme is about the simplest thing you could imagine that could be a complete language.
Haskell What is really growing on me is the type system. So many of the bugs I see in other languages are due to the wrong type showing up somewhere. In Haskell that is almost imposible. Also the idea of a lazy language just has some cool things fall out of it. For example you can create infinite data structures in Haskell and then only create the part that you need.
The biggest plus of learning a functional language before learning an OOP lang is that your programming skills get developed first and then you can easily grasp the OOP concepts. If you direclty start with an OOP language you will have to learn two things simultaenously: "to think about the code" and "to think about the OOD". It can get distracting. First practice with a functional language and develop your programming skills. Then learn OOP and other paradigms. Since OOP was desinged to make up for the shortfalls in structural programming it will be easier to understand why. That is the reason CS courses start with C and then go on to C++.
On the question of how to learn programming by starting with functional programming, two classic recommendations:
The first, and obvious one is the classic Structure and Interpretation of Computer Programs, by Abelson and Sussman, which remains one of the best introductions to CS out there, and is taught from a functional perspective, using Scheme. It's available in full online. If you don't start here, you should get here as some point.
A more recent text covering most of the same ground at a gentler pace, and with a stronger focus on software engineering is How to Design Programs, by Matthew Felleisen and a bunch of others from the Racket/PLT team, which uses the Racket dialect of Scheme. It's also available online, as is the in-progress second edition. This book has the advantage that it's designed to be used with the DrRacket programming environment, which provides a very friendly interface for beginner and expert alike to experiment with code.
On the question of why start with functional programming, I'd like to point at Bob Harper's Blog. Carnegie Mellon has recently retooled their CS curriculum to teach functional programming first, and Harper has been covering their progress blow-by-blow on his blog. As one of the guys behind the definition of Standard ML, it's obvious that he's for this move, and he argues the reasons for it well.
Finally, I'd caution against learning Haskell first, though others may disagree. While Haskell's pure approach to FP will certainly breed good habits, the language's focus on lazy computation isn't necessarily a good match for the beginner; one of the first, and most important things you will need to learn to do as a programmer is to reason about exactly what your program is doing by looking at the source, and about the relative cost of different approaches to the same problem. I'ts my experience that Haskell's laziness makes both of these activities somewhat of a challenge for even experienced programmers, though Your Mileage May Vary.
The main advantage (or, non-disadvantage) of starting out with FP is that most concepts can apply to imperative programming as well. Realm of Racket uses video game analogies to teach both functional and imperative concepts, and dedicated students are left with not only a functional game (n.p.i.), but a solid understanding of conditionals, recursion, loops, ADTs, and event-driven design. These concepts are practically ubiquitous in modern programming and are used constantly.
Even more important, though, is learning how to encode abstractions, something in which FP excels, with the use of higher-order functions and data types. How to Design Programs takes a unique approach to this by teaching through induction. For example, students learn how
fold works by looking at the code for taking both the sum and the product of a list, finding what they have in common, and deriving the implementation themselves.
The OOP equivalent of the above would likely involve one or more of the following: interfaces, abstract classes, generics, functors, or (if you're doing it wrong) singletons. While these are perfectly acceptable design patterns in Java, IMHO they do not belong in an introductory curriculum and only serve to obfuscate the underlying principles. Even as someone who was introduced to FP languages "late", I can say that navigating the ever-shifting sea of OOP has been made vastly easier by having a strong functional anchor.
Functional programming makes things a lot easier. In OOP languages, you have to deal with managing state across multiple threads without ruining that state. In functional languages, when the majority of the work being done is being done by pure functions, you don't have to worry about it.
In terms of speed/performance, I'm not a real performance jockey, but being functional doesn't mean being slow, and the structure of functional languages has little to do with their speed. The syntax of functional languages vary greatly such as the differences between Clojure and Haskell. Clojure is very fast as-is, and can reach (and sometimes exceed) the speeds of Java with after-the-fact optimization.
So it all really depends what you are looking for
I think the availability of learning material, some good code samples, and mentors are very important when learning programming languages. Depending on your situation, you may have a mentor that can teach you, etc. but I think functional language resources are very few compared to the mainstream languages. It means you will progress slower compared to learning mainstream languages. But if you are not in a hurry, then this is not a problem.
Perhaps the most important reason to consider learning functional programming languages is the understanding of algebraic data-types. The mental mapping will help in modelling OO class relations and even database design.
The focus on multi-core/multi-processor systems stress the use of parallel algorithms which can be expressed clearer and more concisely in FP. The lambda branch of languages will likely see a strong increase in use in the next one to two decades.
But there are also some common pitfalls. To believe FP is simpler is a big mistake, since calculating the space and time complexity as well as delivering proofs of halting can be much more challenging in lambda calculus, especially in languages which support lazy evaluation.
So, learn both! Or perhaps better: first learn a language which embraces both, such as Scala. If you don't mind tie-die t-shirts and a slight dutch accent, perhaps you'll find the FP lectures by Dr. Erik Meijer useful, which are on MSDN.