... | ... | @@ -76,6 +76,63 @@ So one solution for record field names is to specify more precisely which one yo |
|
|
|
|
|
---
|
|
|
|
|
|
### Problems with using the module namespace mechanism
|
|
|
|
|
|
|
|
|
Suppose I have 112 hand-crafted data types in my
|
|
|
project (e.g. see attachment 51369.txt), this creates a lot of
|
|
|
conflicts in field names and constructor names. For example:
|
|
|
|
|
|
```wiki
|
|
|
data Comment = Comment {
|
|
|
commentId :: CommentId
|
|
|
, commentContent :: Content
|
|
|
, commentReviewId :: ReviewId
|
|
|
, commentSubmissionId :: SubmissionId
|
|
|
, commentConferenceId :: ConferenceId
|
|
|
, commentDate :: ISODate
|
|
|
, commentReviewerNumber :: Int
|
|
|
} deriving (Show)
|
|
|
```
|
|
|
|
|
|
|
|
|
This is a real type in my project. It has fields like “id”, “content”,
|
|
|
“reviewId”, “submissionId”, “date”. There are seven other data types
|
|
|
that have a field name “submissionId”. There are 15 with
|
|
|
“conferenceId”. There are 7 with “content”. And so on. This is just to
|
|
|
demonstrate that field clashes *do* occur *a lot* in a nontrivial
|
|
|
project.
|
|
|
|
|
|
|
|
|
It also demonstrates that if you propose to put each of these 112 types
|
|
|
into a separate module, you are having a laugh. I tried this around
|
|
|
the 20 type mark and it was, apart from being very slow at compiling,
|
|
|
*very* tedious to work with. Creating and editing these modules was a
|
|
|
distracting and pointless chore.
|
|
|
|
|
|
|
|
|
It *also* demonstrated, to me, that qualified imports are horrible
|
|
|
when used on a large scale. It happened all the time, that'd I'd
|
|
|
import, say, 10 different data types all qualified. Typing map
|
|
|
(Foo.id . BarMu.thisField) and `foo Bar.Zot{x=1,y=2`} becomes tedious
|
|
|
and distracting, especially having to add every type module when I
|
|
|
want to use a type. And when records use other types in other modules,
|
|
|
you have *a lot* of redundancy. With the prefixing paradigm I'd write
|
|
|
fooId and barMuThisField, which is about as tedious but there is at
|
|
|
least less . confusion and no need to make a load of modules and
|
|
|
import lines. Perhaps local modules would solve half of this
|
|
|
problem. Still have to write “Bar.mu bar” rather than “mu bar”, but
|
|
|
it'd be an improvement.
|
|
|
|
|
|
|
|
|
I also have 21 Enum types which often conflict. I end up having to
|
|
|
include the name of the type in the constructor, or rewording it
|
|
|
awkwardly. I guess I should put these all in separate modules and import qualified,
|
|
|
too. Tedious, though. At least in this case languages like C\# and
|
|
|
Java also require that you type `EnumName.EnumValue`, so c‘est la vie.
|
|
|
|
|
|
---
|
|
|
|
|
|
### Type directed name resolution
|
|
|
|
|
|
|
... | ... | |