New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Module qualified syntax #190

Open
wants to merge 12 commits into
base: master
from

Conversation

Projects
None yet
8 participants
@shayne-fletcher-da
Copy link
Contributor

shayne-fletcher-da commented Dec 28, 2018

A proposal for import M qualified syntax.

Rendered

@nomeata

This comment has been minimized.

Copy link
Contributor

nomeata commented Dec 28, 2018

Hmm, my first impression is “not enough baby for the buck”. Also, I vaguely remember proposals that want to allow mixing qualified and unqualified imports in one line; the present proposal might steal syntax from such ideas without a gain in expressivity.

@ndmitchell

This comment has been minimized.

Copy link
Contributor

ndmitchell commented Dec 28, 2018

@nomeata I find the continual annoyance of that qualified before the module to be huge. It's a wart in Haskell where there are two bad choices:

Option 1: don't indent. But now Data.Map on two successive rows doesn't line up. It's a set of imports, but do you sort ignoring the word qualified? It's much harder to scan for what is imported since the location of the interesting bit jumps around.

Option 2: do indent. Visually horribly displeasing, to have inner line indents, which should almost always otherwise be avoided. Requires typing out a bunch of spaces to do an import. But there are lots of semantic benefits around sorting and reading.

So Haskell has two bad options, resulting in inconsistency and people picking their poison, differently, and with a mild dose of poison to boot. In contrast qualified after solves all the issues neatly.

This has previously been proposed at:

  • #21. Reading through the comments, it seemed to be closed because it causes extra work for parsing tools like exact-parse (it really isn't that much), it tried to do too much (this one just moves qualified), and fear of having two different styles of Haskell (which I feel is unfounded - they are already two styles, we could move to having one). The other drawback was no migration plan, but the warning proposal solves that.

There have been lots of alternative proposals for how to collapse imports, making qualified the default, doing qualified exports etc. None of them seem very fleshed out, and none look like they conflict with this change. If qualified before vs after mean different things I'd argue they are poor proposals. If they don't move qualified after, I'd argue they don't tackle one of the major syntactic annoyances.

@nomeata

This comment has been minimized.

Copy link
Contributor

nomeata commented Dec 28, 2018

How about: Group by qualified and non-qualified? No the indenting problem goes away. This variant has the advantage that when you want to find out where some unqualified name foo in the body comes from, you have a shorter list of modules to look through?

@shayne-fletcher-da

This comment has been minimized.

Copy link
Contributor Author

shayne-fletcher-da commented Dec 28, 2018

How about: Group by qualified and non-qualified?

For me, I have a strong preference for wanting to be able to group related modules (mixing qualified and unqualified) by my own criteria rather than on qualified or non-qualified.

@ndmitchell

This comment has been minimized.

Copy link
Contributor

ndmitchell commented Dec 28, 2018

How about: Group by qualified and non-qualified?

I observe that's a valid option today, and one that I've never seen used in the wild. Seems that that disadvantage of not being able to group your modules by some other rules is too severe.

@osa1

This comment has been minimized.

Copy link
Contributor

osa1 commented Dec 28, 2018

To me this doesn't seem like it's worth adding a new pragma + a new warning flag. I'm honestly surprised that you thought this is a problem worth spending time writing and discussing about.

I think we should just stop adding new pragmas/flags for trivial syntax changes like this (another example is -XBlockArguments which started generated bug reports already) as they're in my experience not as low cost as the proposers/implementors (which usually don't keep maintaining the features they add) think they are. Consider all the bugs, changes in error messages with partial/incorrect input, user manual/man page sections, interactions with literally hundreds of other pragmas/warnings/flags, having to contribute the mess that is 100+ language pragmas ...

We're in enough technical debt already, let's at least stop adding features with such low benefit/cost.

@shayne-fletcher-da

This comment has been minimized.

Copy link
Contributor Author

shayne-fletcher-da commented Dec 28, 2018

To me this doesn't seem like it's worth adding a new pragma + a new warning flag.

It's only proposed that there be a warning flag and orthogonal to whether the syntax should be admitted.

If not set (the default) no warnings will be issued (no existing code will suddenly warn where it hasn't before). If on the other hand, in a given code-base the postpositive convention has been decided upon exclusively, enabling the warning can be used to identify violations.

@osa1

This comment has been minimized.

Copy link
Contributor

osa1 commented Dec 28, 2018

Another thing that's been bothering me is that we seem to lack guiding principles for the language design, and just keep adding and adding, to no end. Having more than one way of doing things, especially when the difference is so trivial (e.g. just 2 characters in the case of -XBlockArguments, a few more characters in this proposal), cause huge amount of considerations (compared to what they're actually worth) in collaborations. You'll either let people use whatever style they want (leads to inconsistency), or spend your time and energy on useless matters.

Perhaps it's time to stop for a bit and consider where we want to go with the language and the compiler. Some other languages do this really well. In fact I've yet to see a compiler/language that does as bad as GHC/Haskell on this.

It's only proposed that there be a warning flag and orthogonal to whether the syntax should be admitted.

