[Haskell] Per-type function namespaces (was: Data.Set whishes)
davidb at home.se
Fri Feb 27 11:26:08 EST 2004
Andre "Ozone" wrote:
> On 27/02/2004, at 9:51 AM, David Bergman wrote:
> >> So at the moment, many Haskellers will append the type name to the
> >> function to indicate that it only works on that particular
> data type.
> >> In this respect, Haskell is at a disadvantage vs most
> >> languages, because in them, you can write "x.add", and the type
> >> system will perform "object-oriented polymorphism" for you
> and call
> >> the correct add method, no matter if x is a FiniteMap or a Set.
> >> Writing "addToFM fm ..." or "addToSet set ..." is surely a
> lot more
> >> inconvenient than writing "fm.add" or "set.add", no?
> > Yes. But, you are refering to overloading, no? And, not subtype
> > polymorphism (which is what I denote with "object-oriented
> > polymorphism")? Just to make things clear in my mind.
> Yes, what I'm referring to is essentially overloading. I
> called it "object-oriented polymorphism" because that's
> typically what OO people call such a thing :).
No, "they" do not. What they call polymorphism, we call subype polymorphism
or, if we are really hard-core and/or old school, even ad-hoc polymorphism.
"They" do not even realize that overloading falls in the category of
polymorphism at all...
> (I should
> know better to use OO terminology on a Haskell list; won't
> happen again ...).
I think it is good that you do. We need that touch of engineering realism
> However, it's form of overloading that
> Haskell cannot currently handle well with type classes --
> Oleg's post proves that you can do it, of course, but that's
> a (very good) hack rather than a long-term solution.
I personally use (Haskell) classes for that overloading purpose, but in a
sense that Generic Programmers would call concept modelling.
> > So, you have thought of automatically, but implicitly, introduce a
> > namespace for each data type, and then have Haskell employ Koenig
> > Lookup, to decide which function an expression is refering to?
> It's a bit like Koenig lookup in that it has the same effect,
> although it's probably easier for the compiler to infer the
> namespace wanted, since we write "expr.function ..." rather
> than "function expression ...".
Whether it is prefix or postfix should not alter the complexity of the
> Writing "function expression
> ..." would work too, but then it looks like a standard
> function call rather than a function call associated with a
> particular type, and I think that causes more confusion.
> Long-time Haskell users understand that writing "foo.f"
> means "use f in namespace foo"; changing around the language
> semantics to mean that "f foo" now means "use f in namespace
> foo" would make lots of people rather unhappy :).
I would want it to look as an ordinary function. The single biggest problem
with Haskell, in my extremely humble opinion, is the shared namespace for
all data type accessors, with which you probably agree. It is what irritated
me the most with Entity-Relationship Diagram, that all fields need to have
unique name globally. This in contrast to instance variables, methods and
general overloading, as often found in OO languages.
> > You realize, of course, that "mere" intranamespacial parameter type
> > lookup (regular overloading) would achieve the same effect, without
> > the
> > (implicit)
> > namespaces?
> I'm not sure what you mean by "intranamespcial parameter type lookup"
> -- can you explain?
ah, I meant regular overloading, i.e., have a function be identified not by
its name, but by its whole signature, including the arity and parameter
type(s) [yes, curry, curry...]
> >> There are a number of means by which the x in x.add can be
> >> communicated to the actual function: it's similar to the
> hidden 'self'
> >> or 'this'
> >> variable that's present when you invoke a method on an
> object in OO.
> >> Perhaps x is passed to the function as its first
> parameter, or maybe
> >> it could be its last parameter, or even an arbitrary
> parameter (where
> >> the parameter it's passed as could be defined in the type
> >> of the function). Perhaps 'self' or 'this' could be an implicit
> >> parameter.
> >> Any one of them will work just fine, I think.
> > Again, I think you are confusing the runtime dispatching subtype
> > polymorpism from overloading. Overloading would do what you want,
> > while the subtype polymorphism could (still) be handled by
> class, and
> > instances of classes, the Generic Programming way.
> I (think I) understand the difference between dynamic binding vs
> overloading: here, all I'm after is trying to use the type
> system to give us a very simple form of overloading (e.g.
> based on the first argument to a function), that gives us the
> same effect as a per-type name space.
When I read my own response, I know realize that it sounds harsh. Sorry
about that. That was not the intention. I also think you understand and
appreciate the difference between the two forms of polymorphisms.
You touch at one of the core problems of Haskell.
More information about the Haskell