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
Clean up and simplify the treatment of implicit binding #532
base: master
Are you sure you want to change the base?
Changes from 28 commits
0a1269a
781a39a
5d4bd60
f07d9eb
0334f22
b20db07
e198d72
fd8c09d
2fee77a
4fd1cc3
fd9a254
b936b80
295f297
3acf93f
9ab6da7
93021f4
2ba8d2d
639e0d5
898151f
32fd7b6
b43c752
b347f85
df63606
2bd421f
57da8dc
8811e59
cf52f07
084d901
f2568b0
3079de1
002d686
4fe6730
462cdc5
8584f5f
7c0a98d
4556c0e
a34fa49
896dd74
640a445
868a8b7
7e8b858
e1d3bee
b824a66
d3bcca8
1ed93b9
ad5a84a
bd8a28e
a80cc45
c773b8a
f0ca5d9
2f0a342
f1426e3
0ce19ae
f2383fe
017196f
be556b8
a7ff219
1366216
6590983
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,6 +47,7 @@ Accepted principles | |
|
||
.. _`#281`: proposals/0281-visible-forall.rst | ||
.. _`#378`: proposals/0378-dependent-type-design.rst | ||
.. _`#425`: proposals/0425-decl-invis-binders.rst | ||
.. _`#448`: proposals/0448-type-variable-scoping.rst | ||
|
||
Syntax | ||
|
@@ -160,6 +161,71 @@ there is an absence of punning. | |
Name resolution and scoping | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Explicit Binding Principle (EBP) | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
.. _`Explicit Binding Principle`: | ||
|
||
**Principle**: | ||
Through the right combination of extensions, | ||
every implicit form of variable binding must have an explicit equivalent that, | ||
regardless of the context, | ||
is unambiguously a binding site. | ||
|
||
Examples: | ||
|
||
#. Problem:: | ||
|
||
-- Assume no `a` in scope | ||
|
||
id :: a -> a -- The variable `a` has no explicit binding site. | ||
|
||
Solution:: | ||
|
||
-- Assume no `a` in scope | ||
|
||
id :: forall a. a -> a -- The `a` in `forall a.` is an explicit binding site. | ||
|
||
This is provided by ``-XExplicitForAll``, which predates the GHC proposal process. | ||
|
||
#. Problem:: | ||
|
||
-- Assume no `a` in scope | ||
|
||
data Foo (a :: k) | ||
|
||
Solution:: | ||
|
||
data Foo @k (a :: k) | ||
|
||
This is provided by ``-XTypeAbstractions`` from `#425`_. | ||
|
||
#. Problem:: | ||
|
||
-- Assume no `b` in scope | ||
|
||
f :: (Bool, Bool) -> Bool | ||
f (x :: (b, b)) = ... -- The variable `b` has no implicit binding site. | ||
|
||
We could declare one or both of the ``b`` occurrences above a binding site, | ||
as was the historical interpretation of this, but that doesn't help as this | ||
syntax isn't unambiguously a binding site regardless of context (i.e. | ||
regardless of whether there is a ``b`` already in scope). | ||
|
||
*Motivation:* | ||
The `Explicit Binding Principle`_ allows programmers to control exactly how variables come into scope. | ||
It ensures all short-hands can be explained in terms of an explicit, unambiguous equivalent that is easier to understand at the cost of being more verbose: | ||
|
||
- Positive-position signatures' free vars cause implicit ``forall ... .`` | ||
|
||
- Negative position free vars cause different sorts of binding: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you include a code example illustrating the difference between negative and positive position free vars? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was a bit unsure about to what extent to include examples in the proposed change spec. |
||
|
||
- Signatures on term patterns (pattern signatures) cause implicit ``let type ... = _ in`` | ||
|
||
- Signatures on type variables (kind signatures) cause implicit ``@...`` | ||
|
||
From `#425`_, `#448`_. | ||
|
||
Lexical Scoping Principle (LSP) | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
|
@@ -168,10 +234,17 @@ Lexical Scoping Principle (LSP) | |
**Principle**: | ||
|
||
a. For every appearance of an identifier, | ||
it is possible to determine whether that appearance is a *binding site* or an *occurrence* without examining the context. | ||
it is possible to determine whether that appearance is a mere *occurrence*, | ||
and thus must be bound elsewhere for the program to be valid, | ||
or the variable is a *binding site* (or causes an implicit binding, which is close enough), | ||
without examining the context. | ||
|
||
b. For every *occurrence* of an identifier, | ||
it is possible to uniquely identify its *binding site*, without involving the type system. | ||
it is possible to uniquely identify its *binding site*, without involving the type system. | ||
|
||
This builds upon the `Explicit Binding Principle`_: | ||
whereas that former principle ensures that explicit alternatives to implicit binding constructs *exist at all*, | ||
this latter principle makes those explicit alternatives *compulsory*, because we must not have implicit binding in order to uphold this principle. | ||
|
||
The `Lexical Scoping Principle`_ is almost true today, with the following nuances: | ||
|
||
|
@@ -182,12 +255,17 @@ The `Lexical Scoping Principle`_ is almost true today, with the following nuance | |
3. In a pattern signature, | ||
if we have ``f (x :: Maybe a)``, | ||
the ``a`` is an occurrence if ``a`` is already in scope, | ||
and it is a binding site otherwise. | ||
and is implicitly bound otherwise. | ||
Comment on lines
-185
to
+258
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand this. A pattern-signature binding is a perfectly explicit binding. The original phrase was accurate in this respect. You may argue that this is not where you would like the binding to be (in fact, I believe that it's what you are doing). But this is not something that ought to be discussed in the principles. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See both replies below. I don't mind putting it back the way it was, but I do think it's important for us deliberating the proposal to understand that even if isn't an "implicit binding", it is a violation of the Explicit Binding Principle because it is not explicit and unambiguous. (By which I mean the context doesn't matter as to whether it's a binding or not.) Would it be better to rename this the Explicit and Unambiguous Binding Principle, or the Context-free Binding Principle? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I must register here that your proposal makes the bindings more confusing to me than they currently are. You are free to stick to your guns there, it will however colour my recommendation. To me the context-freeness was the purview of the lexical binding principle; while the presence of a binding site in the text was the domain of the explicit binding principle. You're making the distinction less clear to me, I can't quite understand your point of view yet. I may very well be missing something. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let me just recap your position as I understand it:
If pattern signatures binds really are a perfectly good explicit binding, then it doesn't make sense that So if you really want, I will relent and revert the principles changes in the interest of getting something done, but based on the above I hope it is clear why the amended proposal with the original principles feels shaky to me. Even if you prefer not changing the proposals, I worry about how the rest of the committee would react. Ultimately, I don't really care what the names are, consider my proposal here subject to alpha equivalence. (That is why I bring up "contextual" vs "implicit".) I just want the principles and design decisions to live in harmony. Also, I suspect you view might view the principles as a sort of append-only log, whereas I view the principles as a "living document" in which shuffling them around is a perfectly normal thing to do whether one is amending an existing proposal or writing a new proposal from scratch. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
My personal opinion on whether I agree with the change is insubstantial, honestly. This is why we have a committee. My first job as a shepherd is make sure that the proposal is clear and consistent. It is.
I'd even say that it's factually incorrect. It doesn't mean that they're not a bad idea though.
My point is that the principles already did this. But you can stick to your guns, let's see what the rest of the committee says. I'll be submitting for committee discussion now: I really should have done this last week as I'll be on holiday for the 3 next weeks and won't be checking my emails. The committee's decision will most likely be in January. I'm really sorry about this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK sounds good. Basically I don't want to be so stubborn that the principles changes sink the rest of the proposal. I take it you are saying the Lexical Scoping Principle covers this case today (I agree actually), so then should the extension be called Enjoy your vacation! |
||
|
||
4. In a type signature, | ||
if we have ``f :: a -> a``, | ||
the ``a`` is an occurrence if ``a`` is already in scope, | ||
and is implicitly bound otherwise. | ||
|
||
4. In a type signature, any out-of-scope variable is implicitly bound. | ||
This is not technically a violation of this principle | ||
(the seemingly-unbound identifier in the type signature is always an occurrence), | ||
but it's worth noting here. | ||
#. In a kind signature, | ||
if we have ``data Foo (a :: k)``, | ||
the ``k`` is an occurrence if ``k`` is already in scope, | ||
and is implicitly bound otherwise. | ||
|
||
*Motivation:* | ||
These principles mean that we can understand the binding structure of a program without relying on type inference, | ||
|
@@ -198,31 +276,11 @@ This last point becomes even more poignant if we consider the possibility of mix | |
\(a) from `#448`_; | ||
\(b) from `#378`_. | ||
|
||
Explicit Binding Principle (EBP) | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
.. _`Explicit Binding Principle`: | ||
|
||
**Principle**: | ||
Through the right combination of extensions and/or warning flags, | ||
it is possible for a Haskell programmer to ensure that all identifiers in a program have an explicit binding site. | ||
|
||
Examples:: | ||
|
||
id :: a -> a -- the variable `a` has no explicit binding site, but we can write `forall a.` to provide one | ||
|
||
f :: (Bool, Bool) -> Bool | ||
f (x :: (b, b)) = ... -- the variable `b` is bound to `Bool` by this | ||
-- pattern signature. But either the first b is a binding | ||
-- site, in violation of the Lexical Scoping Principle (a), | ||
-- or there is no explicit binding site, in violation of | ||
-- the Explicit Binding Principle. | ||
|
||
*Motivation:* | ||
The `Explicit Binding Principle`_ allows programmers to control exactly how variables come into scope. | ||
It also prevents the possibility of typos that accidentally introduce new variables. | ||
|
||
From `#448`_. | ||
Here is one more recent historical historical example: | ||
Prior to `#425`_, if we had ``type T1 = 'Nothing :: Maybe a``, | ||
the ``a`` was an occurence if ``a`` is already in scope, | ||
and was implicity bound otherwise. | ||
But since `#425`_ it is never implicitly bound. | ||
|
||
Contiguous Scoping Principle (CSP) | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I must confess: I'm not able to understand how this new text changes the meaning of the principle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The key part is "regardless of the context, is unambiguously a binding site."
I agree actually that whether pattern signature binds are implicit or not is a squishy matter of opinion. So I am trying to step back say it is might be explicit but it is not explicit and unambiguous.
I think explicit and unambiguous is a more objective standard: the syntax needs to mean one thing, regardless of context. Pattern signature binds do not meet that standard.