RE: Export lists in modules

On 22 February 2006 14:54, Malcolm Wallace wrote:
"Simon Peyton-Jones"
wrote: I don't seriously propose for haskell-prime that signatures should be required on exports. Just permitting them would be a large and useful step up already.
If this is to be a serious proposal, someone had better think what to do about classes, data types, instances and so on.
As far as I can see, there is very little to change. Here is a concrete proposal. A qvar in an export list may optionally have a type signature. A qtycon or qtycls in an export list may optionally have an annotation saying whether it is a type, newtype, data, or class. Instances cannot be mentioned in export lists, and this does not change.
export -> qvar | qtycon [ (..) | ( cname_1, ... , cname_n ) ] (n>=0) | qtycls [ (..) | ( var_1, ... , var_n ) ] (n>=0) | module modid
becomes
export -> qvar [ :: type ] | [type] qtycon | [newtype] qtycon [ (..) | ( cname_1, ... , cname_n ) (n>=0) | [data] qtycon [ (..) | ( cname_1, ... , cname_n ) (n>=0) | [class] qtycls [ (..) | ( var_1, ... , var_n ) (n>=0) | module modid
As far as import entity lists are concerned, we permit an optional annotation for type synonyms, newtypes, datatypes, and classes:
import -> var | tycon [ (..) | ( cname_1, ... , cname_n ) ] (n>=0) | tycls [ (..) | ( var_1, ... , var_n ) ] (n>=0)
becomes
import -> var | [type] tycon | [newtype] tycon [ (..) | ( cname_1, ... , cname_n ) ] (n>=0) | [data] tycon [ (..) | ( cname_1, ... , cname_n ) ] (n>=0) | [class] tycls [ (..) | ( var_1, ... , var_n ) ] (n>=0)
Anyone see any difficulties?
You're combining two extensions here - type signatures in export lists and tagging exported entities. Not a problem, but I don't think they're inextricably linked. Regarding tagging of exported entities, see this message from John Meacham in a previous discussion: http://www.haskell.org//pipermail/haskell-prime/2006-January/000226.html basically tagging exports lets us completely separate the namespaces of classes and tycons (currently they share the same namespace, for no really good reason). But you don't need to go so far as to indicate the difference between type/data/newtype - just differentiating classes from tycons is enough to separate the namespaces. Indeed, the distinction between data & newtype should be a completely private property, so we certainly shouldn't distinguish those in exports/imports. It's less clear to me whether type and data/newtype should be distinguished or not, which is why I asked the question. I'm not sure I agree with John's answer, I'd rather just say 'type' or 'data', using 'data' for both data and newtype, like Haddock does. BTW, I think Simon PJ was asking about how to *declare* types & classes in export lists, given that you're adding signatures to export lists which are a kind of declaration. If you want to put more of the interface into the export list, shouldn't you put it all in? Cheers, Simon

"Simon Marlow"
You're combining two extensions here - type signatures in export lists and tagging exported entities. Not a problem, but I don't think they're inextricably linked.
Indeed. I made them separate pages on the wiki. They were combined in my email only because Simon PJ asked how they related to each other. Although I now see that was not really his question at all.
But you don't need to go so far as to indicate the difference between type/data/newtype - just differentiating classes from tycons is enough to separate the namespaces.
Yes. However it could be slightly confusing that one writes "newtype" in the module body, but "data" in the module header?
It's less clear to me whether type and data/newtype should be distinguished or not, which is why I asked the question.
They are already distinguished in ghc. It always complains to me when I write Foo(..) in an export list, where the Foo is a type synonym rather than a datatype. (Not that I necessarily agree with ghc's behaviour here... :-) You will notice that for this reason, the export production for "type Foo" does not permit a subordinate list. However, I would be equally happy to combine type/newtype/data into a single keyword for exports.
BTW, I think Simon PJ was asking about how to *declare* types & classes in export lists, given that you're adding signatures to export lists which are a kind of declaration. If you want to put more of the interface into the export list, shouldn't you put it all in?
Yes, I see the point. In the fullness of time, perhaps we will indeed specify the module interface in full, including datatype definitions. But for the moment, I am more interested in regularising existing practice. Regards, Malcolm

Am Mittwoch, 22. Februar 2006 18:27 schrieb Malcolm Wallace:
[...]
But you don't need to go so far as to indicate the difference between type/data/newtype - just differentiating classes from tycons is enough to separate the namespaces.
Yes. However it could be slightly confusing that one writes "newtype" in the module body, but "data" in the module header?
But whether a type is declared by data or by newtype is an implementation detail, so this distinction shouldn't be made in a part of the code which is supposed to specify an interface. On the other hand, if you export constructors too, the distinction between newtype and data might be important...
[...]
BTW, I think Simon PJ was asking about how to *declare* types & classes in export lists, given that you're adding signatures to export lists which are a kind of declaration. If you want to put more of the interface into the export list, shouldn't you put it all in?
Yes, I see the point. In the fullness of time, perhaps we will indeed specify the module interface in full, including datatype definitions.
Only those parts of datatype definitions which are exported. And we would have to include fixity declarations too.
[...]
Regards, Malcolm
Best wishes, Wolfgang

On Wed, Feb 22, 2006 at 05:11:26PM -0000, Simon Marlow wrote:
Indeed, the distinction between data & newtype should be a completely private property, so we certainly shouldn't distinguish those in exports/imports. It's less clear to me whether type and data/newtype should be distinguished or not, which is why I asked the question. I'm not sure I agree with John's answer, I'd rather just say 'type' or 'data', using 'data' for both data and newtype, like Haddock does.
my best argument against this is to try to compile the following under ghc in strict haskell 98 mode
class Foo a instance Foo IOError
oops! Even if the restriction on synonyms in instance heads is lifted, being able to use type synonyms to give true aliases for types is important part of writing interfaces that can evolve and encapsulating implementation details. But more importantly, The haskell module system has a nice philosophy of just being about controlling the namespace of what is in scope in a module. Conflating representation details with it would just confuse things. I'd say use 'type' for everything in the type namespace, class for everything in the class namespace, value (or nothing) for things in the value namespace and so forth. We want the module system to describe precicely what names are in scope and what entities names in a module map too, nothing more. It is also a much simpler set of rules to remember and much more straightforward to specify. John -- John Meacham - ⑆repetae.net⑆john⑈

Am Donnerstag, 23. Februar 2006 02:47 schrieb John Meacham:
[...]
But more importantly, The haskell module system has a nice philosophy of just being about controlling the namespace of what is in scope in a module. Conflating representation details with it would just confuse things. I'd say use 'type' for everything in the type namespace, class for everything in the class namespace, value (or nothing) for things in the value namespace and so forth. We want the module system to describe precicely what names are in scope and what entities names in a module map too, nothing more. It is also a much simpler set of rules to remember and much more straightforward to specify.
The remaining problem is that using "type" for every type is misleading, since "type" is otherwise used only for aliases. Maybe it would be better to use something like "typealias" for type aliases, since using "type" for declaring type aliases is misleading anyway.
John
Best wishes, Wolfgang

Wolfgang Jeltsch wrote:
Maybe it would be better to use something like "typealias" for type aliases, since using "type" for declaring type aliases is misleading anyway.
I would be happy if "type" were returned to the pool of usable identifiers. The other name I frequently wish I could use is "default". It's frustrating that it's reserved for such a rarely used feature. Yeah, I know, Wadler's law. -- Ben

On Thu, Feb 23, 2006 at 11:36:34AM +0100, Wolfgang Jeltsch wrote:
The remaining problem is that using "type" for every type is misleading, since "type" is otherwise used only for aliases. Maybe it would be better to use something like "typealias" for type aliases, since using "type" for declaring type aliases is misleading anyway.
I don't think it is that misleading, when you have data Foo = Bar | Baz I think of the name 'Foo' as a type. You say x has type Foo. not x has data Foo. type synonyms do nothing but introduce a new type name which is why it is declared with 'type', but data and newtype introduce a typename and something else. but refering to just the name as a 'type' is consistent with usage. not that the terminology is perfect, but I don't think it is odd enough to warrent changing or worrying too much about. John -- John Meacham - ⑆repetae.net⑆john⑈

[sorry, I've lost the original post] On Thu, Feb 23, 2006 at 04:47:37PM -0800, John Meacham wrote:
On Thu, Feb 23, 2006 at 11:36:34AM +0100, Wolfgang Jeltsch wrote:
The remaining problem is that using "type" for every type is misleading, since "type" is otherwise used only for aliases. Maybe it would be better to use something like "typealias" for type aliases, since using "type" for declaring type aliases is misleading anyway.
I'd be in favour of H' supporting "typealias" as well as "type". This would lead the way, via compilers giving warning for uses of "type", to dropping support for "type" more painlessly in a future standard. Too much code has variables called "typ"... I think the same with "data" and "datatype" would be nice too. I also have a number of variables called "dat" dotted around. We could still use "type" in export lists, if desired, in the same way we use can still use things like "export" in FFI exports (i.e. you might have to export "variable type" rather than an unqualified "type"). Thanks Ian
participants (6)
-
Ben Rudiak-Gould
-
Ian Lynagh
-
John Meacham
-
Malcolm Wallace
-
Simon Marlow
-
Wolfgang Jeltsch