How are they orthogonal? The warning makes no sense without the new syntax, does it? And for new syntax you need a new pragma. So really you want a new language pragma + new warning flag.

@shayne-fletcher-da

This comment has been minimized.

Copy link
Contributor Author

shayne-fletcher-da commented Dec 28, 2018

How are they orthogonal?

Not adding a warning does not preclude accepting the postpositive syntax.

I have not considered adding a new language extension to enable this syntax (wouldn't have thought it necessary in this case).

@ndmitchell

This comment has been minimized.

Copy link
Contributor

ndmitchell commented Dec 28, 2018

I view this as important. Shayne does. The reaction on Twitter and thumbs up on this proposal and the previous one suggest others do too. It might not matter to you, but it matters to me. I consider this a mistake that Haskell made, and setting it right has a cost, but so does not fixing it. Each person gets to weigh that for themselves, and decide what to invest time into (and then the committee gets to decide as a whole). I do however think it's only right that the implementer fix up all interactions and documentation, and sufficient test cases, otherwise the patch should rightly be rejected from GHC. That's the barrier for getting a GHC patch accepted.

And for new syntax you need a new pragma.

Not necessarily. Shayne is not proposing one here. Adding a pragma would be a valid alternative.

Perhaps it's time to stop for a bit and consider where we want to go with the language and the compiler.

We gave up on that when we started the GHC proposals process. You can't solicit community contributions and have a top-down plan that isn't shared and decide to freeze changes.

@osa1

This comment has been minimized.

Copy link
Contributor

osa1 commented Dec 28, 2018

I consider this a mistake that Haskell made, and setting it right has a cost, but so does not fixing it.

I can agree that current syntax is a mistake, and the proposed syntax is better. However supporting both is worse than the current situation. Propose a plan for removing current syntax in a few years of time and I'll give a 👍.

Not necessarily. Shayne is not proposing one here. Adding a pragma would be a valid alternative.

Maybe I'm missing something. I thought any changes over the language standard requires a language pragma. Is this not the case? Do we currently have any changes over Haskell 2010 that is not behind a pragma?

We gave up on that when we started the GHC proposals process. You can't solicit community contributions and have a top-down plan that isn't shared and decide to freeze changes.

I disagree. We could for example say that the syntax should be as simple as possible, with one way of doing things whenever possible. On that ground this (and -XBlockArguments) would be rejected, but other some of the syntax extensions (e.g. binary literals) would be accepted.

I'm not expecting a perfect process, but we should be doing something to define some goals and principles.

@ndmitchell

This comment has been minimized.

Copy link
Contributor

ndmitchell commented Dec 28, 2018

I can agree that current syntax is a mistake, and the proposed syntax is better. However supporting both is worse than the current situation. Propose a plan for removing current syntax in a few years of time and I'll give a 👍.

I think the warning is meant to offer a path in that direction. Certainly in commercial code bases (with no backwards compat requirements) I'd expect the warning to be turned on quickly. Disabling it more generally probably has to wait 3 years anyway, but given the clear superiority, my only reason for waiting would be backwards compat.

Maybe I'm missing something. I thought any changes over the language standard requires a language pragma. Is this not the case? Do we currently have any changes over Haskell 2010 that is not behind a pragma?

That would be great to clarify as a design principle.

I'm not expecting a perfect process, but we should be doing something to define some goals and principles.

Hard to argue too much there. Perhaps a request on the committee @nomeata ? The current docs are all very process orientated, not principle orientated. https://github.com/ghc-proposals/ghc-proposals#review-criteria is somewhat close, but doesn't really give weightings, and lacks specificity.

@int-index

This comment has been minimized.

Copy link
Contributor

int-index commented Dec 28, 2018

Another thing that's been bothering me is that we seem to lack guiding principles for the language design, and just keep adding and adding, to no end.

@osa1 We're actually removing some things as well, https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0030-remove-star-kind.rst

For me, the main motivation for removing (or not adding) something is when there are issues with the proposal or when it stands in the way of something more important.

In case of allowing another position for the qualified keyword, I see no issues with this, and it doesn't seem to interfere with other potential extensions. @nomeata mentions "proposals that want to allow mixing qualified and unqualified imports in one line", and I remember them too - perhaps we should be aiming for that in the long run, but I don't see how this small proposal would create any trouble.

That said, I'm overall neutral on this. I don't think alignment matters that much and I'm fine with writing

import Data.Map (Map)
import qualified Data.Map as Map

in two consequent lines without useless extra spaces. Rearranging the keywords doesn't buy us much, but it's not that big a deal to support it in the compiler if people want it.

@nomeata

This comment has been minimized.

Copy link
Contributor

nomeata commented Dec 28, 2018

I thought any changes over the language standard requires a language pragma. Is this not the case? Do we currently have any changes over Haskell 2010 that is not behind a pragma?

That would be great to clarify as a design principle.

This has been a principle with GHC, to the extent possible, even before the proposal process, and still is. Maybe it is not written down explicitly, but came up a few times in discussion and so far, we stuck to this rule.

I understand that having to enable a language extension to get your favorite syntax tweak might make it less attractive. This killed syntax tweaks that I very much liked. But I guess it's a feature, a form of a high pass filter.

So in this case, the proposals ought to propose a pragma.

About a general guideline and direction here: when I joined the committee, I asked for such guidance, but nobody could give it to me. And probably it's just not possible: any general rule will either allow too many changes, and make GHC complicated to develop and use, or too few changes, and cause stagnation, or will be ignored. Hence we look at each proposals individually - it seems to be the best we can do. (If someone can craft a general guidance that works, I'd be very happy about it!)

