Syntax for visible dependent quantification#81
Conversation
|
Not so much a comment as a lament: I see two type parameters that are not the same, albeit they are related. So Also BTW, what can I put as a data constructor on RHS of that You kindaholics keep telling me that with Why aren't there two kind parameters for the kind of |
|
@AntC2 suggests that the declaration And, while I'd like |
|
Thanks @goldfirere, let's take a step back. For that declaration of
The distinction you draw above between having kind Why not In ? |
|
Perhaps another way of phrasing @AntC2's question is: are the following two forms equivalent? (And moreover, will GHC parse both forms under this proposal?)
I would intuitively expect them to be the same, since dependently typed languages like Idris use a similar syntax (in Idris, it would be |
|
I'm in favour of the original proposal. @RyanGlScott the I suspect some of the confusion stems from the fact that in "traditional" Haskell, the
When giving the kind of a type:
The point of this proposal is to start teasing these distinctions apart, so we can use "visible" quantification in kinds while leaving everything else alone. I hope that one day we'll gain access to this in the types of terms as well. 😉 |
|
Thanks @RyanGlScott for trying to help. My question is really: what's happened to the If your two forms are parsed and equivalent (thanks @adamgundry), and/or @goldfirere's distinction about having vs. being, then how about these?:
|
|
@AntC2, let's perhaps approach understanding the new form by relating it to something that's existed in Haskell from the beginning, polymorphism. Witness With this definition, we can say Now, let's add If I use visible type applications, then I can say The only difference between Now, calls would look like Returning back to this proposal, our Other points raised above:
I hope this all helps! |
|
Those people who stand high enough on shoulder’s to see into the Dependent Haskell future: Does this proposed syntax line up for eventual visible dependent parameters that are not kinds? |
|
@nomeata that specific example would need a relevant binder: |
|
So basically |
|
@nomeata visibility and parametricity/relevancy are orthogonal. |
|
Thank you @goldfirere for that explanation via polymorphism and visible I should have said at the outset: I'm +1 that if there's a kind GHC infers, but you can't declare in source, that is "just plain silly". So we need a new bikeshed; the only question is the colour. Like @nomeata, I'm wondering if we need to anticipate how the signatures are going to look for dependent types? Is this binding like a big-pi or big-lambda (as you might use for polymorphism)? I notice they both still use the What's the inferred kind with And in what order do I supply the kind/type parameters? What if I want to use visible
|
|
I am +1 on this proposal. For those interested in where this fits on the road to dependent haskell, it's only necessary to read chapter 4 of Richard's thesis, which is extremely approachable even for a lay person like myself. The chapter concludes with this table (I've removed the matchable quantifiers since they aren't relevant to this discussion):
To address @nomeata's question a little more, |
|
Thanks, @andrewthad, for posting that table. I hope that resolves many of the questions above. As for @AntC2's example: if we have As another specific answer to a specific question: |
It's adding to the confusion. Is this a proposal to tweak a bit of syntax for a kind GHC already infers? Or is this a proposal to adopt the whole of the syntax in @goldfirere's thesis? (I'm not saying that's a bad thing, but let's get straight what we're discussing.) There's already proposals (currently in abeyance) for the matchable vs unmatchable arrows. Had we better make sure this also integrates with whatever is the syntax for linear types (another under-the-radar proposal)? Do we have to support both matchable and unmatchable lollipops for both dependent and non-dependent types/kinds that are either relevant or irrelevant and/or in/visible?
Uh-oh. Curly braces. Is that some innovation I missed? I'm -1 on this proposed syntax. When I see |
|
I think we should have syntax to write down kinds like this. As to concrete syntax I'm fairly relaxed. Options on the table appear to be
Any others? The nice thing about |
|
Richard's thesis suggests that one day all of these would be valid: Currently, only |
Yes
No The title is "visible dependent quantification". That exactly corresponds to one row, but just one row, of the table, as @andrewthad points out.
Matchability is yet another axis of variation, and one unmentioned in this proposal. It's not relevant here.
Squigly and lollipop indeed don't get along well, but matchability and squigly are immaterial to this proposal. The arrow in
That's just indicating that the quantification is inferred. Not sure if it's just informal syntax or something ghci might already print out.
Yes in that all quantification in System-F is visible, and ∀-quantification (introduced by Λ) is irrelevant. |
|
@andrewthad and @Ericson2314 very much have the right idea. Thanks for your posts. Let me add my own small points to theirs:
|
Then should that syntax be accepted? Can we tack it on to this proposal; and with the same motivation:
|
Then what varieties of syntax constructs do those languages use to express them? Do they use both If kind-polymorphic datatypes are "really Pi-quantified, not forall-quantified", why isn't this proposal for Pi-quantified? There's no historical inaccuracy (yet), because I kinda suspect the answer is going to be: because that's not what's in @goldfirere's thesis. Then the claim that this proposal is about "just one row, of the table" is bogus. If this syntax gets accepted for dependent kinds, it'll be fait accompli for function type signatures. What worries me is not providing a succinct syntax to suit yous brain-the-size-of-a-planet dependent type-acrobats; but the newbie who makes a typo (for example missing out a |
There's no need for backhanded compliments. To address one of your concerns, the error messages would actually be better if GHC admitted the dependent irrelevant visible quantifier. Here's a more simple version of the example you gave: In GHC 8.2, the error we get is: The parser simple cannot handle this. But, if the parser could recognize it, then the error could come from a later stage (possibly the type checker although I'm really fuzzy on where this would actually happen). We could then have an error like this: The error message can actually provide instruction on how to fix the problem, which it doesn't currently do.
To make the visible/invisible distinction, agda uses curly braces. It uses the function arrow regardless of whether the type variable is visible. Idris is similar is that it always uses an arrow and uses curly braces to handle visibility. For example: To be more like other dependently typed language, haskell could use curly braces to make type variables invisible. But, that would be strange since we already have syntax for doing this. Richard's thesis takes this into account, preserving our existing syntax for invisible type variable while introducing a new syntax for visible type variables that (a) does not break any currently compiling code and (b) is very consistent with the way other languages handle this. That's why I'm in favor of this syntax. |
There's a really easy solution: just make a beginner mode that doesn't mention non-whitelisted extensions. As @andrewthad mentions, being able to parse this will still help the error message: in this mode, it can simply be "please replace (Off topic) I really find these education-vs-advanced-users debates extremely unproductive. Obviously there's no way to have a single language that suits everyone's needs! But, there's no reason GHC can't simultaneously implement all the langauges needed to cover that (such that they can import one another). The Racket people, who have actually studied CS education empirically, have been doing this for years. |
|
The curly-brace syntax indeed should be accepted. And a collaborator of mine should be posting a proposal to that effect in short order. I don't think the change belongs here. There already is historical inaccuracy. I can say |
|
Conversation seems to have died down here. I believe this proposal is ready to submit to the committee, @nomeata. The long conversation above did not result in any changes to the proposal. It is essentially a Q&A session... but as every reader will have their own questions, I don't think any of it needs to be put in the proposal itself. A committee member may choose to skim through the commentary to see if a question they have is addressed. In particular, I want to publicly express my gratitude to @adamgundry, @andrewthad, and @Ericson2314 for helping to explain aspects of this proposal -- I fully agree with all of their statements above. |
Surely there isn't a fundamental reason why terms couldn't have visible dependent quantification? Is this just to limit the scope of the proposal? |
I shall refer you to the second paragraph of your own comment #81 (comment), where you ask to consider this proposal in isolation 😃 When we consider
I don't think that it's even a problem worth solving for the time being, even adding There are several reasons I would like to incorporate
In many APIs using
I am not sure, but perhaps this could also allow eta-reduction of type-abstracted terms? |
|
@int-index You make good arguments, but you're suggesting a fundamental change to this proposal: the proposal as is discusses adding concrete syntax for an already-existing feature. You're describing a brand new feature (with plausible syntax). While I would find such a proposal interesting and perhaps compelling, I don't wish to tie the much more basic proposal here with this grand new idea. |
|
Okay, but can you tell how much work adding this check implies?
If it's a trivial check then it makes sense to postpone handling this case for later, in a separate proposal. If it'll require non-trivial changes to the compiler, it would be a shame to introduce them just to rip them off later (maybe in the same release, if I manage to get the |
|
The check (now more fully described) would be quite easy to implement. GHC already does what it calls "validity checking", and prohibiting Also of note is that I have posted #102, by request of the committee, which describes a broader approach to quantifiers in (Dependent) Haskell. I believe this proposal stands alone, but the committee wanted to see where this is all going, and #102 gives a sketch. |
Could we have an example of rejected behaviour for each of these bullet point. In a similar fashion, are there examples where we could use either |
|
I've added the examples as requested. |
aspiwack
left a comment
There was a problem hiding this comment.
Wow! This was swift! (and very helpful!)
I don't actually understand why it must be forbidden in types-of-terms.
Other than that, I think this proposal is quite solid
|
|
||
| foo :: TypeRepV (Type -> Type) a -> ... | ||
|
|
||
| and GHC would easily infer that ``a`` should have kind ``Type -> Type``. |
There was a problem hiding this comment.
Add something like:
In contrast, with TypeRep where foo would be written as
foo :: TypeRep a -> …|
The proposal says
But that radically under-specifies what is intended for GADT declarations. Remember that GADT data constructors have their own declaration syntax, involving bangs and record fields for example. So with dependent forall, which of these are OK? Perhaps we should simply strike out this line of the proposal, leaving it open to do something a bit more ambitious for later. |
|
See #393. |
This strikes a small piece of #81 that was never implemented and deserves more careful study than this proposal gives it.
The proposal has been accepted; the following discussion is mostly of historic interest.
This proposes a concrete syntax for a kind that has existed since GHC 8.0, but cannot currently be parsed.
Rendered