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.

Lately, I have been very intrigued with F# which I have been working a bit with. Coming mostly from Java and C#, I like how concise and easily understandable it is. However, I believe that my background with these imperative languages disturb my way of thinking when programming in F#. I found a comparison of the imperative and functional approach, and I surely do recognize the "imperative way" of programming, but I also find it difficult to define problems to fit well with the functional approach.

So my question is: How do I best make the transition from object-oriented programming to functional programming? Can you provide some tips or perhaps provide some literature that can help one to think "in functions" in general?

share|improve this question
2  
This type of question doesn't really seem appropriate for SO, being more methodological than to the point.. –  Kristopher Micinski Apr 24 '12 at 16:40
    
I agree with pad and @KristopherMicinski -- this is really more appropriate to Programmers.SE. Vote to close but hopefully one of the moderators will move it. –  Onorio Catenacci Apr 24 '12 at 16:51
    
Take a look at the questions and answers returned by this search on Programmers.StackExchange.Com [OO And FP Questions](programmers.stackexchange.com/questions/tagged/… ) –  Onorio Catenacci Apr 24 '12 at 16:54
    
Oh sorry, I (obviously) didn't know of that page.. Thanks for letting me know. –  tahatmat Apr 24 '12 at 17:05
1  
@mwilson: There's an accompanying Real World Functional Programming series online. –  Daniel Apr 24 '12 at 19:18
show 1 more comment

migrated from stackoverflow.com Apr 24 '12 at 21:40

This question came from our site for professional and enthusiast programmers.

5 Answers

up vote 18 down vote accepted

Having spent decades writing imperative, i.e. If and While statements, and logical, i.e. PROLOG, programs and having spent the last few months learning F# I will give you some advice from my perspective.

During those decades I have brushed against functional languages such as LISP, and Mercury, with enough understanding to read the code and write simple programs but only until using F# did I learn functional programming with enough detail to write production quality code.

Since you specifically mention the imperative languages Java and C# and the functional language F# I will used them as the basis for my answer. Since you use the term imperative and Object-Oriented in your question and specifically mention Java and C# which are Object-Oriented, I will tend you reference Object-Oriented instead of imperative.

Advise

How do I best make the transition from object-oriented programming to functional programming?

The first advise I will give is to NOT try and translate any imperative programs you already have into a functional language. This probably goes against most of the advise you will see, but I firmly believe that you need to build up the constructs of how functional programming works in a simple manner rather than continuously trying to think in imperative and then try to think in functional. The reason is, is that functional programming relies heavily on recursion, matching, discriminated unions, functions and first class, let binding, and is function-level programming, while Object-Oriented code relies heavily on objects, polymorphism, inheritance, encapsulation, interfaces, and is object-oriented. The point here is that while they are both programming languages they really on two different ways of thinking. The best analogy I can think of, all be it a bad one is, it would be like trying to translate poetry into math. While I am sure you could do it and lay claim that it could be done, they both have very different uses and are well regarded by those who use it.

The second advise is to get one or two good books on F#. I have most of the books of F# and find that most of them are more reference than reading books which is good for the first few weeks, but after that you need to tie the concepts together and don't want a reference book. If I had to chose two books they would be "Expert F# 2.0" by Syme, Granicz, and Cisternino, and "Real-World Functional Programming With examples in F# and C#" by Tomas Petricek and Jon Skeet. "Expert F# 20" is more of a reference book and "Real-World Functional Programming With examples in F# and C#" is a book you read from start to end; don't use it as a refrence book. If "Expert F# 2.0" is not your style then as a substitute I would look at "Beginning F#" by Robert Pickering, or "Programming F#" by Chris Smith.

The third advise is to get a good IDE, e.g. Visual Studio 2010, for using F#. Don't think of this as learning a new programming language but learning a new way of thinking. Most of the errors you get back will be unlike anything from OO and the more you can use an IDE as a crutch, the faster you can hobble along; believe me, you will be hobbling along unless you already know a functional language. In particular, F# uses type inference which causes you to understand this concept to fix the errors.

The fourth advise is to get a mentor. Functional programming relies heavily on recursion and one has to think naturally in recursion to be effective. Luckily for me I learned this when learning PROLOG in college; I can't imagine how hard this would be without a mentor. While it would be possible, it will take longer. If you don't have some one who can mentor you, then use SO. Most of the authors I mentioned answer questions here.

The fifth advise is to learn these concepts: Let binding, F# List, recursion, discriminated unions and pattern matching. I probably use these concepts for more than 80% of the F# code I write. The reason you need F# list is that you will see code that traverse list building a second list of results and then reversing the list before returning the list of results. Because accessing the head of a list is O(1), this is both very fast and effective. The reason you need recursion is because functional programming does not use loops but recursion to preform looping. If you use a tail-call, you have effectively made a loop which does not cause stack overflows. The reason you need discriminated unions and pattern matching is because you can create a single data type, i.e. discriminated union, that holds all of the information for a function, and when combined with matching this is very effective. Microsoft's Introduction to F# is pretty good for these topics.

The sixth advise is don't rush ahead. If you can not explain a part of F# to someone else with enough confidence and clarity to understand it, then you need to keep learning.

The seventh advise is to understand that functional programming is not a solution to all problems. While F# adds OO concepts to functional programming, I try to avoid the use of those concepts when programming with F#. Yes I try to be a purest. By doing this, it keeps me focused on doing with F# what functional programming is best.

