-
Notifications
You must be signed in to change notification settings - Fork 264
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
Amend 281 to use atype instead of ktype #606
Conversation
I don't have a strongly held position myself -- but yes, I did fid it surprising. |
can explicitId (type (forall a. a -> a)) id -- instead of
explicitId (type forall a. a -> a) id servantClient (type (ApiWith SomeArgument AndAnother)) -- instead of
servantClient (type ApiWith SomeArgument AndAnother) EDIT: The only example in the proposal of non-atomic type is explicitly parenthesized t = typeRepVis (type (Maybe String)) It's quite subtle to hide such visible grammar choice into just single example. |
@phadej The end-goal is to write your examples as explicitId (forall a. a -> a) id
servantClient (ApiWith SomeArgument AndAnother) This is possible with part 2 of this proposal. You still have the choice to write out an explicit
Yes, it can be understood as |
@phadej For what it's worth, this was my initial thinking when I put And then Simon had a similar question, which tipped the scales for me. So now I believe that we should support two styles
|
To me it reads as Maybe once I am trained to read |
@nomeata Prelude> let type = foo
<interactive>:1:5: error: parse error on input ‘type’ I see id type Int It's weird at first, but I think it is consistent: everything after a keyword is part of the "type". Even things like ($$) :: (forall (a :: Type) -> f a) -> forall (b :: Type) -> f b
f $$ type x = f type x Would original proposal require to write |
As a variant of your last example, what happens to
So here I see good points for both variants. Tricky. |
Yes, it's a different problem. We have
rather than
You could contemplate the consequences of adding the
We parse it as
So now imagine we extend
Suddenly the left-hand side of a type synonym looks like a naked TH splice, and that's hugely problematic. It's somewhat unsatisfactory to be constrained by the implementation here, and if someone is particularly motivated, perhaps they could find a way to work around this. But we don't have to do it now. To sum up, there are two design questions here
In its current form, the proposal is ambitious on the first point (using
And I will also admit that it's not a very important issue to me, as I do not plan to use the |
@nomeata Excellent example, and I find that your summary "tricky" is also a point in favor of simply requiring parentheses. We could spend a lot of time discussing this and trying to find the best option, then even more time trying to implement it, only to condemn our users to read code like this and say "tricky".
And let's not ignore this. It's a legitimate implementation concern. Our parser is LALR, conflicts like this are a burden. |
If we choose the option of requiring parentheses now does it allow us to defer a possible choice of precedence until later? |
Yes, I think so. One thing to keep in mind is that when faced with It's a corner case, but I'm aware of it and will account for it in the implementation. |
@int-index It looks like I don't understand what For example with non-visible type application: @(Int) on the top level doesn't make sense. Similarly, type Int as visible type-application on top-level shouldn't make any sense. The only way to interpret Continuing with non-visible type application: The only place where it makes sense is when parsing applications, i.e. foo @SomeType As far as I can understand, the new usage of foo (type SomeType) and there the Thus I don't even understand what The 281 proposal is about visible type application. I could understand the problems if goal was to allow embedding types into terms anyhere, and having foo $$ type Bar but not
as it can be undestood as However if we want to allow embedding types everywhere (for some later needs), that IMHO should be proposed separately, if nothing else, than to allow better reference. The proposal 281 does it somewhat sneakily. IMO some new special token (for sake of example However it does say:
It can be understood as "switching to as far left as parenthesizing allows" (like |
And a separate question, will it be allowed to write foo @(type Int) Why or why not? 281 doesn't have an example AFAICS. |
Somewhat unrelated, why And it the latter were allowed, would in part 2 not only (EDIT: IMHO nothing of that should work, and |
@phadej The
This is a valid call to
Now the
That's completely different from You are correct in your observation that
But this is the same problem as this:
Visible forall can function perfectly fine without |
None of what you wrote prevents making |
By "left" you probably mean "right", and yes, I did not touch on that because I was answering this part of your message:
I hope it is clear now that The way we parse this example is an arbitrary decision, my idea is to require explicit parenthesization as a conservative solution that avoids committing to any precedence. |
Partly. Currently it doesn't:
|
Yes. Section "7.1 Syntax" introduces the so-called "types in terms", including the function arrow. |
For reference, here's this PR version of 281: https://github.com/ghc-proposals/ghc-proposals/blob/cc6fe47e00b6106f11add1ed5f98b8e0be795195/proposals/0281-visible-forall.rst Properly reading it makes me more convinced that having 281 add Types-in-terms is conceptually a lot bigger change than |
Being able to use type namespace-bound identifiers but not types violates equational reasoning. IMO the proposal was right to propose both at once. |
The accepted proposal #378 introduces the Syntactic Unification Principle (SUP), it is well established by now that we want to support type-level syntax in terms and vice versa. So there is no question whether to have types-in-terms, the question is where, when, and how to specify them. In my opinion, #281 was a perfectly fine place to do that, as types-in-terms are useful in conjunction with visible forall.
No problem, you noticed it now. Is there something about this part of the proposal that you'd like to change? It's not too late to tweak the specification. My plan is to do implementation for GHC 9.10, we have plenty of time to discuss the finer points and propose small amendments like this one. |
This is not helpful comment.
It's not about that. This proposal process was meant to bring visibility to what changes are happening in GHC. This instance is a partial failure as far as I can say. But at the very least, amend the title to include types-as-terms. As I said, I see that as a lot bigger concrete language change than adding And please don't refer to proposals by just their numbers (like in the title of this one). |
I sympathize with this, proposal #281 has much more fundamental content than ”just” a new type binder, and thus I keep forgetting where types-in-terms has been introduced. But it does makes sense that it's in the first proposal that allows to make use of them, and was already mandated in a way by the overall plan for dependend types in #378. Anyone opposed of we add “and types in terms” to the title of #281 (text and PR), to make hovering the PR number more useful? It certainly would help me! |
@nomeata We need to find a better way to phrase this, as "Visible forall in types of terms and types in terms" is grammatically ambiguous. Is it "Visible forall in [types of terms and types in terms]" or "[Visible forall in types of terms] and [types in terms]"? We want the second interpretation to be clear. Maybe use a semicolon? Though it's not much better. I don't know. |
"Visible forall in types of terms, and types in terms"? |
Serial comma, classic. Yeah, I'm not opposed to that. |
Done |
Glad to see this issue resolved. Can we now return to the topic of |
My stance that I'd rather treat |
|
I'm not sure I understand. Expressions and patterns use the same grammar — we probably couldn't lose symmetry if we tried to. In fact, extending as far to the right as possible is achieved simply by using |
Ah, no, for some reason I was interpreting "as far to the right as possible" as essentially "to the end of the line", i.e. I was ignoring the "as possible" part |
@nomeata Let's submit this to the committee. |
This proposal has now been accepted. Thanks, all! |
The current grammar allows expressions like
Simon found it surprising during code review. It's better to require explicit parentheses:
So I propose we amend the grammar to use
atype
instead ofktype
. This also avoids a shift/reduce conflict in the parser, which is nice.