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

Amend 475 to use ghc-experimental for exports #603

Merged
merged 10 commits into from
Sep 18, 2023
127 changes: 78 additions & 49 deletions proposals/0475-tuple-syntax.rst
adamgundry marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Non-punning list and tuple syntax
.. ticket-url:: https://gitlab.haskell.org/ghc/ghc/-/issues/21294
.. implemented::
.. highlight:: haskell
.. header:: This proposal was `discussed at this pull request <https://github.com/ghc-proposals/ghc-proposals/pull/475>`_.
.. header:: This proposal was `discussed at this pull request <https://github.com/ghc-proposals/ghc-proposals/pull/475>`_ and an amendment at `this pull request <https://github.com/ghc-proposals/ghc-proposals/pull/603>`_.
.. contents::
.. sectnum::

Expand Down Expand Up @@ -63,18 +63,35 @@ variable in a bit of code. This allows us to e.g. refer to ``Tuple2`` and ``Tupl
Proposed Change Specification
-----------------------------

1. Create a new module in ``base`` called ``GHC.Prelude``. This module exports definitions
peculiar to GHC that are safe to use in ordinary code.
This module is *not* intended as a replacement to ``Prelude``,
but instead a complement to it. This module is a counterpart to ``GHC.Exts``, which exports
1. Create two new modules in ``ghc-experimental`` called ``Data.Tuple.Experimental``
and ``Data.Sum.Experimental``.
Since this new paradigm may evolve in response to users' experience, we want
to avoid committing to an API in ``base`` too early, and therefore choose the
new package as the home for the exports of the new entities.

Implementation note: Many type definitions will be "wired-in", defined in ``ghc-prim``,
and simply re-exported from ``ghc-experimental``.

#. Create a new module in ``ghc-experimental`` called ``Prelude.Experimental`` that
shall export definitions peculiar to GHC that are safe to use in ordinary code,
but whose API may evolve rapidly over subsequent releases.
This module is *not* intended as a replacement to ``Prelude``, but instead a
complement to it. This module is a counterpart to ``GHC.Exts``, which exports
many *unsafe* internals.
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhpas add

`Prelude.Experimental` simple re-exports the all the exports of `Data.Tuple.Experimental` and `Data.Sum.Experimental`, thus
   module Prelude.Experimental (
       module Data.Tuple.Experimental,
       module Data.Sum.Experimental
    ) where 
     import Data.Tuple.Experimental
    import Data.Sum.Experimental

Now you don't need to talk about `Prelude.Experimental` any futher.

In fact you could specify `Prelude.Experimental` as a separate bullet.


This proposal lists several definitions to be exported from ``GHC.Prelude``, but leaves other
definitions to be added in separate proposal(s).
For this proposal, ``Prelude.Experimental`` will re-export the entire contents
of ``Data.Tuple.Experimental`` and ``Data.Sum.Experimental`` as well as ``List``::

#. Export the following definitions from ``GHC.Tuple`` and ``GHC.Prelude``. (Implementation note:
These would probably end up in a new module ``GHC.Tuple.Prim``, due to the dependency from
the definitions below in ``GHC.Tuple`` on ``GHC.TypeLits``.) ::
module Prelude.Experimental (
List,
module Data.Tuple.Experimental,
module Data.Sum.Experimental,
) where
import GHC.Types (List)
import Data.Tuple.Experimental
import Data.Sum.Experimental

#. Export the following definitions from ``Data.Tuple.Experimental``::

data Unit = ()
data Solo a = MkSolo a -- this is a change from today's `data Solo a = Solo a`
Expand All @@ -94,8 +111,8 @@ Proposed Change Specification
-- ...
data Tuple64 ... = (...)

#. Export the following definitions from ``GHC.Exts`` and ``GHC.Prelude``. These replace
the existing tuple definitions (in ``GHC.Classes``) today. (Note that ``(...) =>`` is special syntax, and does not
#. Export the following definitions from ``Data.Tuple.Experimental``.
(Note that ``(...) =>`` is special syntax, and does not
construct tuples. See more on this point `below <#constraint-special-syntax>`_.)::

class CUnit
Expand All @@ -115,8 +132,8 @@ Proposed Change Specification
class (...) => CTuple64 ...
instance (...) => CTuple64 ...

#. Export the following pseudo-definitions from ``GHC.Exts``. (Implementation note:
These would likely be exported from ``GHC.Prim`` originally.) ::
#. Add the following pseudo-definitions to ``GHC.Types`` and export them from
``Data.Tuple.Experimental``::

