It would be helpful to support a short syntax for importing unqualified identifiers while establishing a short qualified name. An example of the proposed syntax is,
importData.Map(Map)asM
The desired semantics are that Map be imported unqualified, and M be defined as an alias for Data.Map. This replaces the existing convention of writing,
importData.Map(Map)importqualifiedData.MapasM
The proposed syntax is currently an error, I think, so adding support for it should not break anything.
Trac metadata
Trac field
Value
Version
7.10.1
Type
FeatureRequest
TypeOfFailure
OtherFailure
Priority
normal
Resolution
Unresolved
Component
Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Child items
0
Show closed items
No child items are currently assigned. Use child items to break down this issue into smaller parts.
Linked items
0
Link issues together to show that they're related or that one is blocking others.
Learn more.
I had forgotten about the existing import Data.Map as M syntax. So, to clarify, the proposed syntax will require the parenthetical part. This offers a new way of writing a qualified import: import Foo() as F.
Different semantics based on order of parens and as is too ambiguous and hard to remember IMO.
Also, the existing convention to import data type unqualified and the rest qualified is some kind of a hack working around lack of nested namespaces. In the ideal world Data.Map should export functions qualified. Like the next:
I'm in favor of abbreviating the syntax in this common scenario, but I don't like your choice of syntax, I'm afraid. It would give
import Data.Map (Map) as M -- (1)
a very different meaning from
import Data.Map as M (Map) -- (2)
(1) imports all of Data.Map, qualified with the alias M, and imports the name Map unqualified. (2) imports only the name Map (unqualified) while also aliasing Data.Map.
Having these two coexist seems like we're asking users to be confused.
What about
import Data.Map (Map) qualified as M *
?
The general schema, which replaces the current syntax. This schema does not permit some current syntax, but it would be easy to extend it to be backward-compatible. I've chosen not to for this presentation to avoid clutter.
The top-level maybe_name_list would list all unqualified imports. If it is omitted, and there are no qualified_specs, then all names would be imported unqualified. If it is omitted and there are one or more qualified_specs, then no names would be imported unqualified.
Each import_specifier either adds qualified names (perhaps under a module synonym) or removes names. Removing names with hiding removes those names from the qualified_spec (or top-level maybe_name_list) immediately preceding the hiding.
The special name_list* (note that it is not in parentheses, to avoid ambiguity) means "all names".
This schema allows one import statement to import a mix of qualified and unqualified names, and even allows using different module synonyms for different sets of qualified names. The legacy import syntax could desugar to this form, which seems strictly more expressive. For example:
import qualified Foo --> import Foo qualified *import qualified Bar as B --> import Bar qualified as B *import Baz hiding (wurble) --> import Baz hiding (wurble)
Why not use (..) instead of *? It seems more consistent with Haskell's current syntax.
Sold. I like this much more than *. It was also suggested that (..) could be omitted if it were going to be the last item on the line. I'm happy with that suggestion, too.
I don't think a desire to keep the qualified word is more logical or obvious than any other option. I can't think of another programming language that uses the qualified keyword. Agda uses import M as N to create a qualified alias. Python imports qualified by default. But this is Haskell, so we should consider how Haskell is used. If you grep over the source of all packages in the Stackage package set, you will find that import statements that use the as keyword are qualified 10x more than unqualified. If you focus on the specific syntax, import Foo as F(bar), it is used in less than 0.3% of all import statements. So we are loading by far the more common usage with extra syntax.
I suggest a way of reading import statements as "import ModuleName (unqualifiedImports)" If you want to use qualified names, all of that information is given by appending a suffix to the import statement beginning with the as keyword.
This is certainly new syntax, but I have yet to see any quantifiable argument that it is less logical or undesired (see the support for the proposal linked from the haskell-cafe thread). Also note that the proposal will not break anything: if you find qualified easier to read, then you can continue to use it. If nobody uses the new syntax because it is hard to understand, then nobody will suffer.
Here is an overview for two of the proposals listed on this ticket. Please inform me of any mistakes there might be, and I will edit this comment.
I'm using the variant of goldfire's proposal with (..) instead of *, and where (..) at the end of the line can be omitted.
@goldfire: I understand your proposal would (also) be fully backward compatible. Please tell me on which rows you would recommend to use the old syntax. And maybe there's a useful trick only your proposal supports?
Perhaps my proposal was not clearly stated. I have modified the examples below to support my intent. If you see an error in the proposal, please do let me know! My changes affect the first block and the very last line.
Potentially confusing things about these proposals, assuming full backward compatibility:
proposal
H2010 syntax
new syntax
Why confusing?
acowley
\*\*import A as B (x)\*\*
\*\*import A (x) as B\*\*
look similar, do different things
Just to chime in to confirm that this is the most ripe for confusion part of the proposal. No semantics of working code change with the extension enabled, but this point of confusion is introduced. For context, the syntax import A as B (x) is used in 0.3% of all import statements over all the code in the Stackage package set.
A lot (15?) of people on the mailinglist were in favour of acowley's proposal, or at least for some form of shorter import syntax.
Only one person was specifically in favour of goldfire's proposal. I think this low number had more to do with the proposal not being presented very clearly than anything else, given how similar the two proposals are.
Edit: Some people argued for a more descriptive keyword than as (e.g. import Data.Map (Map) and as M (...) or import Data.Map (Map) andAs M (...)). These could be counted towards goldfire's proposal perhaps.
A few people were (strongly) against acowley's proposal, all citing Richard O'Keefe's mail.
reddit seemed firmly against acowley's proposal as well (the top comment has 12 votes and starts with "-1"). This is the reason I think we should proceed carefully here.
I don't think this is going to go anywhere without someone writing a proposal page on the wiki, with specifications of the 2 options and the above table, and then having another round of discussion on the mailinglist.
If one of you could get behind the other person's proposal, that would make things easier as well.