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 5 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: 87 additions & 35 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 @@ -158,32 +159,108 @@ 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
is must have an explicit equivalent that, regardless of the context, is unambiguously a binding site.
Ericson2314 marked this conversation as resolved.
Show resolved Hide resolved

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) case implicit ``@...``
Ericson2314 marked this conversation as resolved.
Show resolved Hide resolved

From `#425`_, `#448`_.

Lexical Scoping Principle (LSP)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. _`Lexical Scoping Principle`:

**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.
a. For every appearance of an identifier, 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 site, basically the same thing).

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.

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:

1. Template Haskell splices may need to be run before completing name resolution (and running those splices requires type-checking them).
#. Template Haskell splices may need to be run before completing name resolution (and running those splices requires type-checking them).

#. The `deprecated mechanism <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/exts/duplicate_record_fields.html#selector-functions>`_ for disambiguating duplicate record fields violates the `Lexical Scoping Principle`_ by requiring the type system.

#. In a pattern signature, if we have ``f (x :: Maybe a)``, the ``a``
is an occurrence if ``a`` is already in scope, and is implicitly bound otherwise.

2. The `deprecated mechanism <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/exts/duplicate_record_fields.html#selector-functions>`_ for disambiguating duplicate record fields violates the `Lexical Scoping Principle`_ by requiring the type system.
#. In a type signature, if we have ``f :: a -> a``, the ``a``
is an occurrence if ``a`` is already in scope, and it implicitly bound otherwise.
Ericson2314 marked this conversation as resolved.
Show resolved Hide resolved

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.
#. In a kind signature, if we have ``data Foo (a :: k)``, the ``k``
Ericson2314 marked this conversation as resolved.
Show resolved Hide resolved
is an occurrence if ``k`` is already in scope (historically impossible), and it implicitly bound otherwise.
Ericson2314 marked this conversation as resolved.
Show resolved Hide resolved

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
Technically this might be a violation of this principle as the ``k`` is in fact always a use with the implicit bind coming before,
but implicit foot-gun behavior

(the seemingly-unbound identifier in the type signature
is always an occurrence), but it's worth noting here.

*Motivation:* These principles mean that we can understand the binding
Expand All @@ -197,31 +274,6 @@ variables and imported term variables.

(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`_.

Contiguous Scoping Principle (CSP)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -296,4 +348,4 @@ advanced features even when writing simple code. In addition, the existence of a
down GHC even when those features are not active. Yet this principle is important to keep in mind going forward,
as we hope not to make the current situation worse.

From `#378`_, slightly generalized.
From `#378`_, slightly generalized.
9 changes: 9 additions & 0 deletions proposals/0425-decl-invis-binders.rst
Expand Up @@ -621,6 +621,15 @@ The proposed changes provide the programmer with a more principled way of
brining type variables into scope in certain corner cases, simplify arity
inference and scoping rules.

This gets us closer to upholding two principles:

- The `Explicit Binding Principle`_, because the new ``@``-binders is explicit unlike previous alternatives
Ericson2314 marked this conversation as resolved.
Show resolved Hide resolved

- The `Lexical Scoping Principle`_, because the new simplified rules about variables needing to occur on the LHS in certain situations.
Ericson2314 marked this conversation as resolved.
Show resolved Hide resolved

.. _`Explicit Binding Principle`: ../principles.rst#explicit-binding-principle
.. _`Lexical Scoping Principle`: ../principles.rst#lexical-scoping-principle

Costs and Drawbacks
-------------------

Expand Down