summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorTakano Akio <tak@anoak.io>2018-01-31 21:35:29 -0500
committerBen Gamari <ben@smart-cactus.org>2018-01-31 23:28:48 -0500
commitbe84823b956f0aa09c58d94d1901f2dff13546b4 (patch)
tree94b76f4746a8af6748bbfb2f868c9fd98206735f /docs
parent0bff9e677f0569bc8a7207c20cddddfd67e2448f (diff)
downloadhaskell-be84823b956f0aa09c58d94d1901f2dff13546b4.tar.gz
Implement BlockArguments (#10843)
This patch implements the BlockArguments extension, as proposed at https://github.com/ghc-proposals/ghc-proposals/pull/90. It also fixes #10855 as a side-effect. This patch adds a large number of shift-reduce conflicts to the parser. All of them concern the ambiguity as to where constructs like `if` and `let` end. Fortunately they are resolved correctly by preferring shift. The patch is based on @gibiansky's ArgumentDo implementation (D1219). Test Plan: ./validate Reviewers: goldfire, bgamari, alanz, mpickering Reviewed By: bgamari, mpickering Subscribers: Wizek, dfeuer, gibiansky, rwbarton, thomie, mpickering, carter GHC Trac Issues: #10843, #10855 Differential Revision: https://phabricator.haskell.org/D4260
Diffstat (limited to 'docs')
-rw-r--r--docs/users_guide/bugs.rst6
-rw-r--r--docs/users_guide/glasgow_exts.rst98
2 files changed, 98 insertions, 6 deletions
diff --git a/docs/users_guide/bugs.rst b/docs/users_guide/bugs.rst
index 7d41d874bb..3cfc023ea0 100644
--- a/docs/users_guide/bugs.rst
+++ b/docs/users_guide/bugs.rst
@@ -83,12 +83,6 @@ Context-free syntax
(let x = 42 in x == 42 == True)
-- The Haskell Report allows you to put a unary ``-`` preceding certain
- expressions headed by keywords, allowing constructs like ``- case x of ...``
- or ``- do { ... }``. GHC does not allow this. Instead, unary ``-`` is allowed
- before only expressions that could potentially be applied as a function.
-
-
.. _infelicities-exprs-pats:
Expressions and patterns
diff --git a/docs/users_guide/glasgow_exts.rst b/docs/users_guide/glasgow_exts.rst
index 514dae8dd6..190c611ede 100644
--- a/docs/users_guide/glasgow_exts.rst
+++ b/docs/users_guide/glasgow_exts.rst
@@ -2098,6 +2098,104 @@ data constructor in an import or export list with the keyword
``pattern``, to allow the import or export of a data constructor without
its parent type constructor (see :ref:`patsyn-impexp`).
+.. _block-arguments:
+
+More liberal syntax for function arguments
+------------------------------------------
+
+.. extension:: BlockArguments
+ :shortdesc: Allow ``do`` blocks and other constructs as function arguments.
+
+ :since: 8.6.1
+
+ Allow ``do`` expressions, lambda expressions, etc. to be directly used as
+ a function argument.
+
+In Haskell 2010, certain kinds of expressions can be used without parentheses
+as an argument to an operator, but not as an argument to a function.
+They include ``do``, lambda, ``if``, ``case``, and ``let``
+expressions. Some GHC extensions also define language constructs of this type:
+``mdo`` (:ref:`recursive-do-notation`), ``\case`` (:ref:`lambda-case`), and
+``proc`` (:ref:`arrow-notation`).
+
+The :extension:`BlockArguments` extension allows these constructs to be directly
+used as a function argument. For example::
+
+ when (x > 0) do
+ print x
+ exitFailure
+
+will be parsed as::
+
+ when (x > 0) (do
+ print x
+ exitFailure)
+
+and
+
+::
+
+ withForeignPtr fptr \ptr -> c_memcpy buf ptr size
+
+will be parsed as::
+
+ withForeignPtr fptr (\ptr -> c_memcpy buf ptr size)
+
+Changes to the grammar
+~~~~~~~~~~~~~~~~~~~~~~
+
+The Haskell report `defines
+<https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-220003>`_
+the ``lexp`` nonterminal thus (``*`` indicates a rule of interest)::
+
+ lexp → \ apat1 … apatn -> exp (lambda abstraction, n ≥ 1) *
+ | let decls in exp (let expression) *
+ | if exp [;] then exp [;] else exp (conditional) *
+ | case exp of { alts } (case expression) *
+ | do { stmts } (do expression) *
+ | fexp
+
+ fexp → [fexp] aexp (function application)
+
+ aexp → qvar (variable)
+ | gcon (general constructor)
+ | literal
+ | ( exp ) (parenthesized expression)
+ | qcon { fbind1 … fbindn } (labeled construction)
+ | aexp { fbind1 … fbindn } (labelled update)
+ | …
+
+The :extension:`BlockArguments` extension moves these production rules under
+``aexp``::
+
+ lexp → fexp
+
+ fexp → [fexp] aexp (function application)
+
+ aexp → qvar (variable)
+ | gcon (general constructor)
+ | literal
+ | ( exp ) (parenthesized expression)
+ | qcon { fbind1 … fbindn } (labeled construction)
+ | aexp { fbind1 … fbindn } (labelled update)
+ | \ apat1 … apatn -> exp (lambda abstraction, n ≥ 1) *
+ | let decls in exp (let expression) *
+ | if exp [;] then exp [;] else exp (conditional) *
+ | case exp of { alts } (case expression) *
+ | do { stmts } (do expression) *
+ | …
+
+Now the ``lexp`` nonterminal is redundant and can be dropped from the grammar.
+
+Note that this change relies on an existing meta-rule to resolve ambiguities:
+
+ The grammar is ambiguous regarding the extent of lambda abstractions, let
+ expressions, and conditionals. The ambiguity is resolved by the meta-rule
+ that each of these constructs extends as far to the right as possible.
+
+For example, ``f \a -> a b`` will be parsed as ``f (\a -> a b)``, not as ``f
+(\a -> a) b``.
+
.. _syntax-stolen:
Summary of stolen syntax