@shayne-fletcher-da

This comment has been minimized.

Copy link
Contributor Author

shayne-fletcher-da commented Dec 28, 2018

So in this case, the proposals ought to propose a pragma.

Seems reasonable enough. That being the case, let's suppose then (implicitly,) this proposal to do so!

@gbaz

This comment has been minimized.

Copy link

gbaz commented Dec 28, 2018

I think what this points to is that a full rework of import syntax that resolved a bunch of annoyances at once might get past the filter with better success. I.e. solving the qualified indents and also allowing mixed qualified and unqualified on one line, etc. So then an "extended import syntax" or whatever pragma can pay its way much more clearly.

@ndmitchell

This comment has been minimized.

Copy link
Contributor

ndmitchell commented Jan 9, 2019

@gbaz a full rework of everything would be great. But no one has a coherent design, and the fallout is unknown. There is a proposal here for a small step in a positive direction. If someone volunteers to come up with a full proposal to solve more, or can point at one, we should close this one. But I don't think perfect should be the enemy of better.

@ndmitchell

This comment has been minimized.

Copy link
Contributor

ndmitchell commented Jan 27, 2019

The proposal has been amended to include a language extension. Discussion has tailed off. There are very definitely two camps here:

  • People who love this extension hugely. 16 thumbs up. 34 on the previous iteration of the proposal. 6 retweets, 34 likes. I've also had a chunk of individual messages from people saying "finally".
  • People who feel this extension doesn't bring enough bang for the buck. It is a small extension.

I can only reiterate that it would remove one of the frustrations that I've experienced at every company I've worked at. It's absence doesn't put anyone off using Haskell, but it certainly makes Haskell teams have an internal debate between multiple styles when there's clearly a best answer, and this proposal just lets them use it. I suggest the proposal go to the committee as-is.

@gbaz

This comment has been minimized.

Copy link

gbaz commented Jan 28, 2019

For clarity, would this proposal allow us to say the following?

import Data.Map qualified as M

@erikd

This comment has been minimized.

Copy link

erikd commented Jan 28, 2019

Just clarifying @gbaz's comment, under this proposal would:

import Data.Map qualified as M

have identical behavior to:

import qualified Data.Map as M

as we currently have?

@shayne-fletcher-da

This comment has been minimized.

Copy link
Contributor Author

shayne-fletcher-da commented Jan 28, 2019

Yes, indeed! import Data.Map qualified as M will behave identically to import qualified Data.Map as M.

@int-index

This comment has been minimized.

Copy link
Contributor

int-index commented Jan 28, 2019

When the QualifiedImportsPostpositive extension is on, I would expect the prepositive form to be disallowed. It's an unnecessary axis of freedom.

@shayne-fletcher-da

This comment has been minimized.

Copy link
Contributor Author

shayne-fletcher-da commented Jan 28, 2019

That's the purpose of the newly introduced warning. Right now the intent is to default it to off as mentioned in the proposal.

@int-index

This comment has been minimized.

Copy link
Contributor

int-index commented Jan 28, 2019

Yes, that's the bit I disagree with. I don't see any reason to make it a warning rather than an error – why would anyone use both the postpositive and the prepositive form in a single file (or project)? It's one more thing to disallow in styleguides.

@shayne-fletcher-da

This comment has been minimized.

Copy link
Contributor Author

shayne-fletcher-da commented Jan 28, 2019

Noted. Thanks for the feedback!

@ndmitchell

This comment has been minimized.

Copy link
Contributor

ndmitchell commented Jan 28, 2019

@int-index for a large project I might enable the extension, convert files one at a time, and then at the end enable the warning. That said, I'm happy either way, it's probably only a sed away from fixing them all in one go. I suggest it get added to the list of unresolved questions or alternatives.

@int-index

This comment has been minimized.

Copy link
Contributor

int-index commented Jan 28, 2019

What happens if the programmer specifies the qualified keyword in both positions?

import qualified Data.Map qualified as M

Is this an error or is it the same as a single qualified? If we make the extension disallow the prepositive form, we don't face this question.

@shayne-fletcher-da

This comment has been minimized.

Copy link
Contributor Author

shayne-fletcher-da commented Jan 28, 2019

I had intended that should it be specified in both positions that it should be treated as qualified. I'll write this case too into the unresolved questions section.

shayne-fletcher-da added some commits Jan 28, 2019

@simonpj

This comment has been minimized.

Copy link
Contributor

simonpj commented Jan 28, 2019

I can only reiterate that it would remove one of the frustrations that I've experienced at every company I've worked at.

Coming from someone like Neil, this counts heavily for me.

This is a superficial change with no deep consequences or knock-on effects. Let's just do it and move on!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment