John Meacham wrote:
On Tue, Aug 01, 2006 at 02:56:21AM +0100, Brian Hulley wrote:
Now the problem is that person C may come along and notice that
there is a useful abstraction to be made by inheriting both from
ClassA and ClassB. But both of these define "foo" and there is no
mechanism in the language to resolve this.
This is not true at all. every name in haskell can be uniquely
specified.
module ClassA where
class ClassA a where
foo :: a -> Int
module ClassB where
class classB a where
foo :: a -> String
import ClassA
import ClassB
class (ClassA a, ClassB a) => ClassC a where
bar :: a -> (Int, String)
bar x = (ClassA.foo x, ClassB.foo x)
Hi John -
Thanks for pointing this out. The only thing that I find slightly uneasy
about it is that you have to keep the module names and class names in sync
so that "ClassA.foo" which means "the value foo exposed by the module
ClassA" is in truth the same as "the foo method of class ClassA". The
language doesn't enforce this correspondence (indeed perhaps such a
correspondence would be undesirable but it's difficult to get used to this
need to keep different entities in sync instead of just being able to name
the concept once in one place).
I'm also wondering if it would be a good idea to be able to declare
some class methods as final, so they don't clutter up the dictionary
at runtime, and so that we could end the dubious practice of
declaring some functions which are conceptually part of a class as
top level functions outside the class just to save space/time in the
dictionary and therefore needing the physical module to create the
conceptual grouping instead of using the language level grouping
provided by the class name.
I think a fundamental thing you are missing is that Haskell classes
are not like C# or Java or other OO classes. Not because of
implementation, but rather they are actually fundamentally different
things.
The reasons people don't place certain functions in classes has
nothing to do with the size of class dicionaries. Heck, jhc doesn't
even use dictionaries at all, there is no cost for adding methods to
a class. People place them in top level functions because it makes
more sense. of course, sometimes it is gotten wrong, and something
would have been better off as a class method, but in general there
are different concerns when dealing with haskell classes than OO
classes.
An OO class could be considered equivalent to a triplet of a Haskell
data type, a Haskell existential with a class constraint, and a class
with the resriction the class type can _only_ appear as the first
argument to each method. In haskell all of these things are separate
independent tools and are much more general and powerful than the
limited and conjoined form that OO programming provides.
I think the transition from OOP to Haskell is difficult because although OOP
is less powerful for the reasons you've mentioned, many of the decisions you
have to make when writing Haskell code just don't exist in OOP eg in C#
there are no modules to worry about, every class belongs to a file with the
same name, you don't need to decide where to put the object argument and
there are no top level functions or values.
In contrast, in Haskell you have to juggle class declarations, instance
declarations, types, values which may or may not be part of a class, and
decide which combinations of the above should go into which modules and what
the names of the modules should be and manually remember to keep some module
names and class names (or type names eg Data.Set and data Set a = ...) in
sync.
Anyway these are probably more long term ideas but I mentioned them
now just to hopefully start the ball rolling (the above should not
be taken as a criticism of Haskell, I'm just saying that at some
point we need all the normal mechanisms that everyone else (Java,
C#) takes for granted because there's no point waiting till we
encounter the same well-known software engineering problems that
already have well established good solutions).
It is best to think of haskell primitives as something completely new,
they reuse some naming conventions from OO programming, but that
doesn't mean they suffer from the same limitations.
Hopefully my neural pathways will reconnect themselves soon to take
advantage of all this new power!!! :-)
It took me a few
trys to wrap my brain around it. I liken learning haskell to tipping
over a vending machine. you can't just push it, you gotta rock it
back and forth a few times building up momentum until bam! suddenly
the flash of insight hits and it all makes sense.
Great image! We need a film or video of "a day in the life of Haskell" with
these kind of things in it eg camera cutting from scene of vending machine
satori to animated folds rippling through space gathering structure like a
new planet forming, then another cut to a silent robed figure casting
objects from a sack into a bottomless pit... :-)
Best regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.
http://www.metamilk.com
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe