First off, immutability, laziness, and such are not strictly elements of functional programming. For example, Lisp (one of the first practical functional programming languages) has both mutation and strictness.

I think probably the better approach is to start with the fundamentals. In MIT and Berkeley, we used to teach using a now classic book called SICP (Structure and Interpretation of Computer Programs). The first chapter covers the core concepts of functional programming, and I highly recommend it. Doing the exercises is necessary to really get a grasp.

The book uses Lisp, but the syntax is so lightweight that it shouldn't be an issue.

http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-4.html


The class taught at Berkeley and MIT is the first class that computer science majors take. Most of the students who took the course were already familiar with imperative programming, and while it can be a little mind bending at first, everyone eventually gets a grasp of it after the homework.

If you are looking for the lectures, you can find them on youtube (or otherwise) by these course numbers. It always the first thing taught in the class.

Berkeley: CS61A
http://www.youtube.com/watch?v=zmYqShvVDh4 (and the following ones)

MIT: 6.001
http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/video-lectures/

James


On Thu, Oct 16, 2014 at 7:59 PM, John Wiegley <johnw@newartisans.com> wrote:
>>>>> Birmjin In <yinbirmjin@gmail.com> writes:

> It seems more difficult than it looks - thinking in functional programming
> way for the long time C, C++ and Java developers.

C/C++ and Java all have a functional component: their expression language.
Since this is the only way to writie constexpr functions in C++, for example,
such functions must be FP in nature.

I think the thing to get across is how a functional programs mutate values
through a composition of smaller components: each function takes in an
argument, and returns a result which is derived from that argument.

This, of course, can be terribly inefficient in languages like C++, which do
not have full support for taking advantage of things persistence, the way
Haskell does.  This is usually where a biggest disconnect happens: the
functional "way" feels wrong, because it's not how you would ever write
efficient C++.  Teaching them to think that way requires viewing the
"progression of data" in a completely different way.

I remember it took me months to become comfortable with folds rather than for
loops, exactly because of this distinction.  Folds in C++ are a bit of a pain,
and can be wasteful; while mutative iteration in Haskell is likewise a pain.

I don't this gap can be bridged simply by taking one camp and showing them
another language, and thinking that the insights will occur by themselves.
You also have to talk about data structures, and how the whole concept of data
flow through a program fundamentally changes when you have the facilities of a
functional programming environment at your disposal.

So, with an FP environment comes methodologies that are tuned for FP, and
these methodologies do not always have direct analogues.  What is good for one
is not necessarily good for the other and vice versa.  If you asked a C++
programmer how he'd compute Fibonacci using only the expression sub-language
of C++, he could do it -- and he'd end up with a functional-style solution by
doing so.  But it would feel like tying his hands behind his back -- a feeling
anyway who has done any template meta-programming has felt, since that is also
a functional subset of C++, where most of the idioms are missing.

I think that once the data flow model can be understood, and its benefits (in
the scenarios where it does have benefits), then presenting how functional
languages take advantage of these can make a lot more sense.

John
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe