Fp Vs Oo

[MergeMe with OoVsFunctional somehow.]

Here we discuss the relation between FunctionalProgramming (FP) and ObjectOrientedProgramming (OO(P)). Is it possible to combine both? And why would one want to do that?


In the impure FunctionalProgrammingLanguages SchemeLanguage and CommonLisp, it is possible to create your own object system. As I understand it, the CommonLispObjectSystem was also the first in any language to receive an ANSI standard, even before CeePlusPlus (!), and it has some interesting abilities not found in the object systems of other languages (e.g., MultipleDispatch).


There is a concept of "FunctionalObject?s" (a.k.a. ValueObjects). Such an object, instead of changing state, returns a copy of itself with changed state. You see them quite often in "non-functional" people's programs, too...


It's been a few years since I've looked at FunctionalProgramming but it's very unlike ObjectOrientedProgramming. Functional means no SideEffects so that a function's behaviour is entirely determined by its arguments. The grand benefit is that if you test a function once then it will always work. The downside is that the entire state of the program must be passed on the stack to every function [Wrong. Much of the program state is on, or accessible via, the stack, but not passed to every function.]. FunctionalProgrammingLanguages (HaskellLanguage?) hide this from the programmer somewhat.

Well, you can pass the entire state, but then you are not really taking advantage of functional programming, because then the result of the function still depends on the complete state. Rather, you want the result of a function to depend only on a small set of explicit input parameters. Moreover, I think that limiting SideEffects is a good idea in any programming language - side effects are a very good rope to hang yourself with. The problem is that when you take a look at a language like HaskellLanguage, that does non-strict evaluation, then if you have side effects (which you can have in most implementations, if you really feel like it), you will soon find out that the hang-yourself-with capacities of side-effects are greatly amplified.


It depends on how you characterize OO. One useful definition is:

In other words, identity and mutable state don't get a look in. This fits conventional OO languages like SmalltalkLanguage, but can also fit functional (and logical) languages too. I would argue that it captures the essence of OO, as compared with previous paradigms, better than stateful definitions. -- DaveHarris

[Actually it fits everything but stone age Pascal, C, Fortran, Cobol and Algol. This definition is about as useful as "There are only OO languages and macro assemblers." I take this as more evidence that OO is no paradigm but merely a set of conventions.]

The original definition of OO as far as I can remember it contained three elements:

That's it, no more and no less. -- PhilGoodwin

"Encapsulation" is a misunderstood word; some people say it implies information hiding and some it doesn't. Personally I like to keep the notions separate, but Encapsulation + Information Hiding = Abstract Data Types. So I doubt we disagree fundamentally here.

"Inheritance" excludes delegation; I think this just expresses ignorance of how cool delegation is (reasonable in an old definition, but there's no need to perpetuate it). They are very tightly related, especially if you have direct language support (which most common languages don't).

"Polymorphism" - no argument.

