FP/OO 
Author Message
 FP/OO

I would like to add my personal slant on the debate re. OO versus FP. I
apologise in advance if I am repeating anything already discussed in the
thread which I may have missed.

It seems to me that one is unable to achieve the unambiguity of
specifications such as the following written in Haskell:

        someFun :: Type1 -> Type2 -> Type1

Here it is quite clear that the function `someFun' takes a `Type1' value and
a `Type2' value and returns a new `Type1' value. In the OO world (using Java
notation) the following declaration is less clear:

--- some class stuff

        public Type1Class someFun(Type1Class x, Type2Class y)
        {
                some more stuff
        }

The inputted values to `someFun' could either be (references to) objects of
the declared classes, or objects of their subtypes. In addition, is the
returned value a new object or an updated version of an existing object. One
would have to look at the function definition to answer this question. If one
wanted to be clear as to the class of the inputted object, one could declare
the class to be non-extendible, but this is a design decision made when the
class is declared, not at the behest of the function.

If however one wants a (constrained) polymorphic function then in Haskell
one could specify a function as follows:

        someFun2 :: (Class1 a, Class2 b) => a -> b -> a

`someFun2' requires two arguments whose values are of types which
instantiate interfaces specified by the classes `Class1' and `Class2'.

The common approach in the OO world is to use the inheritance hierarchy to
supply subtypes, from which acceptable objects may be provided. The problem
with this approach is that the interfaces required of the arguments are hidden
somewhere within the class declarations. In addition, one is constrained to
use objects which instantiate classes within a hierarchy, which on the one
hand supports reuse (both behaviourial and implementation) and restricts
reuse, by disallowing other objects which exhibit the necessary behaviour.    

Using Java Interfaces resolves this problem, although they still have to be
declared when the class is declared.

All functional languages support functions as first class objects, allowing
functions as input and output. One can mimic this in OO languages via
function objects which can be declared through overloading the parenthesis
operator (C++), through wrapping a function up in a class (Java) or using
Smalltalk's blocks.

However one cannot naturally mimic the reusability of functions such as
Haskell's map:

        map :: Functor c => (a -> b) -> c a -> c b

where any function can be supplied as long as it is of the correct type.
In C++ one could achieve this through templates but not without a degree of
preparatory work -- creating the template, and any required functions as
function objects. Also, do the object-oriented community regard templates as
Object-Oriented or do they more closely resemble the functional approach ?

In addition, can one always support anonymous functions and closures in the OO
world ?

A desire for encapsulation has resulted in the coupling of data,
functionality and interface in an object. If one wants to provide the same
data with the same functionality but a different interface this will require
the declaration of a new class either through extending the original class or
declaring a class anew (dependant on how the interfaces differ).  
The FP world allows the developer to decouple data, functionality and
interface. For example, SML supports coupling data and functionality in a
structure (which has an implicit signature if not declared explicitly), with
the interface supplied by an explicitly declared signature. Similarly Haskell's
module system allows a similar decoupling. Of course one can also decouple
data from functionality. Adding functionality to data is also less of a
headache when they are decoupled.

Of course in the functional world there is another level of decoupling --
values are decoupled from their state.

My final point is not about programming but about design. The OO world
prides itself in not only having an effective and efficient programming
paradigm, but also an effective and efficient design paradigm. The two are
sold either as a package (non-Java of course) i.e. analyze and design in an OO
way using an OO methodology (Booch, OMT, Objectory, UML (not really a
methodology)), and then implement in an OO language, or analyze and design in
an OO way and then implement in a language of your choice. The FP community is
not backward in coming forward about the benefits of programming in an FP
language. What about the benefits of an FP package (design and
implementation), or using an FP Design approach when the implementation
language is non-FP ?

For example, in FP design one would focus on (de-coupled) functionality,
data, and interface, and develop the abstract type as required. Free from
the bonds of inheritance hierarchies, one can design reusable structures,
whose reusability contract is explicit.  



