summaryrefslogtreecommitdiff
path: root/docs/users_guide
diff options
context:
space:
mode:
authorRichard Eisenberg <rae@cs.brynmawr.edu>2016-12-14 21:37:43 -0500
committerRichard Eisenberg <rae@cs.brynmawr.edu>2017-01-19 10:31:52 -0500
commite7985ed23ddc68b6a2e4af753578dc1d9e8ab4c9 (patch)
treeba8c4016e218710f8165db92d4b4c10e5559245a /docs/users_guide
parent38374caa9d6e1373d1b9d335d0f99f3664931fd9 (diff)
downloadhaskell-e7985ed23ddc68b6a2e4af753578dc1d9e8ab4c9.tar.gz
Update levity polymorphism
This commit implements the proposal in https://github.com/ghc-proposals/ghc-proposals/pull/29 and https://github.com/ghc-proposals/ghc-proposals/pull/35. Here are some of the pieces of that proposal: * Some of RuntimeRep's constructors have been shortened. * TupleRep and SumRep are now parameterized over a list of RuntimeReps. * This means that two types with the same kind surely have the same representation. Previously, all unboxed tuples had the same kind, and thus the fact above was false. * RepType.typePrimRep and friends now return a *list* of PrimReps. These functions can now work successfully on unboxed tuples. This change is necessary because we allow abstraction over unboxed tuple types and so cannot always handle unboxed tuples specially as we did before. * We sometimes have to create an Id from a PrimRep. I thus split PtrRep * into LiftedRep and UnliftedRep, so that the created Ids have the right strictness. * The RepType.RepType type was removed, as it didn't seem to help with * much. * The RepType.repType function is also removed, in favor of typePrimRep. * I have waffled a good deal on whether or not to keep VoidRep in TyCon.PrimRep. In the end, I decided to keep it there. PrimRep is *not* represented in RuntimeRep, and typePrimRep will never return a list including VoidRep. But it's handy to have in, e.g., ByteCodeGen and friends. I can imagine another design choice where we have a PrimRepV type that is PrimRep with an extra constructor. That seemed to be a heavier design, though, and I'm not sure what the benefit would be. * The last, unused vestiges of # (unliftedTypeKind) have been removed. * There were several pretty-printing bugs that this change exposed; * these are fixed. * We previously checked for levity polymorphism in the types of binders. * But we also must exclude levity polymorphism in function arguments. This is hard to check for, requiring a good deal of care in the desugarer. See Note [Levity polymorphism checking] in DsMonad. * In order to efficiently check for levity polymorphism in functions, it * was necessary to add a new bit of IdInfo. See Note [Levity info] in IdInfo. * It is now safe for unlifted types to be unsaturated in Core. Core Lint * is updated accordingly. * We can only know strictness after zonking, so several checks around * strictness in the type-checker (checkStrictBinds, the check for unlifted variables under a ~ pattern) have been moved to the desugarer. * Along the way, I improved the treatment of unlifted vs. banged * bindings. See Note [Strict binds checks] in DsBinds and #13075. * Now that we print type-checked source, we must be careful to print * ConLikes correctly. This is facilitated by a new HsConLikeOut constructor to HsExpr. Particularly troublesome are unlifted pattern synonyms that get an extra void# argument. * Includes a submodule update for haddock, getting rid of #. * New testcases: typecheck/should_fail/StrictBinds typecheck/should_fail/T12973 typecheck/should_run/StrictPats typecheck/should_run/T12809 typecheck/should_fail/T13105 patsyn/should_fail/UnliftedPSBind typecheck/should_fail/LevPolyBounded typecheck/should_compile/T12987 typecheck/should_compile/T11736 * Fixed tickets: #12809 #12973 #11736 #13075 #12987 * This also adds a test case for #13105. This test case is * "compile_fail" and succeeds, because I want the testsuite to monitor the error message. When #13105 is fixed, the test case will compile cleanly.
Diffstat (limited to 'docs/users_guide')
-rw-r--r--docs/users_guide/glasgow_exts.rst79
-rw-r--r--docs/users_guide/using-warnings.rst7
-rw-r--r--docs/users_guide/using.rst2
3 files changed, 46 insertions, 42 deletions
diff --git a/docs/users_guide/glasgow_exts.rst b/docs/users_guide/glasgow_exts.rst
index 103d6ac93d..52163b976f 100644
--- a/docs/users_guide/glasgow_exts.rst
+++ b/docs/users_guide/glasgow_exts.rst
@@ -175,8 +175,9 @@ There are some restrictions on the use of primitive types:
binding.
- You may bind unboxed variables in a (non-recursive, non-top-level)
- pattern binding, but you must make any such pattern-match strict. For
- example, rather than:
+ pattern binding, but you must make any such pattern-match strict.
+ (Failing to do so emits a warning :ghc-flag:`-Wunbanged-strict-patterns`.)
+ For example, rather than:
::
@@ -227,10 +228,6 @@ unnecessary allocation during sequences of operations.
There are some restrictions on the use of unboxed tuples:
-- Values of unboxed tuple types are subject to the same restrictions as
- other unboxed types; i.e. they may not be stored in polymorphic data
- structures or passed to polymorphic functions.
-
- The typical use of unboxed tuples is simply to return multiple
values, binding those multiple results with a ``case`` expression,
thus:
@@ -8015,47 +8012,42 @@ these flags, especially :ghc-flag:`-fprint-explicit-kinds`.
.. index::
single: TYPE
- single: representation polymorphism
+ single: levity polymorphism
.. _runtime-rep:
-Runtime representation polymorphism
-===================================
+Levity polymorphism
+===================
In order to allow full flexibility in how kinds are used, it is necessary
to use the kind system to differentiate between boxed, lifted types
(normal, everyday types like ``Int`` and ``[Bool]``) and unboxed, primitive
-types (:ref:`primitives`) like ``Int#``. We thus have so-called representation
+types (:ref:`primitives`) like ``Int#``. We thus have so-called levity
polymorphism.
-.. note::
- For quite some time, this idea was known as *levity* polymorphism, when
- it differentiated between only lifted and unlifted types. Now that it
- differentiates between any runtime representations, the name has been
- changed. But anything you've read or heard about levity polymorphism
- likely applies to the story told here -- this is just a small generalisation.
-
Here are the key definitions, all available from ``GHC.Exts``: ::
TYPE :: RuntimeRep -> * -- highly magical, built into GHC
- data RuntimeRep = PtrRepLifted -- for things like `Int`
- | PtrRepUnlifted -- for things like `Array#`
- | IntRep -- for things like `Int#`
+ data RuntimeRep = LiftedRep -- for things like `Int`
+ | UnliftedRep -- for things like `Array#`
+ | IntRep -- for `Int#`
+ | TupleRep [RuntimeRep] -- unboxed tuples, indexed by the representations of the elements
+ | SumRep [RuntimeRep] -- unboxed sums, indexed by the representations of the disjuncts
| ...
- type * = TYPE PtrRepLifted -- * is just an ordinary type synonym
+ type * = TYPE LiftedRep -- * is just an ordinary type synonym
The idea is that we have a new fundamental type constant ``TYPE``, which
is parameterised by a ``RuntimeRep``. We thus get ``Int# :: TYPE 'IntRep``
-and ``Bool :: TYPE 'PtrRepLifted``. Anything with a type of the form
+and ``Bool :: TYPE 'LiftedRep``. Anything with a type of the form
``TYPE x`` can appear to either side of a function arrow ``->``. We can
thus say that ``->`` has type
-``TYPE r1 -> TYPE r2 -> TYPE 'PtrRepLifted``. The result is always lifted
+``TYPE r1 -> TYPE r2 -> TYPE 'LiftedRep``. The result is always lifted
because all functions are lifted in GHC.
-No representation-polymorphic variables
----------------------------------------
+No levity-polymorphic variables or arguments
+--------------------------------------------
If GHC didn't have to compile programs that run in the real world, that
would be the end of the story. But representation polymorphism can cause
@@ -8072,10 +8064,10 @@ In particular, when we call ``bad``, we must somehow pass ``x`` into
``bad``. How wide (that is, how many bits) is ``x``? Is it a pointer?
What kind of register (floating-point or integral) should ``x`` go in?
It's all impossible to say, because ``x``'s type, ``TYPE r2`` is
-representation polymorphic. We thus forbid such constructions, via the
+levity polymorphic. We thus forbid such constructions, via the
following straightforward rule:
- No variable may have a representation-polymorphic type.
+ No variable may have a levity-polymorphic type.
This eliminates ``bad`` because the variable ``x`` would have a
representation-polymorphic type.
@@ -8086,15 +8078,20 @@ However, not all is lost. We can still do this: ::
(a -> b) -> a -> b
f $ x = f x
-Here, only ``b`` is representation polymorphic. There are no variables
-with a representation polymorphic type. And the code generator has no
+Here, only ``b`` is levity polymorphic. There are no variables
+with a levity-polymorphic type. And the code generator has no
trouble with this. Indeed, this is the true type of GHC's ``$`` operator,
slightly more general than the Haskell 98 version.
-Representation-polymorphic bottoms
-----------------------------------
+Because the code generator must store and move arguments as well
+as variables, the logic above applies equally well to function arguments,
+which may not be levity-polymorphic.
+
-We can use representation polymorphism to good effect with ``error``
+Levity-polymorphic bottoms
+--------------------------
+
+We can use levity polymorphism to good effect with ``error``
and ``undefined``, whose types are given here: ::
undefined :: forall (r :: RuntimeRep) (a :: TYPE r).
@@ -8102,25 +8099,25 @@ and ``undefined``, whose types are given here: ::
error :: forall (r :: RuntimeRep) (a :: TYPE r).
HasCallStack => String -> a
-These functions do not bind a representation-polymorphic variable, and
+These functions do not bind a levity-polymorphic variable, and
so are accepted. Their polymorphism allows users to use these to conveniently
stub out functions that return unboxed types.
-Printing representation-polymorphic types
------------------------------------------
+Printing levity-polymorphic types
+---------------------------------
.. ghc-flag:: -Wprint-explicit-runtime-rep
Print ``RuntimeRep`` parameters as they appear; otherwise, they are
- defaulted to ``'PtrRepLifted``.
+ defaulted to ``'LiftedRep``.
-Most GHC users will not need to worry about representation polymorphism
-or unboxed types. For these users, see the representation polymorphism
+Most GHC users will not need to worry about levity polymorphism
+or unboxed types. For these users, seeing the levity polymorphism
in the type of ``$`` is unhelpful. And thus, by default, it is suppressed,
-by supposing all type variables of type ``RuntimeType`` to be ``'PtrRepLifted``
-when printing, and printing ``TYPE 'PtrRepLifted`` as ``*``.
+by supposing all type variables of type ``RuntimeRep`` to be ``'LiftedRep``
+when printing, and printing ``TYPE 'LiftedRep`` as ``*``.
-Should you wish to see representation polymorphism in your types, enable
+Should you wish to see levity polymorphism in your types, enable
the flag :ghc-flag:`-fprint-explicit-runtime-reps`.
.. _type-level-literals:
diff --git a/docs/users_guide/using-warnings.rst b/docs/users_guide/using-warnings.rst
index fdda600773..21f00c454e 100644
--- a/docs/users_guide/using-warnings.rst
+++ b/docs/users_guide/using-warnings.rst
@@ -49,6 +49,7 @@ The following flags are simple ways to select standard "packages" of warnings:
* :ghc-flag:`-Wincomplete-patterns`
* :ghc-flag:`-Wdodgy-exports`
* :ghc-flag:`-Wdodgy-imports`
+ * :ghc-flag:`-Wunbanged-strict-patterns`
.. ghc-flag:: -Wall
@@ -1030,6 +1031,12 @@ of ``-W(no-)*``.
which causes the pre-processor to warn on uses of the `#if` directive on
undefined identifiers.
+.. ghc-flag:: -Wunbanged-strict-patterns
+
+ This flag warns whenever you write a pattern that binds a variable whose
+ type is unlifted, and yet the pattern is not a bang pattern nor a bare variable.
+ See :ref:`glasgow-unboxed` for informatino about unlifted types.
+
If you're feeling really paranoid, the :ghc-flag:`-dcore-lint` option is a good choice.
It turns on heavyweight intra-pass sanity-checking within GHC. (It checks GHC's
sanity, not yours.)
diff --git a/docs/users_guide/using.rst b/docs/users_guide/using.rst
index 7b01fc27b6..60007b0155 100644
--- a/docs/users_guide/using.rst
+++ b/docs/users_guide/using.rst
@@ -694,7 +694,7 @@ messages and in GHCi:
.. ghc-flag:: -fprint-explicit-runtime-reps
When :ghc-flag:`-fprint-explicit-runtime-reps` is enabled, GHC prints
- ``RuntimeRep`` type variables for runtime-representation-polymorphic types.
+ ``RuntimeRep`` type variables for levity-polymorphic types.
Otherwise GHC will default these to ``PtrRepLifted``. For example,
.. code-block:: none