views:

1437

answers:

7

From day 1 of my programming career, I started with object-oriented programming. However, I'm interested in learning other paradigms (something which I've said here on SO a number of times is a good thing, but I haven't had the time to do). I think I'm not only ready, but have the time, so I'll be starting functional programming with F#.

However, I'm not sure how to structure much less design applications. I'm used to the one-class-per-file and class-noun/function-verb ideas in OO programming. How do you design and structure functional applications?

+5  A: 

Given that modern functional languages (i.e. not lisps) by default use early-bound polymorphic functions (efficiently), and that object-orientation is just a particular way of arranging to have polymorphic functions, it's not really very different, if you know how to design properly encapsulated classes.

Lisps use late-binding to achieve a similar effect. To be honest, there's not much difference, except that you don't explictly declare the structure of types.

If you've programmed extensively with C++ template functions, then you probably have an idea already.

In any case, the answer is small "classes" and instead of modifying internal state, you have to return a new version with different state.

Marcin
So really, it's a lot of the same stuff. Just a different way of thinking. I noticed that in C, I was using structs in the same way I use classes, which might have been good or bad (I know C, but I'm not C-ace). Similar things apply?
Thomas Owens
I'm not sure how you can apply polymorphic to functional programming.
dacracot
Youcan still modify structs, which is a difference, but it's a similar design process.The main difference is the focus on very well defined, well behaved interfaces, that allow you to use e.g. iteration functions sensibly. That habit helps smooth out programme structures, and speeds development.
Marcin
@dacracot - read this http://en.wikipedia.org/wiki/Type_polymorphism to see how polymorphism applies to functional programming
jop
@jop - You can pseudo-polymorph the data through casting (ie char as an int) but casting and polymorphism imply different things. With polymorphism a Cirle IS A shape through inheritance. With casting, I can really say a char IS A int, just that I can convert a char to an int.
dacracot
Dacracot, you don't know what polymorphism is.Polymorphism in this context is the ability to pass different types to the same function. This is what object-orientation also gives you.
Marcin
I'd add that you didn't read the article that Jop linked to.
Marcin
@Marcin - I get your point, but the asker is looking to find a new paradigm. I suspect he has a idea of what polymorphism is. Making a point where your definition is context sensitive is only going to confuse. It did me.
dacracot
Dacracot, this definition is not context sensitive. This definition is also the definition of polymorphism that applies to OO. Just because you don't understand it, it doesn't make it incorrect or misleading.
Marcin
+9  A: 

Read the SICP.

Also, there is a PDF Version available.

Paul Nathan
See this guy's reading notes on SICP - very comprehensive.http://eli.thegreenplace.net/category/programming/lisp/sicp/
ripper234
Also, http://en.wikipedia.org/wiki/Functional_design
Dan
+2  A: 

Functional programming is a different paradigm for sure. Perhaps the easiest way to wrap your head around it is to insist that the design be laid out using a flow chart. Each function is distinct, no inheritance, no polymorphism, distinct. The data is passed around from function to function to make deletions, updates, insertion, and create new data.

dacracot
I believe a professor talked about this once...something about stomping all over the data to create something new. Is this what he meant?
Thomas Owens
I believe so. A big issue that the functional programming brings to the developer/designer is care and feeding of the data blob. It is separate and a part from the functions. You have to structure it very carefully to be compatible with all the functions that want to get at it.
dacracot
+6  A: 

You might want to check out a recent blog entry of mine: How does functional programming affect the structure of your code?

At a high level, an OO design methodology is still quite useful for structuring an F# program, but you'll find this breaking down (more exceptions to the rule) as you get down to lower levels. At a physical level, "one class per file" will not work in all cases, as mutually recursive types need to be defined in the same file (type Class1 = ... and Class2 = ...), and a bit of your code may reside in "free" functions not bound to a particular class (this is what F# "module"s are good for). The file-ordering constraints in F# will also force you to think critically about the dependencies among types in your program; this is a double-edged sword, as it may take more work/thought to untangle high-level dependencies, but will yield programs that are organized in a way that always makes them approachable (as the most primitive entities always come first and you can always read a program from 'top to bottom' and have new things introduced one-by-one, rather than just start looking a directory full of files of code and not know 'where to start').

Brian
+1  A: 

How to Design Programs is all about this (at tiresome length, using Scheme instead of F#, but the principles carry over). Briefly, your code mirrors your datatypes; this idea goes back to old-fashioned "structured programming", only functional programming is more explicit about it, and with fancier datatypes.

Darius Bacon
+2  A: 

F# provides the conventional OO approachs for large-scale structured programming (e.g. interfaces) and does not attempt to provide the experimental approaches pioneered in languages like OCaml (e.g. functors).

Consequently, the large-scale structuring of F# programs is essentially the same as that of C# programs.

Jon Harrop
+1  A: 

On structuring functional programs:

While OO languages structure the code with classes, functional languages structure it with modules. Objects contain state and methods, modules contain data types and functions. In both cases the structural units group data types together with related behavior. Both paradigms have tools for building and enforcing abstraction barriers.

I would highly recommend picking a functional programming language you are comfortable with (F#, OCaml, Haskell, or Scheme) and taking a long look at how its standard library is structured.

Compare, for example, the OCaml Stack module with System.Collections.Generic.Stack from .NET or a similar collection in Java.

toyvo
Objects do not necessarily contain state. Look at functional object update in OCaml, for example.
Jon Harrop