Fri, 20 Jul 2001 03:00:00 GMT  
 FP/OO

 >I would like to add my personal slant on the debate re. OO versus FP. I
 >apologise in advance if I am repeating anything already discussed in the
 >thread which I may have missed.
 >
 >It seems to me that one is unable to achieve the unambiguity of
 >specifications such as the following written in Haskell:
 >
 >        someFun :: Type1 -> Type2 -> Type1
 >
 >Here it is quite clear that the function `someFun' takes a `Type1' value and
 >a `Type2' value and returns a new `Type1' value. In the OO world (using Java
 >notation) the following declaration is less clear:
 >
 >--- some class stuff
 >
 >        public Type1Class someFun(Type1Class x, Type2Class y)
 >        {
 >                some more stuff
 >        }
 >
 >The inputted values to `someFun' could either be (references to) objects of
 >the declared classes, or objects of their subtypes.

Well, the "OO world" is rather diverse, and not all languages in it
suffer from that problem.  For example, Ada 95 distinguishes between
these two possibilities:

        -- arguments and return value must have the exact type specified
        function someFun(arg1: Type1, arg2: Type2) return Type2;

        -- arguments and return value may have the type specified or
        -- any type derived from that type
        function someOtherFun(arg1: Type1'class, arg2: Type2'class)
                return Type2'class;

--

WWW: <http://www.cs.mu.oz.au/~fjh>  |   but source code lives forever"



Sat, 21 Jul 2001 03:00:00 GMT  
 FP/OO
Quote:


>  >I would like to add my personal slant on the debate re. OO versus FP. I
>  >apologise in advance if I am repeating anything already discussed in the
>  >thread which I may have missed.

>  >It seems to me that one is unable to achieve the unambiguity of
>  >specifications such as the following written in Haskell:

>  >        someFun :: Type1 -> Type2 -> Type1

>  >Here it is quite clear that the function `someFun' takes a `Type1' value and
>  >a `Type2' value and returns a new `Type1' value. In the OO world (using Java
>  >notation) the following declaration is less clear:

>  >--- some class stuff

>  >        public Type1Class someFun(Type1Class x, Type2Class y)
>  >        {
>  >                some more stuff
>  >        }

Eiffel

someFun (x: Type1Class; y: Type2Class): Type1Class

why should that be more difficult to understand?

Regards
Friedrich



Sat, 21 Jul 2001 03:00:00 GMT  
 FP/OO

Quote:

> My final point is not about programming but about design. The OO
> world prides itself in not only having an effective and efficient
> programming paradigm, but also an effective and efficient design
> paradigm.

