Skip to content
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

Draft
wants to merge 59 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
0a1269a
Clean up and simplify the treatment of implicit binding
Ericson2314 Nov 28, 2021
781a39a
principles: Fix reST
Ericson2314 Aug 14, 2022
5d4bd60
532: Copy template
Ericson2314 Aug 14, 2022
f07d9eb
532: Add meta-proposal
Ericson2314 Aug 14, 2022
0334f22
523 Fix typo
Ericson2314 Aug 15, 2022
b20db07
448: Improve flow for pattern signatures and binding motivation
Ericson2314 Aug 15, 2022
e198d72
523: Fix typo
Ericson2314 Aug 15, 2022
fd8c09d
Apply suggestions fixing typos from code review
Ericson2314 Aug 15, 2022
2fee77a
Fix typo in principles.rst
Ericson2314 Aug 15, 2022
4fd1cc3
Update proposals/0448-type-variable-scoping.rst
Ericson2314 Aug 15, 2022
fd9a254
532: Replace "arity" with something more clear
Ericson2314 Aug 15, 2022
b936b80
Fix typos
Ericson2314 Aug 22, 2022
295f297
532: Fix typo
Ericson2314 Aug 22, 2022
3acf93f
Fix formatting
nomeata Aug 23, 2022
9ab6da7
Actually we did get rid of `-XPatternSignatureBinds`
Ericson2314 Nov 16, 2022
93021f4
532: Connect principles to practical changes
Ericson2314 Nov 16, 2022
2ba8d2d
Merge branch 'type-variables-reformat' into type-variables-2
Ericson2314 Nov 16, 2022
639e0d5
Add missing link
Ericson2314 Nov 16, 2022
898151f
Merge remote-tracking branch 'upstream/master' into type-variables
Ericson2314 Nov 16, 2022
32fd7b6
532: Fix typos
Ericson2314 Nov 26, 2022
b43c752
principles: Shrink diff in one place
Ericson2314 Nov 29, 2022
b347f85
425, principles: Revert link from 425 to the principles
Ericson2314 Nov 29, 2022
df63606
Apply suggestions from code review
Ericson2314 Nov 29, 2022
2bd421f
532: Make sure other proposals are linked
Ericson2314 Nov 29, 2022
57da8dc
448: Fix reflow to match master
Ericson2314 Nov 29, 2022
8811e59
Add examples to rest of `-XImplicitBinds` in proposal
Ericson2314 Nov 29, 2022
cf52f07
532: Demonstrate the #270 interaction with example
Ericson2314 Nov 29, 2022
084d901
448: Demonstrate the ``-XKindSignatures`` ret-con
Ericson2314 Nov 29, 2022
f2568b0
448: Expand on iteraction between `-XNoImplicitBinds` and `-Wpuns`
Ericson2314 Dec 4, 2022
3079de1
448: Fix typo
Ericson2314 Dec 13, 2022
002d686
532: Fix links
Ericson2314 Jan 5, 2023
4fe6730
Merge remote-tracking branch 'upstream/master' into type-variables
Ericson2314 Jan 5, 2023
462cdc5
532: No more changes to 425
Ericson2314 Jan 5, 2023
8584f5f
448: Remove a trailing space
Ericson2314 Jan 5, 2023
7c0a98d
523: Add an explicit summary list of changes
Ericson2314 Jan 5, 2023
4556c0e
448: Fix stray line breaks
Ericson2314 Jan 5, 2023
a34fa49
Merge remote-tracking branch 'upstream/master' into type-variables
Ericson2314 May 24, 2023
896dd74
Merge branch 'master' into type-variables
Ericson2314 Jul 12, 2023
640a445
Narrower `-XPatternSignatures` instead of `-Wpattern-signature-binds`
Ericson2314 Jul 12, 2023
868a8b7
Add SPJ's comment from #523
Ericson2314 Jul 12, 2023
7e8b858
Merge branch 'pattern-signatures-without-binds' into type-variables
Ericson2314 Jul 12, 2023
e1d3bee
Merge branch 'no-imply-type-abstractions' into pattern-signatures-wit…
Ericson2314 Jul 25, 2023
b824a66
Merge branch 'pattern-signatures-without-binds' into type-variables
Ericson2314 Jul 25, 2023
d3bcca8
Merge branch 'no-imply-type-abstractions' into pattern-signatures-wit…
Ericson2314 Aug 2, 2023
1ed93b9
Merge remote-tracking branch 'upstream/master' into pattern-signature…
Ericson2314 Aug 2, 2023
ad5a84a
Merge branch 'pattern-signatures-without-binds' into type-variables
Ericson2314 Aug 2, 2023
bd8a28e
Word-smithing
Ericson2314 Aug 3, 2023
a80cc45
Do not mention `-XImplicitBinds`
Ericson2314 Aug 3, 2023
c773b8a
Merge branch 'pattern-signatures-without-binds' (early part) into typ…
Ericson2314 Aug 3, 2023
f0ca5d9
Merge branch 'pattern-signatures-without-binds' into type-variables
Ericson2314 Aug 3, 2023
2f0a342
Revert "Do not mention `-XImplicitBinds`"
Ericson2314 Aug 3, 2023
f1426e3
Add examples
Ericson2314 Aug 3, 2023
0ce19ae
608: Fix type errors in quoted comment
Ericson2314 Aug 12, 2023
f2383fe
Merge branch 'pattern-signatures-without-binds' into type-variables
Ericson2314 Aug 12, 2023
017196f
Fix typos
Ericson2314 Aug 30, 2023
be556b8
Merge remote-tracking branch 'upstream/master' into pattern-signature…
Ericson2314 Oct 3, 2023
a7ff219
Merge branch 'pattern-signatures-without-binds' into type-variables
Ericson2314 Oct 3, 2023
1366216
Discuss interaction with #281 and implicit binding more clearly
Ericson2314 Oct 10, 2023
6590983
Merge branch 'pattern-signatures-without-binds' into type-variables
Ericson2314 Oct 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
122 changes: 90 additions & 32 deletions principles.rst
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Comment on lines +169 to +173
Copy link
Contributor

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.

Copy link
Contributor Author

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.


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:
Copy link
Contributor

Choose a reason for hiding this comment

The 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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand All @@ -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:

Expand All @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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?

Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me just recap your position as I understand it:

  • Substantive changes seem mostly fine
    • substantive changes include -XImplicitBinds enabling pattern signature binds.
  • Characterizing pattern signature binds as implicit binds seems bad or at least unnecessarily opinionated.
  • Principles changes seem gratuitous
    • Principles changes are trying to demonstrate how pattern signature binds are dubious in the same way as the others.

If pattern signatures binds really are a perfectly good explicit binding, then it doesn't make sense that -XImplicitBinds would be required to use them! On the other hand if they are a dubvious implicit/contextual binding, then it does make sense that -XImplictlBinds/-XContextualBinds is a requirement to use them.

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.

Copy link
Contributor

@aspiwack aspiwack Dec 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Substantive changes seem mostly fine

  • substantive changes include -XImplicitBinds enabling pattern signature binds.

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.

Characterizing pattern signature binds as implicit binds seems bad or at least unnecessarily opinionated.

I'd even say that it's factually incorrect. It doesn't mean that they're not a bad idea though.

Principles changes seem gratuitous

  • Principles changes are trying to demonstrate how pattern signature binds are dubious in the same way as the others.

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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 -XNonLexicalBinds or -XLexicalBinds? I'll go with the flow on whatever the committee wants re naming.

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,
Expand All @@ -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)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down