type Unit# :: TYPE (TupleRep [])
data Unit# = (# #)
Expand All @@ -135,6 +152,9 @@ Proposed Change Specification
type Tuple64# :: TYPE r1 -> ... -> TYPE r64 -> TYPE (TupleRep [r1, ..., r64])
data Tuple64# ... = (# ... #)

#. Add the following pseudo-definitions to ``GHC.Types`` and export them from
``Data.Sum.Experimental``::

-- NB: There are no 0-sums or 1-sums in Haskell, today or tomorrow.

type Sum2# :: TYPE r1 -> TYPE r2 -> TYPE (SumRep [r1, r2])
Expand All @@ -148,9 +168,7 @@ Proposed Change Specification
type Sum64# :: TYPE r1 -> ... -> TYPE r64 -> TYPE (SumRep [r1, ..., r64])
data Sum64# ... = ...

#. Remove existing tuple definitions from ``GHC.Tuple``.

#. Export the following definitions from ``GHC.Tuple``::
#. Export the following definitions from ``Data.Tuple.Experimental``::

type Length :: List a -> Nat -- not exported
type family Length xs where
Expand Down Expand Up @@ -210,6 +228,8 @@ Proposed Change Specification
Tuple# (a, b, ..., bk, bl) = Tuple64# a b ... bk bl
Tuple# @reps _ = TypeError (ShowType (Length reps) :<>: Text " is too large; the maximum size of a tuple is 64.")

#. Export the following definitions from ``Data.Sum.Experimental``::

type Sum# :: forall (reps :: List RuntimeRep). TupleArgKind# reps -> TYPE (SumRep reps)
type family Sum# ts where
Sum# () = TypeError (Text "GHC does not support empty unboxed sums. Consider Data.Void.Void instead.")
Expand All @@ -224,7 +244,7 @@ Proposed Change Specification

data List a = [] | a : List a

#. Re-export ``List`` from ``GHC.List`` and ``GHC.Prelude``.
#. Re-export ``List`` from ``GHC.List``.