The eighth advise is that once you feel comfortable with many portions of functional programming, write a real program based on a real world problem. I find myself learning more about F# from working on a particular problem than working on made up problems. I have learned so much in the last few months, I won't even try and list it all here. One big benefit has been learning FParsec and a lot about LISP. Since my problem deals with AI, a lot of the books I read give sample code in LISP which I have to translate into F#. Since LISP people like to enter data as S-expressions and LISP can process S-expressions, they tend to get away with skiping parsing; thus a reason to learn FParsec.

I could list more items of advise, but at this point it becomes more of a list than sound advise.

Examples

Can you provide some tips or perhaps provide some literature that can help one to think "in functions" in general?

Probably the easist way to identify problems that can be solved with functional programming is to look at the data structure definitions.

If you have a class or structure that has a reference back to the same class or structure and you traverse from one object to next using the reference then you should consider using functional programming for the solution.

A simple example is a linked list where you have to process all of the items in the list. You start on the first item in the list, then process then next item in the list until you reach the end of the list.

A more advanced example is a tree where you have to process all of the items in the tree. You start at the root of the tree, then process each child in the tree until you have no more children left. See: tree traversal

An even more advanced example is a graph where you have to process all of the nodes in the graph. You start with a node, then process each adjacent node, keeping track of visited nodes, until you have no more unvisited nodes left.

Also if you have a sequence of data that needs to be generated from a starting value then consider using functional programming for the solution.

Another large area where functional programming is useful is with Catamorphisms. While this is an advanced concept, think of it simply as a set of data that can be enumerated. You can map the data, e.g. an indentity number into and name, and fold the data, e.g. sum up all of the values in a list. Any time you see an enumeration in an OO language, see if it can be solved with a recursive function.

Other more advanced ares were functional programing is used often is with parsing, theorem provers and AI.

If you can find code written in other functional languages, then try and translate that to F#.

Good luck.

share|improve this answer
    
I'm familiar with most of the code concepts and data structures you mentioned, but I found your 1st, 2nd and 8th advice very helpful. I started reading the online version of Real-World Functional Programming (mentioned by Daniel) and from what I read so far that seems to be exactly what I was looking for, and I will most likely buy a copy. Thanks for the enthusiastic answer! –  tahatmat Apr 26 '12 at 16:55
    
@tahatmat Did you know that Tomas Petricek answers alot of F# questions at SO? stackoverflow.com/users/33518/tomas-petricek –  Guy Coder Apr 26 '12 at 18:22
    
I knew Jon Skeet did, but not Tomas Petricek - nice to know! –  tahatmat Apr 26 '12 at 19:37
    
"A single, well thought–out discriminated union, together with appropriate pattern matching code, can often be used as a simpler alternative to an object hierarchy." See: When to Use Classes, Unions, Records, and Structures –  Guy Coder Jan 18 at 12:56
add comment

Here's an idea:

  1. write/rewrite a program in F# as easily as possible, which may be thoroughly imperative
  2. make incremental improvements
    • eliminate mutability
    • look for loops that can be replaced with higher-order functions (map, filter, reduce, etc)
    • try replacing trivial type hierarchies with discriminated unions
    • replace conditionals, especially nested ones, with pattern matching
    • try separating classes into "data" (DUs, records) and "behaviors" (modules containing let-bound functions)

This is by no means an exhaustive list, merely a "getting started" guide. Beyond this, read good code (F# core/compiler, FSharpx, and WebSharper are all open source) and use F# a lot!

share|improve this answer
add comment

The fact that F# allows you to program both in a functional and in an imperative style could make your task a bit harder at the beginning because each time you have some difficulty you'll want to fall back to more familiar constructs and ways of reasoning.

Have you considered a jump-into-cold-water approach, e.g. trying to learn a purely functional language like Haskell (a good book is Real World Haskell) first? This will force you to reason in a functional way for some time and to concentrate on general concepts without being distracted by the imperative paradigm. Like with foreign languages, you learn a language much faster when that language is the only one that you can use.

You do not need to become a Haskell expert, I would say that a few months of Haskell is sufficient. When you are proficient enough that you can write a small tool in Haskell (e.g. a tool that can process some text file and extract some information from it), you can go back to learning F# and you will probably find many concepts and a way of reasoning that has already become familiar to you. And especially, you will find it much easier to separate the imperative from the functional aspects of F# as you learn it.

share|improve this answer
4  
I'm all in favor of jumping into the cold water. But I'd suggest "Learn You a Haskell for Great Good" as more beginner friendly book. –  scarfridge Apr 25 '12 at 9:31
    
@scarfridge: Thank you for the hint. I have not read "Learn You a Haskell for Great Good" but I will definitely take a look at it when I have some time. I have learned some Haskell as an intermediate step between Java and Scala. Scala is so easy to learn now! –  Giorgio Apr 25 '12 at 10:27
add comment

I highly recommend "Real World Functional Programming: With Examples in F# and C#" by Tomas Petricek and John Skeet, it contains /as the title sujests/ a lot of equivalent examples in F# and C# that make it much easier to make the connection. For general introduction to functional programming I also recommend the classic "Structure and interpretation of Computer programs" that is available for free online together with the corresponding video lectures from MIT from 1986 or so... The first 3 chapters did it for me. If you want to go deep take a look at some lambda calculus papers also available online, it is the grand-father of all functional programming languages and is a great joy to explore.

share|improve this answer
add comment

The other answers have good references. My advice is just to restrict your pride for a bit and do it. It will be like learning for the first time again- you'll write a lot of terrible code at the start but you'll get the hang of it. Take a realistic expectation that it will take some time writing some nasty code before you get the hang of it and everything will turn out ok.

Best of luck, remember to keep it fun!

share|improve this answer
add comment

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.