| | 113 | |
| | 114 | |
| | 115 | |
| | 116 | === Problems with using the current module namespace mechanism === |
| | 117 | |
| | 118 | 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: |
| | 119 | |
| | 120 | {{{ |
| | 121 | data Comment = Comment { |
| | 122 | commentId :: CommentId |
| | 123 | , commentContent :: Content |
| | 124 | , commentReviewId :: ReviewId |
| | 125 | , commentSubmissionId :: SubmissionId |
| | 126 | , commentConferenceId :: ConferenceId |
| | 127 | , commentDate :: ISODate |
| | 128 | , commentReviewerNumber :: Int |
| | 129 | } deriving (Show) |
| | 130 | }}} |
| | 131 | |
| | 132 | 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. |
| | 133 | |
| | 134 | 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. |
| | 135 | |
| | 136 | 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. |
| | 137 | |
| | 138 | 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. |