#. Introduce a new extension ``-XListTuplePuns``; this extension is part
of ``-XHaskell98``, ``-XHaskell2010``, and ``-XGHC2021``. It is thus on by default.
Expand All @@ -248,31 +268,31 @@ Proposed Change Specification
kind ``Constraint``, is
a synonym for ``GHC.Tuple.Tuple<n>`` ``ty1 ty2 ... ty<n-1> ty<n>``. (This rule retains today's behavior.)

#. With ``-XUnboxedTuples``, an occurrence of ``(# #)`` in type-syntax is a synonym for ``GHC.Exts.Unit#``.
#. With ``-XUnboxedTuples``, an occurrence of ``(# #)`` in type-syntax is a synonym for ``GHC.Types.Unit#``.

#. With ``-XUnboxedTuples``, an occurrence of ``(# ty #)`` in type-syntax is a synonym for ``GHC.Exts.Solo# ty``.
#. With ``-XUnboxedTuples``, an occurrence of ``(# ty #)`` in type-syntax is a synonym for ``GHC.Types.Solo# ty``.

#. With ``-XUnboxedTuples``, an occurrence of ``(#,,...,,#)`` where there are *n* commas (for *n* ≧ 1) in type-syntax
is a synonym for ``GHC.Exts.Tuple<n+1>#``.
is a synonym for ``GHC.Types.Tuple<n+1>#``.

#. With ``-XUnboxedTuples``, an occurrence of ``(# ty1, ty2, ... , ty<n-1>, ty<n> #)`` (for *n* ≧ 2) in type-syntax is a synonym
for ``GHC.Exts.Tuple<n># ty1 ty2 ... ty<n-1> ty<n>``.
for ``GHC.Types.Tuple<n># ty1 ty2 ... ty<n-1> ty<n>``.

#. With ``-XUnboxedSums``, an occurrence of ``(# | | ... | | #)`` where there are *n* pipes (for *n* ≧ 1) in type-syntax
is a synonym for ``GHC.Exts.Sum<n+1>#``.
is a synonym for ``GHC.Types.Sum<n+1>#``.

#. With ``-XUnboxedSums``, an occurrence of ``(# ty1 | ty2 | ... | ty<n-1> | ty<n> #)`` (for *n* ≧ 2) in type-syntax is a
synonym for ``GHC.Exts.Sum<n># ty1 ty2 ... ty<n-1> ty<n>``.
synonym for ``GHC.Types.Sum<n># ty1 ty2 ... ty<n-1> ty<n>``.

#. An occurrence of ``()`` in type-syntax, where the type is expected to be of kind ``Constraint``,
is a synonym for ``GHC.Tuple.CUnit``.
is a synonym for ``GHC.Classes.CUnit``.

#. An occurrence of ``(ty1, ty2, ..., ty<n-1>, ty<n>)`` (for *n* ≧ 2) in type-syntax, where the type is
expected to be of kind ``Constraint``, is a synonym for ``GHC.Tuple.CTuple<n> ty1 ty2 ... ty<n-1> ty<n>``.
expected to be of kind ``Constraint``, is a synonym for ``Data.Tuple.Experimental.CTuple<n> ty1 ty2 ... ty<n-1> ty<n>``.

#. An occurrence of ``(ty1, ty2, ..., ty<n-1>, ty<n>)`` (for *n* ≧ 2) in type-syntax, where the first
``ty<i>`` inferred to have kind ``Type`` or ``Constraint`` has kind ``Constraint``, is a synonym
for ``GHC.Tuple.CTuple<n> ty1 ty2 ... ty<n-1> ty<n>``.
for ``GHC.Classes.CTuple<n> ty1 ty2 ... ty<n-1> ty<n>``.

#. An unapplied occurrence of ``GHC.List.List`` is pretty-printed as ``[]``.

Expand All @@ -285,21 +305,21 @@ Proposed Change Specification
#. An occurrence of ``GHC.Tuple.Tuple<n>``, but not applied to a full *n* arguments, is pretty-printed as ``(,,...,,)``,
where there are *n-1* commas.

#. An occurrence of ``GHC.Exts.Unit#`` is pretty-printed as ``(# #)``.
#. An occurrence of ``GHC.Types.Unit#`` is pretty-printed as ``(# #)``.
Copy link
Contributor

Choose a reason for hiding this comment

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

We seemingly have GHC.Types.Unit# here, but GHC.Exts.Unit# elsewhere, and when Unit# is introduced it says it "would likely be exported from GHC.Prim originally". (And similarly for the other types.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

those should all have been changed to GHC.Types, I overlooked a few occurrences.
GHC.Prim is a virtual module, so my assumption is that Richard hadn't determined the precise module yet at the point of writing it.

The straightforward change would have been to use Data.Tuple.Experimental instead of GHC.Exts – I used GHC.Types because I now know what we landed on eventually…do you think that's too much retconning? We could also change the other sentence to say "would likely be exported from GHC.Types originally".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah no, there's no equivalent of GHC.Exts with the new schema…


#. An occurrence of ``GHC.Exts.Tuple<n># ty1 ty2 ... ty<n>`` is pretty-printed as ``(# ty1, ty2, ..., ty<n> #)``.
#. An occurrence of ``GHC.Types.Tuple<n># ty1 ty2 ... ty<n>`` is pretty-printed as ``(# ty1, ty2, ..., ty<n> #)``.

#. An occurrence of ``GHC.Exts.Tuple<n>#``, but not applied to a full *n* arguments, is pretty-printed as ``(#,,...,,#)``,
#. An occurrence of ``GHC.Types.Tuple<n>#``, but not applied to a full *n* arguments, is pretty-printed as ``(#,,...,,#)``,
where there are *n-1* commas.

#. An occurrence of ``GHC.Exts.Sum<n># ty1 ty2 ... ty<n>`` is pretty-printed as ``(# ty1 | ty2 | ... | ty<n> #)``.
#. An occurrence of ``GHC.Types.Sum<n># ty1 ty2 ... ty<n>`` is pretty-printed as ``(# ty1 | ty2 | ... | ty<n> #)``.

#. An occurrence of ``GHC.Exts.Sum<n>#``, but not applied to a full *n* arguments, is pretty-printed as ``(# | | ... | | #)``,
#. An occurrence of ``GHC.Types.Sum<n>#``, but not applied to a full *n* arguments, is pretty-printed as ``(# | | ... | | #)``,
where there are *n-1* pipes.

#. An occurrence of ``GHC.Tuple.CUnit`` is pretty-printed as ``()``.
#. An occurrence of ``GHC.Classes.CUnit`` is pretty-printed as ``()``.

#. An occurrence of ``GHC.Tuple.CTuple<n> ty1 ty2 ... ty<n>`` is pretty-printed as ``(ty1, ty2, ..., ty<n>)``.
#. An occurrence of ``GHC.Classes.CTuple<n> ty1 ty2 ... ty<n>`` is pretty-printed as ``(ty1, ty2, ..., ty<n>)``.

#. With ``-XNoListTuplePuns``:

Expand All @@ -312,11 +332,11 @@ Proposed Change Specification

#. An occurrence of ``GHC.Tuple.Tuple<n> ty1 ty2 ... ty<n>`` is pretty-printed as ``Tuple (ty1, ty2, ..., ty<n>)``.

#. An occurrence of ``GHC.Tuple.CTuple<n> ty1 ty2 ... ty<n>`` is pretty-printed as ``Constraints (ty1, ty2, ..., ty<n>)``.
#. An occurrence of ``GHC.Classes.CTuple<n> ty1 ty2 ... ty<n>`` is pretty-printed as ``Constraints (ty1, ty2, ..., ty<n>)``.

#. An occurrence of ``GHC.Exts.Tuple<n># ty1 ty2 ... ty<n>`` is pretty-printed as ``Tuple# (ty1, ty2, ..., ty<n>)``.
#. An occurrence of ``GHC.Types.Tuple<n># ty1 ty2 ... ty<n>`` is pretty-printed as ``Tuple# (ty1, ty2, ..., ty<n>)``.

#. An occurrence of ``GHC.Exts.Sum<n># ty1 ty2 ... ty<n>`` is pretty-printed as ``Sum# (ty1, ty2, ..., ty<n>)``.
#. An occurrence of ``GHC.Types.Sum<n># ty1 ty2 ... ty<n>`` is pretty-printed as ``Sum# (ty1, ty2, ..., ty<n>)``.

#. A use of ``'[ty1, ..., ty<n>]`` (for *n* ≧ 0) is now disallowed.

Expand All @@ -328,6 +348,27 @@ Proposed Change Specification

#. Three releases after this proposal is implemented, remove the ``Solo`` pattern synonym from ``GHC.Tuple``.

Proposed Library Change Specification
-------------------------------------

1. ``base``:

- ``GHC.List`` will export ``GHC.Types.List``.
The proposal and the implementation of the ``List`` part predate the
stability practice of introducing experimental entities in ``ghc-experimental``.

#. ``ghc-experimental``:

- ``Data.Tuple.Experimental`` will export all tuple-related entities.
- ``Data.Sum.Experimental`` will export all sum-related entities.
- ``Prelude.Experimental`` will export all of the above and ``List``.

#. ``ghc-prim``:

- ``GHC.Tuple`` will contain the new boxed tuple data declarations.
- ``GHC.Types`` will contain the new unboxed tuple and sum data declarations.
- ``GHC.Classes`` will contain the new constraint tuple class and instance declarations.

Effect and Interactions
-----------------------
1. With ``-XListTuplePuns`` (which is on by default), all programs that are accepted today continue
Expand Down Expand Up @@ -462,18 +503,6 @@ Alternatives
``-XNoListTuplePuns`` is not necessary to avoid punning, but is done only for
consistency. We could skip this, but I prefer keeping it as proposed.

#. There was an objection in the commentary about the name ``GHC.Prelude``. I continue
to like that name: the module exports basic definitions one will likely want when
using the GHC compiler for Haskell. However, an alternative might be
``GHC.SafeExts`` or something similar. (I'd actually rather have the safe extensions
be in ``GHC.Exts`` and the unsafe ones be in ``GHC.Exts.Unsafe``, but that ship has
sailed and is not worth calling back to port.)

Note that GHC itself already has a module named ``GHC.Prelude`` that would have to
be renamed if we keep ``GHC.Prelude`` as the choice for the new module in ``base``.
This is purely an implementation detail, though, and would not affect users (except
via the GHC API).

#. The following definitions were included in an earlier version of this proposal,
but the committee decided we were better without::

Expand Down