
On Fri, 2009-01-02 at 15:20 +0100, Felix Martini wrote:
Hi all,
There is currently a discussion on reddit/programming about Haskell. One complaint is that Haskell functions often use abbreviated names. I tend to agree with that. In my personal experience it generally takes more time to learn a third party Haskell library than libraries written in other languages. I am not sure why but it could be because of function names. It seems to me that Haskell's current record syntax enhances this. Take for example the new xml library,
data Element = Element { elName :: QName elAttribs :: [Attr] elContent :: [Content] elLine :: Maybe Line }
data Attr = Attr { attrKey :: QName attrVal :: String }
data QName = QName { qName :: String qURI :: Maybe String qPrefix :: Maybe String }
Personally i would prefer it to be something like
data Element = Element { name :: QualifiedName attributes :: [Attribute] content :: [Content] line :: Maybe Line }
data Attribute = Attribute { key :: QualifiedName value :: String }
data QualifiedName = QualifiedName { name :: String uri :: Maybe String prefix :: Maybe String }
but the global scope of the record field names doesn't allow that
They are not global. They are scoped to the module just like any other function definition. So if you were to put each record in it's own module you can have Attribute.key today. No one does this though because that's rather heavy-weight. I've suggested in #haskell a few times an orthogonal language feature that will resolve this as well as providing other nice things and, being orthogonal, it keeps namespacing to namespacing mechanisms (namely modules.) The feature is simply local modules. You'd get what you want by simply writing, module Attribute where data Attribute = Attribute { key :: QualifiedName, value :: String } I haven't been able to find any semantic difficulties with this addition. There are some choices, namely what to import and export by default and some scoping issues. My choices would be to import everything in scope at the module declaration, the containing module tacitly imports everything the contained module exports, the same notation Module.name is used so a local module would shadow a top-level (hierarchical) module of the same name (though I don't expect that to be a common case.) With these conventions there would often be nominal mutual recursion between local modules at the same level. The implementation could either check to see if there is any actual mutual recursion and give an error, or, much more preferably, simply allow mutually recursive local modules as this should be much easier to handle than mutually recursive top-level modules. Some other benefits of this would be a nice way to make abstract data types, which are also underused due to the heaviness of the module system. You could write, for example, module Stack (Stack, empty, push, pop, isEmpty) where newtype Stack a = Stack [a] empty = Stack [] push x (Stack xs) = Stack (x:xs) pop (Stack (x:xs)) = Just (x, Stack xs) pop (Stack [] ) = Nothing isEmpty (Stack xs) = null xs It should be straightforward to implement this today as a pre-processor at the cost of not allowing local modules with the same qualified name as a top-level module and losing some encapsulation. The pre-processor would simply need to extract all the local module declarations and make the appropriate hierarchical modules and add the appropriate import statements. The easiest and most restrictive way to deal with mutual recursion in this case is simply have a local module only import it's ancestor modules and any modules explicitly imported. The benefit of this approach is that it doesn't require any kind of analysis, it could be done on an almost purely textual basis.
and therefore all kinds of abbreviations are inserted in front of the record field names which are hard to remember. So a better record syntax would be welcome. Perhaps the constructor could be used to limit the scope of the record field name e.g. QualifiedName.prefix?
Regards, Felix _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe