[Haskell] Per-type function namespaces (was: Data.Set whishes)

Abraham Egnor aegnor at antioch-college.edu
Thu Feb 26 13:28:16 EST 2004


I think that this is a problem that can be solved with a simple convention
change, rather than a language extension - instead of appending type
names, I think it would be much better if modules simply used the short,
convenient, common names and expected the user to import them qualified
where overlap is a problem - in short, do exactly what DData does.  It's
slightly more verbose than OO-style: "Map.add map key value" instead of
"map.add(key, value);" but I don't think that "what OO does" is a good
language design target.

Another random thought: what you describe sounds awfully similar to
typeclasses, just with a single function in each typeclass.

Abe

ozone at algorithm.com.au writes:
>I've had an idea stewing in my head to do with per-type function 
>namespaces, that the current module namespace discussion reminded me 
>about.  The problem is that there is a limited namespace for functions, 
>so that if you define a new data type, it is unwise to call functions 
>which work on that data type a very generic name such as 'add'.  An 
>example of this is Data.FiniteMap and Data.Set: both data types define 
>a function to add things to their respective data types.
>
>addToFM :: Ord key => FiniteMap key elt -> key -> elt -> FiniteMap key 
>elt
>addToSet :: Ord a => Set a -> a -> Set a
>
>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 object-oriented 
>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?
>
>The idea that I've been throwing around is to be able to define a 
>separate namespace for each type; a function can either belong in a 
>"global" (default) namespace, or belong in a particular type's 
>namespace.  So, in the above example, instead of writing "addToFM fm 
>...", we could instead associate an 'add' function with the FiniteMap 
>type, so we could write "fm.add ..." instead.  Provided that fm's type 
>is monomorphic, it should be possible to call the 'correct' add 
>function; if we defined another 'add' function that's associated with 
>the Set type, that will only get called if the 'x' in "x.add" is of 
>type :: Set.  So, like OO languages which inherently give separate 
>namespaces to their different objects, here we give separate namespaces 
>to different (monomorphic) types.  In this case, if one simply writes 
>"add" instead of "x.add", the compiler throws an error, because there 
>is no 'add' function defined in the default namespace; add is only 
>defined when a programmer writes "x.add" where x :: FiniteMap or x :: 
>Set[1].
>
>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 signature of the 
>function).  Perhaps 'self' or 'this' could be an implicit parameter.  
>Any one of them will work just fine, I think.
>
>However, this scheme is only for functions which have such a 'primary' 
>data type to be associated with, such as FiniteMap or Set.  For 
>functions which are truly polymorphic (such as ==), you still leave 
>them in the default namespace.  Perhaps it's sensible to even make it a 
>requirement that functions in the default namespace must be 
>polymorphic: if they are monomorphic, they are associated with 
>operating on a specific data type, so they should belong in a 
>type-specific namespace.  You then still guarantee that such 
>commonly-used polymorphic functions cannot be 'hijacked' to have stupid 
>type signatures; i.e. == is always guaranteed to be :: Eq a -> a -> 
>Bool.
>
>Anyhow, feedback is more than welcome; I would certainly welcome this 
>addition if it's feasible.  It feels inferior to be typing in 'addToFM 
>foo' all the time when our OO brethren type the simpler and more 
>succinct 'foo.add', especially given that Haskell's type system is far 
>more powerful!
>
>1. I haven't thought hard enough about whether it would be possible to 
>have the same function name in both the 'default' namespace as well as 
>in per-type namespaces, but my gut feeling says it should be OK.
>
>
>-- 
>% Andre Pang : trust.in.love.to.save
>_______________________________________________
>Haskell mailing list
>Haskell at haskell.org
>http://www.haskell.org/mailman/listinfo/haskell
>





More information about the Haskell mailing list