Automated memory management is something I throw in to wind up the CeePlusPlus crowd. (I'm sure I got it from an article in the early ByteMagazine special edition, which will have predated C++.) So really we're pretty close.

I need object identity as a core concept. I need to have inheritance and polymorphism to construct frameworks. They can be mimicked with some sort of delegation, that's all right with me. But these three things I feel I must have. I haven't seen them yet in a FunctionalProgrammingLanguage, and have doubts it can be done. -- AlistairCockburn

I agree. My take on much of FP is that it is a way of eliminating identity. Face it, identity only matters when something changes. If a thing can't change then any other one that looks the same will do. I'm skeptical of FP for large-scale systems. I wonder about maintainability. OTOH, I find myself programming in a more ValueOrientedProgramming? style recently. -- MichaelFeathers

I actually like delegation much more than implementation inheritance and wish that there was a popular non-interpreted language that supported it. You got me on GarbageCollection. I think that the ideal system would have garbage collection be optional. I think that you can do that if the references are more than just pointers, but that's a different discussion.

And, since you guys brought up identity and functional programming in the same breath: have you looked at the stuff I've been writing about ObjectFunctionalPatterns? I suspect that object identity is a basic assumption of OO - not part of its definition, but only because nobody thought to question the assumption at all. Now that it's been questioned I think that it's undeniably part of OO. Of course with identity comes mutable state and with mutability comes the concept of time and ordering - all undoubtedly important to OO whether they are part of its definition or not. -- PhilGoodwin.


Everyone, take a look at O'Haskell. An object-oriented functional language based on HaskellLanguage. Having seen mostly examples with imperative-style programming so far, which perhaps may not seem too worthwhile, I am not yet ready to pass judgment on this.

In any case, taking over some things from the FunctionalProgramming world is cool regardless:

Most ObjectOrientedLanguages associate polymorphism with subtyping. Most FP languages make use of ParametricPolymorphism. (Sure, there are templates in CeePlusPlus for this but it is not really the same.)

In an OO-FP language you (should) get both. This particular language also has some other basic foundations, such as built in concurrency. (All objects are active objects - running their own thread).

-- GunnarAndersson

Link: http://www.cs.chalmers.se/~nordland/ohaskell/


My take: FunctionalProgramming is about minimizing state, and ObjectOrientation is about managing it. You don't want to do stateful objects in a SideEffect-free language, but you can gain the AdvantagesOfFunctionalProgramming in any language.

Some languages make it easier than others, of course. For example, iterators always struck me as a needless multiplication of entities; I'd rather be mapping a function over the collection.


How do you characterize OO? AFAICT, the characteristics all OO languages have in common are object identity, and InclusionalPolymorphism?.

OO (Inclusional) Polymorphism

Most OO programmers probably think of polymorphism in the ObjectOriented sense, which is substituting a sub-type where a given type is expected. This is inclusional polymorphism (see also LiskovSubstitutionPrinciple, this is something similar, if not the same thing). However, there are a number of types of polymorphism:

So-called "inclusional" polymorphism is merely a degenerate form of MultipleDispatch that only allows polymorphism on the first parameter to a function. OperatorOverloading is the same as defining a method that takes the same number of arguments as the operator, so is also the same as multiple dispatch.

The two above items both show that polymorphism is merely a way of defining types, and how functions apply to those types, so in fact we have only one kind of polymorphism.

For example, JavaLanguage supports only inclusional polymorphism (through class inheritance and/or interfaces). CeePlusPlus supports inclusional (single and multiple inheritance), parametric (templates), and AdHocPolymorphism. The interesting thing with C++ is the use of MultipleInheritance to allow a given type to be a sub-type of many (possibly unrelated) types. Java uses interfaces, and Ruby uses MixIns to the same end.

OO Feature Check

Some (for example, see Booch's ObjectOrientedAnalysisAndDesign) will claim that an ComponentOrientedLanguage should have some or all of:

(How is delegation a separate characteristic? Someone help me here because currently I simply see delegation as an consequence of inclusional polymorphism.)

Inheritance is a RedHerring.

You only need it in languages such as CeePlusPlus and EiffelLanguage because it is the only way to achieve sub-typing. EmeraldLanguage? (http://www.cs.ubc.ca/nest/dsg/emerald.html [BrokenLink 2005-08-31]- alt, see http://www.cs.ubc.ca/~norm/emerald.html (2007-01-23)) is an example of an ObjectOrientedLanguage which does not have any form of inheritance, yet I consider it to be OO because it supports inclusional polymorphism (and object identity). Emerald uses contra-variance to achieve sub-typing; see ContraVsCoVariance.

I've read claims that behavioural reuse (as opposed to interface reuse) through inheritance is just as important. However, you can achieve behavioural reuse through composition, so you really gain nothing. Composition also reduces dependency, which is a GoodThing (composition is advocated by the GangOfFour book).

Many languages support encapsulation, modularity, and abstract datatypes, yet they do not claim to be OO. Examples: MlLanguage, ModulaTwo, (old, pre-OO) AdaLanguage, Oracle's PlSql (The version bundled with the 7.3 RDBMS. Later versions of Oracle (8) have added objects/classes etc. AFAIK PL/SQL was inspired by Ada.) So I would say that these are not defining characteristics of OO languages, though clearly desirable (and apparently ubiquitous - can you name an OO language which does not support these concepts?).

FunctionalProgramming Feature Check

Some modern FunctionalProgrammingLanguages also support these concepts, and also inclusional polymorphism. HaskellLanguage looks like it supports inclusional polymorphism through type classes, but it doesn't (not yet, anyway. Type classes are exactly that: classes of types, i.e., they are not types. You could best think of them as constraints on types.) Haskell is also not OO because it has no notion of object identity.

FP deals purely with data. You can think of a purely functional program as creating, copying, and passing around many immutable objects. (Because objects are immutable, everything can be passed by reference [PassByReference]. All storage is allocated on the heap, so the stack is only used for passing pointers to heap objects.)

FP languages also differ significantly in that they treat functions (and LexicalClosures?) as FirstClass objects, so they can be passed to other functions like objects/data. FP is typified by HigherOrderFunctions: functions that take functions as arguments and return functions. This can be achieved in OO languages (see BlocksInJava) but it's somewhat cumbersome, and there is no static type checking (anyway, weren't these ideas were inspired-by/borrowed-from FP languages? - see FunctionalPatternSystemForObjectOrientedDesign). I am aware that SmalltalkLanguage supports lexical closures, but again no static type checking.

HaskellLanguage can support the missing OO concepts (object identity and state) through Monads. Most (all) aspects of SideEffect-based programming can be modelled with Monads, while still retaining ReferentialTransparency, which is one of the claimed AdvantagesOfFunctionalProgramming. (See OnMonads.)

Monads are not the only abstraction in functional programming, and they are not the most useful one. I wish this misconception would stop being parroted.

Summary:

I wrote this a while ago and it looks like a pile of poo now. But I suppose it is a milestone for my understanding of type systems at the time. A little knowledge is a dangerous thing... http://www.apa.org/journals/psp/psp7761121.html. (BrokenLink 2005-08-31)

OnUnderstandingTypes, Data Abstraction, and Polymorphism (1985). LucaCardelli, PeterWegner. ACM Computing Surveys. http://citeseer.nj.nec.com/cardelli85understanding.html (BrokenLink 2005-08-31)

-- AlistairBayley


See ObjectiveCaml for a FunctionalProgrammingLanguage with OO bolted on. Ocaml has also a very sophisticated type system where subtyping is not inheritance-based.


At the limits:

-- AndrewKoenig


This page has an "article mode" version in the June 2005 issue of The Monad.Reader - http://www.haskell.org/tmrwiki/FpVsOo, thanks to AlistairBayley. -- ShaeErisson


Over the broad middle ground, we choose when to treat something as program and when to treat it as data: NiceLanguage, ScalaLanguage.



CategoryObjectFunctionalPatterns ParadigmPissingMatch


EditText of this page (last edited February 22, 2011) or FindPage with title or text search