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.

In a blog post on F# for fun and profit, it says:

In a functional design, it is very important to separate behavior from data. The data types are simple and "dumb". And then separately, you have a number of functions that act on those data types.

This is the exact opposite of an object-oriented design, where behavior and data are meant to be combined. After all, that's exactly what a class is. In a truly object-oriented design in fact, you should have nothing but behavior -- the data is private and can only be accessed via methods.

In fact, in OOD, not having enough behavior around a data type is considered a Bad Thing, and even has a name: the "anemic domain model".

Given that in C# we seem to keep borrowing from F#, and trying to write more functional-style code; how come we're not borrowing the idea of separating data/behavior, and even consider it bad? Is it simply that the definition doesn't with with OOP, or is there a concrete reason that it's bad in C# that for some reason doesn't apply in F# (and in fact, is reversed)?

(Note: I'm specifically interested in the differences in C#/F# that could change the opinion of what is good/bad, rather than individuals that may disagree with either opinion in the blog post).

share|improve this question
    
"Note: I'm specifically interested in the differences in C#/F# that could change the opinion of what is good/bad" - whose opinion? Note that you used the word "opinion". Do you suffer from being a conformist? Then stop. You are not obligated to write a bunch of oop code in order to use C#. You could use structs when all you need is data, but you must be careful with structs as they get copied by value, and other stuff. Sometimes all you need is a bunch of stateless functions. You have to create a class to encapsulate them, though not in VB.Net. This is just a restriction of the C# language. –  Job Aug 5 '13 at 20:03
    
I was interested in other peoples opinions; so I might learn from them. Lots of people will have opinions based on things I hadn't thought of; I'm simply trying to learn. –  Danny Tuppeny Aug 6 '13 at 5:52
1  
Hi Dan! Your aditude is inspirational. Besides the .NET(and haskell) platform I encourage you to look at scala. Debashish ghosh has written a couple of blogs about domain modeling with functional tools, it was insightful for me, hopefully for you too, here you go: debasishg.blogspot.com/2012/01/… –  AndreasScheinert Aug 8 '13 at 10:44
    
"Given that in C# we seem to keep borrowing from F#, and trying to write more functional-style code" Because some things are easier in functional or useful, but I think this implies people want c# to move from oo to functional, which I disagree with. I think its giving he developer a choice to use functional paradigms when its easier, but its to supplement not replace oo. –  Andy Mar 18 at 1:29
2  
I was sent an interesting blog post by a colleague today: blog.inf.ed.ac.uk/sapm/2014/02/04/… It seems that people are starting to challenge the idea that anaemic domain models are outright bad; which I think might be a good thing! –  Danny Tuppeny Apr 2 at 16:58
add comment

1 Answer 1

up vote 27 down vote accepted

The main reason FP aims for this and C# OOP does not is that in FP the focus is on referential transparency; that is, data goes into a function and data comes out, but the original data is not changed.

In C# OOP there's a concept of delegation of responsibility where you delegate an object's management to it, and therefore you want it to change its own internals.

In FP you never want to change the values in an object, therefore having your functions embedded in your object doesn't make sense.

Further in FP you have higher kinded polymorphism allowing your functions to be far more generalized than C# OOP allows. In this way you may write a function that works for any a, and therefore having it embedded in a block of data doesn't make sense; that would tightly couple the method so that it only works with that particular kind of a. Behaviour like that is all well and common in C# OOP because you don't have the ability to abstract functions so generally anyway, but in FP it's a tradeoff.

The biggest problem I've seen in anemic domain models in C# OOP is that you end up with duplicate code because you have DTO x, and 4 different functions that commits activity f to DTO x because 4 different people didn't see the other implementation. When you put the method directly on DTO x, then those 4 people all see the implementation of f and reuse it.

Anemic data models in C# OOP hinder code reuse, but this isn't the case in FP because a single function is generalized across so many different types that you get greater code reuse since that function is usable in so many more scenarios than a function you would write for a single DTO in C#.


As pointed out in comments, type inference is one of the benefits FP relies on to allow such significant polymorphism, and specifically you can trace this back to the Hindley Milner type system with Algorithm W type inference; such type inference in the C# OOP type system was avoided because the compilation time when constraint-based inference is added becomes extremely long due to the exhaustive search necessary, details here: http://stackoverflow.com/questions/3968834/generics-why-cant-the-compiler-infer-the-type-arguments-in-this-case

share|improve this answer
    
What feature(s) in F# make it easier to write this sort of reusable code? Why can't code in C# be as reusable? (I think I saw the ability to have methods take arguments with specific properties, without needing an interface; which I guess would be a key one?) –  Danny Tuppeny Jun 28 '13 at 17:27
5  
@DannyTuppeny honestly F# is a poor example for comparison, it's just a slightly dressed up C#; it's a mutable imperative language just like C#, it has a few FP facilities that C# doesn't have but not much. Look to haskell to see where FP really stands out and things like this become much more possible due to type classes as well as generic ADTs –  Jimmy Hoffa Jun 28 '13 at 18:16
    
@MattFenwick I'm referring explicitly to C# in that because that's what the poster was asking about. Where I refer to OOP throughout my answer here I mean C# OOP, I'll edit to clarify. –  Jimmy Hoffa Jun 28 '13 at 18:17
1  
A common feature among functional languages allowing this type of reuse is dynamic or inferred typing. While the language itself may use well-defined data types, the typical function doesn't care what data is, as long as the operations (other functions or arithmetic) being performed on them are valid. This is available in OO paradigms as well (Go, for instance, has implicit interface implementation allowing an object to be a Duck, because it can Fly, Swim and Quack, without the object having been explicitly declared as being a Duck) but it is pretty much a requisite of functional programming. –  KeithS Jun 28 '13 at 18:17
1  
@KeithS By value based overloading in Haskell I think you mean pattern matching. Haskell's ability to have multiple top level functions of the same name with different patterns desugars immediately to 1 toplevel function + a pattern match. –  jozefg Jul 5 '13 at 11:44
show 2 more comments

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.