Hmm - yes.  It is sometimes easier to think in terms of objects that
behave in certain ways.  I find FP (which I'm really an amateur in) to
be somewhat like the top-down structured programming paradigm of olde
(anybody remember that?):

You start with expressing your solution, and gradually refine it by
..uh.. elaborating further on it.  Anything to complex, you just name,
and postpone the exact definition.

Anybody else get the same eerie feeling of deja vu?

Quote:
> What about the benefits of an FP package (design and
> implementation), or using an FP Design approach when the
> implementation language is non-FP ?

Possibly, we need a book called 'Functional Design Patterns', or some
such.  I must say I found the OO design patterns very helpful, and FP
is, until you get the hang of it, a rather strange way of thinking.

~kzm
--
If I haven't seen further, it is by standing in the footprints of giants



Sat, 21 Jul 2001 03:00:00 GMT  
 FP/OO


: > My final point is not about programming but about design. The OO
: > world prides itself in not only having an effective and efficient
: > programming paradigm, but also an effective and efficient design
: > paradigm.

: Hmm - yes.  It is sometimes easier to think in terms of objects that
: behave in certain ways.  I find FP (which I'm really an amateur in) to
: be somewhat like the top-down structured programming paradigm of olde
: (anybody remember that?):

: You start with expressing your solution, and gradually refine it by
: ..uh.. elaborating further on it.  Anything to complex, you just name,
: and postpone the exact definition.

: Anybody else get the same eerie feeling of deja vu?

: > What about the benefits of an FP package (design and
: > implementation), or using an FP Design approach when the
: > implementation language is non-FP ?

: Possibly, we need a book called 'Functional Design Patterns', or some
: such.  I must say I found the OO design patterns very helpful, and FP
: is, until you get the hang of it, a rather strange way of thinking.

IMO FP and OO style design stand respectively for a simplification of
top-down and bottom-up design. The OO style helps you avoiding inventing the
wheel every time: you start with basic objects which can do simple things
and build upon them (inheritance). The implementation of the basic operations
rarely change. In the same manner one can say that FP style helps you
avoiding inventing rolling every time. However the algorithm of rolling is
implemented differently for each type of wheel (including new versions).
So in FP the upper part of the design is allready given while in OO the
bottom part is given.
FP: a rather strange way of thinking? I think not. I find it easier to
implement OO in a FP language than FP in an OO language. FP has the
advantage of easy abstraction. One says to the computer how the abstract
types relate and let the computer fix the implementation for the actual
data (I know: oversimplification).
It is however correct that you need to get the hang of it. But that is IMO
the consequence of education. One builds up the ideas from simple things to
complex things (as it should) but then forgets to mention that it can be
done in reverse: from simple abstract things (which are very complex to
understand, high IQ necessary) to complex abstract things (which are very
simple to understand: e.g. a car is a collection of a colection of engine
design, a collection of driving methods, a collection of selections of
colors, etc). The problem is that most educators don't understand that this
reversion can be done on any level of abstraction or complexification.

Frank Meisschaert



Sat, 21 Jul 2001 03:00:00 GMT  
 FP/OO

 >I would like to add my personal slant on the debate re. OO versus FP. I
 >apologise in advance if I am repeating anything already discussed in the
 >thread which I may have missed.
 >
 >It seems to me that one is unable to achieve the unambiguity of
 >specifications such as the following written in Haskell:
 >
 >        someFun :: Type1 -> Type2 -> Type1
 >
 >Here it is quite clear that the function `someFun' takes a `Type1' value and
 >a `Type2' value and returns a new `Type1' value. In the OO world (using Java
 >notation) the following declaration is less clear:
 >
 >--- some class stuff
 >
 >        public Type1Class someFun(Type1Class x, Type2Class y)
 >        {
 >                some more stuff
 >        }
 >
 >The inputted values to `someFun' could either be (references to) objects of
 >the declared classes, or objects of their subtypes. In addition, is the
 >returned value a new object or an updated version of an existing object. One
 >would have to look at the function definition to answer this question. If one
 >wanted to be clear as to the class of the inputted object, one could declare
 >the class to be non-extendible, but this is a design decision made when the
 >class is declared, not at the behest of the function.

The last part of your last sentence is not true at all.  A Haskell
typeclass corresponds to an abstract base class (ABC) or Java
interface.  A Haskell data type corresponds to a "final" concrete class
(one that can't be derived from).  Just as you can choose whether a
Haskell function's parameter should have a typeclass-constrained
polymorphic type or a concrete type, in OOPLs such as Java and Eiffel
you can likewise choose whether a parameter's class is an abstract base
class or a "final" concrete class derived from that ABC.  The mere act
of declaring the "final" concrete class as "final" does not prevent
code from using the ABC for parameter types.

The fact that some OOPLs use a single notion (classes) to represent
what Haskell considers as two different notions (types and type classes)
does not mean that you have to use a single class to represent both a
type and a type class at the same type.  If you want the unambiguity
of Haskell declarations, then you just need to separate the interface
and implementation aspects into two different OOP classes.

--

WWW: <http://www.cs.mu.oz.au/~fjh>  |   but source code lives forever"



Sat, 21 Jul 2001 03:00:00 GMT  
 FP/OO

Quote:


>>  >I would like to add my personal slant on the debate re. OO versus FP. I
>>  >apologise in advance if I am repeating anything already discussed in the
>>  >thread which I may have missed.

>>  >It seems to me that one is unable to achieve the unambiguity of
>>  >specifications such as the following written in Haskell:

>>  >        someFun :: Type1 -> Type2 -> Type1

>>  >Here it is quite clear that the function `someFun' takes a `Type1' value
>>  >and a `Type2' value and returns a new `Type1' value. In the OO world
>>  >(using Java notation) the following declaration is less clear:

>>  >        public Type1Class someFun(Type1Class x, Type2Class y)

>Eiffel

>someFun (x: Type1Class; y: Type2Class): Type1Class

>why should that be more difficult to understand?

I suspect Daniel Russell may have been thinking of a more direct
semantics-preserving transliteration into Eiffel, e.g. something
like this (Daniel, please excuse me if this conjecture is not correct):

        someFun(x: Type1Class; y: Type2Class): Type1Class is
        require
            -- x must be of type Type1Class, not a class derived from that
            -- y must be of type Type1Class, not a class derived from that
        ensure
            -- the return value will must be of type Type1Class,
            -- not a class derived from that

Notice that the contract for this routine includes a bunch of constraints
which Eiffel won't check statically.  In fact I didn't know off-hand how
to even check those constraints at runtime, so I just used comments.
(As far as I know, it may well be possible to check them at runtime --
I just don't know much about Eiffel's library features for RTTI.)

But I think your general point is right -- this kind of transliteration
is the old apples-vs-oranges comparison where we try to use our Haskell
idioms directly in Eiffel rather than using Eiffel idioms.  A more
high-level translation which translates Haskell idioms into Eiffel idioms
(see my other post in this thread for details) would give a fairer
comparison than you'd get from the above low-level transliteration.
If you do that, then Eiffel will come out looking a lot better.

--

WWW: <http://www.cs.mu.oz.au/~fjh>  |   but source code lives forever"



Sat, 21 Jul 2001 03:00:00 GMT  
 FP/OO
Quote:

> >someFun (x: Type1Class; y: Type2Class): Type1Class

> >why should that be more difficult to understand?

> I suspect Daniel Russell may have been thinking of a more direct
> semantics-preserving transliteration into Eiffel, e.g. something
> like this (Daniel, please excuse me if this conjecture is not correct):

>         someFun(x: Type1Class; y: Type2Class): Type1Class is
>         require
>             -- x must be of type Type1Class, not a class derived from that
>             -- y must be of type Type1Class, not a class derived from that
>         ensure
>             -- the return value will must be of type Type1Class,
>             -- not a class derived from that

You can figure this out and write it in the assertion clauses but that
isn't good Eiffel-programming. There is an Interface to the Internals of
an object, but I don't know at this moment the concret class
Regards
Friedrich


Sat, 21 Jul 2001 03:00:00 GMT  
 FP/OO

:  >The inputted values to `someFun' could either be (references to) objects
:  >of the declared classes, or objects of their subtypes. In addition, is
:  >the returned value a new object or an updated version of an existing
:  >object. One would have to look at the function definition to answer this
:  >question.
:  >If one wanted to be clear as to the class of the inputted object, one
:  >could declare the class to be non-extendible, but this is a design
:  >decision made when the class is declared, not at the behest of the
:  >function.

: The last part of your last sentence is not true at all.  A Haskell
: typeclass corresponds to an abstract base class (ABC) or Java
: interface.  A Haskell data type corresponds to a "final" concrete class
: (one that can't be derived from).  Just as you can choose whether a
: Haskell function's parameter should have a typeclass-constrained
: polymorphic type or a concrete type, in OOPLs such as Java and Eiffel
: you can likewise choose whether a parameter's class is an abstract base
: class or a "final" concrete class derived from that ABC.  The mere act
: of declaring the "final" concrete class as "final" does not prevent
: code from using the ABC for parameter types.

: The fact that some OOPLs use a single notion (classes) to represent
: what Haskell considers as two different notions (types and type classes)
: does not mean that you have to use a single class to represent both a
: type and a type class at the same type.  If you want the unambiguity
: of Haskell declarations, then you just need to separate the interface
: and implementation aspects into two different OOP classes.

Agreed. But because inheritance has multiple semantics
(interface reuse, code reuse, specialization, generalization etc.) it seems
to me that one is always going to encounter design difficulties.

For example, let class ABC1 be an abstract (interface) class, ABC2 be another
abstact (interface) class which extends ABC1, and CC1 and CC2 implement ABC1
and ABC2 via inheritance. Then we have separated interface and
implementation, and created two final classes. However, if CC2 simply
generalizes CC1, then it would be sensible to create CC2 through inheritance
of CC1.

CC1 is then no longer a final class, and although one can resolve this in
Ada 95, it's not clear to me how one resolves this in other OO languages.

Dan Russell
Kingston University



Wed, 25 Jul 2001 03:00:00 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. OO and FP (was subtyping in FP)

2. FP, OO and relations. Does anyone trump the others?

3. FP, OO and relations. Does anyone trump the others?

4. FP, OO and relations. Does anyone trump the others?

5. FP as enhancement of OO

6. FP's and OO and generic programming

7. OO and FP - mutually exclusive?

8. OO and FP - mutually exclusive?

9. More than two FP-TB-3 with FP-TC-120

10. FP Component Libraries? (FP vs OOP)

11. FP to FP Binary/Hex

12. OO and FP [Fwd: comparison OOP and FP (and how to put them together) was: Re: need help with haskell]

 

 
Powered by phpBB® Forum Software