[Haskell] Dynamic binding

Ralf Lammel ralfla at microsoft.com
Fri Jun 24 07:07:34 EDT 2005


> If we were on an OOP mailing
> list, I could ask for days how to simulate pattern matching and
> algebraic types---and get a nonsensical runaround involving the
visitor
> pattern and huge swaths of unreadable code.

In such a case, I would be happy if someone told me that there is work
like this: http://www.cs.cornell.edu/Projects/jmatch/ 
People who wrote those papers clearly have thought harder of the
problem than most subscribers to the preconceived OOP mailing list.

> Ralf, I think it's incumbent on you, having said several times "that
> isn't solving the problem", to more clearly explain what problem you
> think exists and cannot be solved gracefully 

I am sure I said it.

Also, Oleg and I should be fairly clear on all this in the OOHaskell
paper.

http://www.cwi.nl/~ralf/OOHaskell Major revision 13 June 2005

We will be grateful for additional comments and questions,
and I am happy to summarize all feedback we get,
if not on this mailing list, then in the paper's appendices,
and elsewhere.

Anyway, as it is incumbent on me to explain,
I try to be as concise as I can get at 4.00am:

[This should also cover Andreas' question.]

1. The original poster asked:

> What would be the normal way for a Haskell programmer
> to handle the typical shape example in beginner OO
> tutorials?

2. 

I take for granted that "typical shape example" is very
well abstracted in this famous benchmark:

http://onestepback.org/articles/poly/ 
http://www.angelfire.com/tx4/cus/shapes/

The essence of the typical shape example is the following:

a there are different kinds of shapes (say rectangle, circle, whatever),
b which are organized in a subtyping hierarchy, and
c each kind of shape supports a subclass-specific draw method;
d the interface of shapes allows for mutation/observation of state,
e and eventually we want to process collections of shapes

3.

Note that e) looks arbitrary at first sight,
but it is crucial because shape apps will
involve instances of the Composite pattern.

Also note that the original poster indeed said:

std::list<shape *> shapes;
for(std::list<shape *>::iterator it = shapes.begin();it !=
shapes.end();++it)
{ (*it)->draw(...); }

Also note that the
body of the for loop happens to be a single
statement that invokes draw, but obviously we must keep in mind
what happens if the body is a compound statement.

4. 

Where did I say "that isn't solving the problem"?

((

For the record,
I did *not* say so when Lennart posted his proposal.
I only mentioned that this proposal has the extensibility
problem and that ("minor issue") it needs extra effort to
recover the same degree of type distinction as in the normal
OO approach.

))

Indeed,
I did strongly disagree regarding the faithfulness of Bulat's
attempts. He made two proposals. The first one basically
suggested:

- do not build a list of shapes,
- do rather build a list of (lazy) applications of draw methods to shape
construction arguments
- then do not map over a list of shapes to perform functionality per
element
- do rather map over a list of expressions to sequence their effects.

If you think of it,
we can get rid of the generality of Haskell's map this way,
which is something that others have thought of:

http://lambda-the-ultimate.org/node/view/613


The second proposal by Bulat goes as follows:
(again I save band with by not showing the actual code)

- define a single *non-parameterized* datatype ShapeInterface
- construct all sorts of shapes as terms over this monomorphic type
- allow for state by IOref allocation before returning the shape terms
- do *not* cover the problem of shapes with different interfaces
- that is do really just pretend that all shapes have the same type
- do therefore simplify away the issue of different types for different
kinds of shapes
- based on this simplification, build a homogeneous list of shapes
- and do a reasonable loop with type-specific draw method invocations
indeed.

Again, if you think of it, we can adopt the same simplification
strategy to Haskell. That is, in Haskell 20??, superclass constraints
will not be allowed. We will recommend to define a single class in
the recompilable Prelude to which we add methods as we encounter them.

Ralf

P.S.: I just realized that there is no OOCobol solution in the shapes
repository. I sign for it.



More information about the Haskell mailing list