From: tmb@arolla.idiap.ch (Thomas M. Breuel)
Newsgroups: comp.object
Subject: Re: Passing functions as parameters in an OO environment
Date: 28 Sep 92 19:54:04 GMT
	<1992Sep23.104513.22660@ruby.comlab.ox.ac.uk>
	<1992Sep25.150611.24570@actrix.gen.nz>
Reply-To: tmb@idiap.ch
Organization: IDIAP (Institut Dalle Molle d'Intelligence Artificielle
	Perceptive)
In-reply-to: Des.Kenny@bbs.actrix.gen.nz's message of 25 Sep 92 15:06:11 GMT

In article <1992Sep25.150611.24570@actrix.gen.nz> Des.Kenny@bbs.actrix.gen.nz writes:

   Since you seem to be in a mathematical environment I suggest that 
   you think of objects in terms of Algebra, Analysis, Topology etc. For 
   example Real numbers are a Field. Without the relevant operators  
   the definition of a Field is incomplete and useless. Similarly the 
   Real operators are specifically defined in the context of the 
   definition of the Field set of values , the set of Real numbers. In 
   addition it is not optional to include the associated definitions, 
   axioms and theorems of Real number Algebra it is mandatory!
   [...]
   My point is you need to define your own Abstract Data Types for your 
   special area. Then you will be plugged into reality ( at least your 
   own reality ).

Yes, but OOP is not the only way to program in terms of ADT's. OOP is
one particular approach to programming in terms of ADT's, with its own
strengths and limitations.

What limitations, you will ask. Well, one of them is that it is
difficult to represent a collection of related datatypes and
operations on them simultaneously. For example, a definition of a
"graph" may involve related "vertex" and "edge" types, and operations
with the graph may have to operate on both "vertex" and "edge".
However, in an OO setting, it is difficult to express the fact that
only a "vertex" and an "edge" type that have been defined together can
be used together. Another limitation is that the only form of deriving
one structure from another is inheritance, which allows you to add
members but not remove them; a lot of mathematical relationships are
more conveniently expressed by starting out with some complicated
mathematical object and "forgetting" some of its structure.

   The misguided evolution of the 'functional' movement, 'functional 
   decomposition', 'structured analysis' etc is , in my opinion, almost 
   entirely due to ignorance of the most basic concepts of 
   mathematics. e.g. the nonsense of the idea of a 'function' existing 
   independently of its domain, range , taxonomic context, axioms, 
   theorems etc.

I think the designers of the SML module system, which essentially is a
computational embodiment of category theory, would be surprised to
hear that (SML is a mostly-functional programming language and has no
OO features).

In particular, the SML module system is based on the notion of
"structures" (usually called "modules" in other languages), which
contain type definitions and definitions of operations on those types,
"signatures", which specify the interfaces to structures, and
"functors", which allow you to derive one structure from another.

"structures" are somewhat analogous to "classes", except that they can
describe a group of related data types and operations, not just a
single datatype and operations on it. "signatures" are somewhat
analogous to abstract base classes. "functors" are somewhat analogous
to inheritance, except that functors can perform much more general
operations.

   The so called 'functional' concepts have led software people into a 
   kind of mathematical cloud cuckoo land. [...]
   OO gives us the opportunity to get back to the real 
   mathematical sense of what a function is and has been for several 
   hundred years.

"Functional programming" refers to eliminating side effects from
programming; beyond that, it has nothing to do with how you organize
your functions, or whether you program in terms of ADT's. Eliminating`
side effects is, in fact, vitally important if you want to bring
programming closer to mathematics and make it more amenable to formal
analysis, since for any mathematical function, f(x) = f(y) when x = y.
Such identities are obviously not guaranteed to be satisfied if "f" is
a "function" or method in an imperative languages like C or Smalltalk.

Functional programming languages also usually (though not always) let
you treat functions/closures as first-class objects, meaning that you
can create them and pass them around. This substitutes for the dynamic
aspects of inheritance in languages such as Smalltalk and C++ (virtual
functions). In fact, in many ways, it is a more flexible approach,
letting you use method dispatch from well-defined interfaces when you
want to, but also giving you the freedom of creating "unnamed" classes
and interfaces on the fly.

The point of all this is not to malign the object-oriented paradigm,
but simply to point out that there are alternative approaches to
programming in terms of abstract data types that are more powerful in
some respects. "Looking over the fence" may benefit both the
object-oriented community and the functional programming community.

If you are specifically interested in computational analogs of
mathematical categories, I suspect the SML module system would
actually serve you better. One book you may want to look at is
Rydeheard and Burstall: "Computational Category Theory". For an
introduction to what functional programming actually means, Reade's
book "Elements of Functional Programming" is probably a nice choice.

					Thomas.

PS: To give you a taste of what you can express with the SML module
system, consider the following descriptions of some basic mathematical
objects.

For fun, try to work out how you would represent these in your
favorite OO language. Note that in SML, all these definitions can be
type-checked statically, and, unlike C++ templates, they can be type
checked at the time of definition.

Note that "f: X -> Y" means that "f" is a function mapping values of
type "X" to values of type "Y".

If you want to see more concrete applications of the SML module
system, you may want to take a look at Paulson: "ML for the Working
Programmer": the SML module system is actually useful for writing
real programs.

signature ENUMERABLE_SET =
   sig
       type element
       type set
       val member : element * set -> bool
       val enumerate : element * set -> element stream
   end;


signature GROUP =
   sig
       type element
       val identity : element
       val multiply : element * element -> element
       val inverse : element -> element
   end;


functor FreeGroup(structure EnumerableSet: ENUMERABLE_SET): GROUP =

   (* given an enumerable set, make the corresponding free group *)

   ... definition deleted ...


signature FIELD =
   sig
       type element
       val add : element * element -> element
       val multiply : element * element -> element
       val zero : element
       val one : element
       val additive_inverse : element -> element
       exception DivisionByZero
       val multiplicative_inverse : element -> element
   end;


functor MakeField(structure AdditiveGroup: GROUP
                  and MultiplicativeGroup: GROUP
		  sharing type AdditiveGroup.element =
		               MultiplicativeGroup.element): FIELD =

   (* given an additive GROUP and a multiplicative GROUP over the
      same set, make a FIELD out of them *)

   ... definition deleted ...


functor AdditiveGroupOfField(structure F: FIELD): GROUP =

   (* extract the additive GROUP from a FIELD *)

   struct
       type element = F.element
       val identity = F.zero
       val multiply = F.add
       val inverse = F.additive_inverse
   end;


functor FieldConveniences(structure F: FIELD) =

   (* takes a FIELD consisting of the defining operations and
      adds all those conveniences we usually take for granted *)

   struct
       val op+ = F.add
       val op* = F.multiply

       fun op-(x,y) = F.add(x,F.additive_inverse(y)
       fun op/(x,y) = F.multiply(x,F.multiplicative_inverse(y))

       fun integer_power(x,n: int) = ...

       ... more useful definitions deleted ...

       (* make the basic FIELD operations available as well *)

       open F 
   end;
Newsgroups: comp.object,comp.lang.smalltalk,comp.lang.eiffel