<para> Language options recognised by Cabal can also be enabled using the <literal>LANGUAGE</literal> pragma,
thus <literal>{-# LANGUAGE TemplateHaskell #-}</literal> (see <xref linkend="language-pragma"/>>). </para>
- <para>Turning on an option that enables special syntax
- <emphasis>might</emphasis> cause working Haskell 98 code to fail
- to compile, perhaps because it uses a variable name which has
- become a reserved word. So, together with each option below, we
- list the special syntax which is enabled by this option. We use
- notation and nonterminal names from the Haskell 98 lexical syntax
- (see the Haskell 98 Report). There are two classes of special
- syntax:</para>
-
- <itemizedlist>
- <listitem>
- <para>New reserved words and symbols: character sequences
- which are no longer available for use as identifiers in the
- program.</para>
- </listitem>
- <listitem>
- <para>Other special syntax: sequences of characters that have
- a different meaning when this particular option is turned
- on.</para>
- </listitem>
- </itemizedlist>
-
- <para>We are only listing syntax changes here that might affect
- existing working programs (i.e. "stolen" syntax). Many of these
- extensions will also enable new context-free syntax, but in all
- cases programs written to use the new syntax would not be
- compilable without the option enabled.</para>
-
- <variablelist>
-
- <varlistentry>
- <term>
- <option>-fglasgow-exts</option>:
+ <para>The flag <option>-fglasgow-exts</option>:
<indexterm><primary><option>-fglasgow-exts</option></primary></indexterm>
- </term>
- <listitem>
- <para>This simultaneously enables all of the extensions to
- Haskell 98 described in <xref
- linkend="ghc-language-features"/>, except where otherwise
- noted. We are trying to move away from this portmanteau flag,
- and towards enabling features individaully.</para>
-
- <para>New reserved words: <literal>forall</literal> (only in
- types), <literal>mdo</literal>.</para>
-
- <para>Other syntax stolen:
- <replaceable>varid</replaceable>{<literal>#</literal>},
- <replaceable>char</replaceable><literal>#</literal>,
- <replaceable>string</replaceable><literal>#</literal>,
- <replaceable>integer</replaceable><literal>#</literal>,
- <replaceable>float</replaceable><literal>#</literal>,
- <replaceable>float</replaceable><literal>##</literal>,
- <literal>(#</literal>, <literal>#)</literal>,
- <literal>|)</literal>, <literal>{|</literal>.</para>
-
- <para>Implies these specific language options:
+ simultaneously enables the following extensions:
<option>-XForeignFunctionInterface</option>,
<option>-XImplicitParams</option>,
<option>-XScopedTypeVariables</option>,
<option>-XGADTs</option>,
- <option>-XTypeFamilies</option>. </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
- <option>-XForeignFunctionInterface</option>:
- <indexterm><primary><option>-XForeignFunctionInterface</option></primary></indexterm>
- </term>
- <listitem>
- <para>This option enables the language extension defined in the
- Haskell 98 Foreign Function Interface Addendum.</para>
-
- <para>New reserved words: <literal>foreign</literal>.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
- <option>-XMonomorphismRestriction</option>,<option>-XMonoPatBinds</option>:
- </term>
- <listitem>
- <para> These two flags control how generalisation is done.
- See <xref linkend="monomorphism"/>.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
- <option>-XExtendedDefaultRules</option>:
- <indexterm><primary><option>-XExtendedDefaultRules</option></primary></indexterm>
- </term>
- <listitem>
- <para> Use GHCi's extended default rules in a regular module (<xref linkend="extended-default-rules"/>).
- Independent of the <option>-fglasgow-exts</option>
- flag. </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
- <option>-XOverlappingInstances</option>
- <indexterm><primary><option>-XOverlappingInstances</option></primary></indexterm>
- </term>
- <term>
- <option>-XUndecidableInstances</option>
- <indexterm><primary><option>-XUndecidableInstances</option></primary></indexterm>
- </term>
- <term>
- <option>-XIncoherentInstances</option>
- <indexterm><primary><option>-XIncoherentInstances</option></primary></indexterm>
- </term>
- <term>
- <option>-fcontext-stack=N</option>
- <indexterm><primary><option>-fcontext-stack</option></primary></indexterm>
- </term>
- <listitem>
- <para> See <xref linkend="instance-decls"/>. Only relevant
- if you also use <option>-fglasgow-exts</option>.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
- <option>-finline-phase</option>
- <indexterm><primary><option>-finline-phase</option></primary></indexterm>
- </term>
- <listitem>
- <para>See <xref linkend="rewrite-rules"/>. Only relevant if
- you also use <option>-fglasgow-exts</option>.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
- <option>-XArrows</option>
- <indexterm><primary><option>-XArrows</option></primary></indexterm>
- </term>
- <listitem>
- <para>See <xref linkend="arrow-notation"/>. Independent of
- <option>-fglasgow-exts</option>.</para>
-
- <para>New reserved words/symbols: <literal>rec</literal>,
- <literal>proc</literal>, <literal>-<</literal>,
- <literal>>-</literal>, <literal>-<<</literal>,
- <literal>>>-</literal>.</para>
-
- <para>Other syntax stolen: <literal>(|</literal>,
- <literal>|)</literal>.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
- <option>-XGenerics</option>
- <indexterm><primary><option>-XGenerics</option></primary></indexterm>
- </term>
- <listitem>
- <para>See <xref linkend="generic-classes"/>. Independent of
- <option>-fglasgow-exts</option>.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-XNoImplicitPrelude</option></term>
- <listitem>
- <para><indexterm><primary>-XNoImplicitPrelude
- option</primary></indexterm> GHC normally imports
- <filename>Prelude.hi</filename> files for you. If you'd
- rather it didn't, then give it a
- <option>-XNoImplicitPrelude</option> option. The idea is
- that you can then import a Prelude of your own. (But don't
- call it <literal>Prelude</literal>; the Haskell module
- namespace is flat, and you must not conflict with any
- Prelude module.)</para>
-
- <para>Even though you have not imported the Prelude, most of
- the built-in syntax still refers to the built-in Haskell
- Prelude types and values, as specified by the Haskell
- Report. For example, the type <literal>[Int]</literal>
- still means <literal>Prelude.[] Int</literal>; tuples
- continue to refer to the standard Prelude tuples; the
- translation for list comprehensions continues to use
- <literal>Prelude.map</literal> etc.</para>
-
- <para>However, <option>-XNoImplicitPrelude</option> does
- change the handling of certain built-in syntax: see <xref
- linkend="rebindable-syntax"/>.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-XImplicitParams</option></term>
- <listitem>
- <para>Enables implicit parameters (see <xref
- linkend="implicit-parameters"/>). Currently also implied by
- <option>-fglasgow-exts</option>.</para>
-
- <para>Syntax stolen:
- <literal>?<replaceable>varid</replaceable></literal>,
- <literal>%<replaceable>varid</replaceable></literal>.</para>
- </listitem>
- </varlistentry>
+ <option>-XTypeFamilies</option>.
+ Enabling these options is the <emphasis>only</emphasis>
+ effect of <options>-fglasgow-exts</options>
+ We are trying to move away from this portmanteau flag,
+ and towards enabling features individually.</para>
- <varlistentry>
- <term><option>-XOverloadedStrings</option></term>
- <listitem>
- <para>Enables overloaded string literals (see <xref
- linkend="overloaded-strings"/>).</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-XScopedTypeVariables</option></term>
- <listitem>
- <para>Enables lexically-scoped type variables (see <xref
- linkend="scoped-type-variables"/>). Implied by
- <option>-fglasgow-exts</option>.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-XTemplateHaskell</option></term>
- <listitem>
- <para>Enables Template Haskell (see <xref
- linkend="template-haskell"/>). This flag must
- be given explicitly; it is no longer implied by
- <option>-fglasgow-exts</option>.</para>
-
- <para>Syntax stolen: <literal>[|</literal>,
- <literal>[e|</literal>, <literal>[p|</literal>,
- <literal>[d|</literal>, <literal>[t|</literal>,
- <literal>$(</literal>,
- <literal>$<replaceable>varid</replaceable></literal>.</para>
- </listitem>
- </varlistentry>
-
- </variablelist>
</sect1>
<!-- UNBOXED TYPES AND PRIMITIVE OPERATIONS -->
<sect1 id="primitives">
<title>Unboxed types and primitive operations</title>
-<para>GHC is built on a raft of primitive data types and operations.
+<para>GHC is built on a raft of primitive data types and operations;
+"primitive" in the sense that they cannot be defined in Haskell itself.
While you really can use this stuff to write fast code,
we generally find it a lot less painful, and more satisfying in the
long run, to use higher-level language features and libraries. With
unboxed version in any case. And if it isn't, we'd like to know
about it.</para>
-<para>We do not currently have good, up-to-date documentation about the
-primitives, perhaps because they are mainly intended for internal use.
-There used to be a long section about them here in the User Guide, but it
-became out of date, and wrong information is worse than none.</para>
-
-<para>The Real Truth about what primitive types there are, and what operations
-work over those types, is held in the file
-<filename>fptools/ghc/compiler/prelude/primops.txt.pp</filename>.
-This file is used directly to generate GHC's primitive-operation definitions, so
-it is always correct! It is also intended for processing into text.</para>
-
-<para> Indeed,
-the result of such processing is part of the description of the
- <ulink
- url="http://www.haskell.org/ghc/docs/papers/core.ps.gz">External
- Core language</ulink>.
-So that document is a good place to look for a type-set version.
-We would be very happy if someone wanted to volunteer to produce an SGML
-back end to the program that processes <filename>primops.txt</filename> so that
-we could include the results here in the User Guide.</para>
-
-<para>What follows here is a brief summary of some main points.</para>
+<para>All these primitive data types and operations are exported by the
+library <literal>GHC.Prim</literal>, for which there is
+<ulink url="../libraries/base/GHC.Prim.html">detailed online documentation</ulink>.
+(This documentation is generated from the file <filename>compiler/prelude/primops.txt.pp</filename>.)
+</para>
+<para>
+If you want to mention any of the primitive data types or operations in your
+program, you must first import <literal>GHC.Prim</literal> to bring them
+into scope. Many of them have names ending in "#", and to mention such
+names you need the <option>-XMagicHash</option> extension (<xref linkend="magic-hash"/>).
+</para>
+
+<para>The primops make extensive use of <link linkend="glasgow-unboxed">unboxed types</link>
+and <link linkend="unboxed-tuples">unboxed tuples</link>, which
+we briefly summarise here. </para>
<sect2 id="glasgow-unboxed">
<title>Unboxed types
Primitive (unboxed) types cannot be defined in Haskell, and are
therefore built into the language and compiler. Primitive types are
always unlifted; that is, a value of a primitive type cannot be
-bottom. We use the convention that primitive types, values, and
-operations have a <literal>#</literal> suffix.
+bottom. We use the convention (but it is only a convention)
+that primitive types, values, and
+operations have a <literal>#</literal> suffix (see <xref linkend="magic-hash"/>).
+For some primitive types we have special syntax for literals, also
+described in the <link linkend="magic-hash">same section</link>.
</para>
<para>
<sect1 id="syntax-extns">
<title>Syntactic extensions</title>
+ <sect2 id="magic-hash">
+ <title>The magic hash</title>
+ <para>The language extension <option>-XMagicHash</option> allows "#" as a
+ postfix modifier to identifiers. Thus, "x#" is a valid variable, and "T#" is
+ a valid type constructor or data constructor.</para>
+
+ <para>The hash sign does not change sematics at all. We tend to use variable
+ names ending in "#" for unboxed values or types (e.g. <literal>Int#</literal>),
+ but there is no requirement to do so; they are just plain ordinary variables.
+ Nor does the <option>-XMagicHash</option> extension bring anything into scope.
+ For example, to bring <literal>Int#</literal> into scope you must
+ import <literal>GHC.Prim</literal> (see <xref linkend="primitives"/>);
+ the <option>-XMagicHash</option> extension
+ then allows you to <emphasis>refer</emphasis> to the <literal>Int#</literal>
+ that is now in scope.</para>
+ <para> The <option>-XMagicHash</option> also enables some new forms of literals (see <xref linkend="glasgow-unboxed"/>):
+ <itemizedlist>
+ <listitem><para> <literal>'x'#</literal> has type <literal>Char#</literal></para> </listitem>
+ <listitem><para> <literal>"foo"#</literal> has type <literal>Addr#</literal></para> </listitem>
+ <listitem><para> <literal>3#</literal> has type <literal>Int#</literal>. In general,
+ any Haskell 98 integer lexeme followed by a <literal>#</literal> is an <literal>Int#</literal> literal, e.g.
+ <literal>-0x3A#</literal> as well as <literal>32#</literal></para>.</listitem>
+ <listitem><para> <literal>3##</literal> has type <literal>Word#</literal>. In general,
+ any non-negative Haskell 98 integer lexeme followed by <literal>##</literal>
+ is a <literal>Word#</literal>. </para> </listitem>
+ <listitem><para> <literal>3.2#</literal> has type <literal>Float#</literal>.</para> </listitem>
+ <listitem><para> <literal>3.2##</literal> has type <literal>Double#</literal></para> </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+
<!-- ====================== HIERARCHICAL MODULES ======================= -->
+
<sect2 id="hierarchical-modules">
<title>Hierarchical Modules</title>
</programlisting>
The representation of Typ is held abstract, permitting implementations
-to use a fancy representation (e.g., hash-consing to managage sharing).
+to use a fancy representation (e.g., hash-consing to manage sharing).
Without view patterns, using this signature a little inconvenient:
<programlisting>
(The function <literal>sortWith</literal> is not a keyword; it is an ordinary
function that is exported by <literal>GHC.Exts</literal>.)</para>
-<para>There are five new forms of compehension qualifier,
+<para>There are five new forms of comprehension qualifier,
all introduced by the (existing) keyword <literal>then</literal>:
<itemizedlist>
<listitem>
is a function supplied to f by the compiler which lets it compute e on every
element of the list being transformed. However, unlike the non-grouping case,
f additionally partitions the list into a number of sublists: this means that
- at every point after this statement, binders occuring before it in the comprehension
+ at every point after this statement, binders occurring before it in the comprehension
refer to <emphasis>lists</emphasis> of possible values, not single values. To help understand
this, let's look at an example:</para>
<!-- ===================== REBINDABLE SYNTAX =================== -->
<sect2 id="rebindable-syntax">
-<title>Rebindable syntax</title>
-
- <para>GHC allows most kinds of built-in syntax to be rebound by
- the user, to facilitate replacing the <literal>Prelude</literal>
- with a home-grown version, for example.</para>
-
- <para>You may want to define your own numeric class
+<title>Rebindable syntax and the implicit Prelude import</title>
+
+ <para><indexterm><primary>-XNoImplicitPrelude
+ option</primary></indexterm> GHC normally imports
+ <filename>Prelude.hi</filename> files for you. If you'd
+ rather it didn't, then give it a
+ <option>-XNoImplicitPrelude</option> option. The idea is
+ that you can then import a Prelude of your own. (But don't
+ call it <literal>Prelude</literal>; the Haskell module
+ namespace is flat, and you must not conflict with any
+ Prelude module.)</para>
+
+ <para>Suppose you are importing a Prelude of your own
+ in order to define your own numeric class
hierarchy. It completely defeats that purpose if the
literal "1" means "<literal>Prelude.fromInteger
1</literal>", which is what the Haskell Report specifies.
- So the <option>-XNoImplicitPrelude</option> flag causes
+ So the <option>-XNoImplicitPrelude</option>
+ flag <emphasis>also</emphasis> causes
the following pieces of built-in syntax to refer to
<emphasis>whatever is in scope</emphasis>, not the Prelude
versions:
-
<itemizedlist>
<listitem>
<para>An integer literal <literal>368</literal> means
</para></listitem>
</itemizedlist>
In all cases (apart from arrow notation), the static semantics should be that of the desugared form,
-even if that is a little unexpected. For emample, the
+even if that is a little unexpected. For example, the
static semantics of the literal <literal>368</literal>
is exactly that of <literal>fromInteger (368::Integer)</literal>; it's fine for
<literal>fromInteger</literal> to have any of the types:
</title>
<para>
-Record puns are enabled by the flag <literal>-XRecordPuns</literal>.
+Record puns are enabled by the flag <literal>-XNamedFieldPuns</literal>.
</para>
<para>
sides of other <literal>let</literal>-bindings and the body of the
<literal>let</literal>C. Or, in recursive <literal>do</literal>
expressions (<xref linkend="mdo-notation"/>), the local fixity
-declarations of aA <literal>let</literal> statement scope over other
+declarations of a <literal>let</literal> statement scope over other
statements in the group, just as the bound name does.
</para>
-Moreover, a local fixity declatation *must* accompany a local binding of
+<para>
+Moreover, a local fixity declaration *must* accompany a local binding of
that name: it is not possible to revise the fixity of name bound
elsewhere, as in
<programlisting>
Because local fixity declarations are technically Haskell 98, no flag is
necessary to enable them.
+</para>
+</sect2>
+
+<sect2 id="package-imports">
+ <title>Package-qualified imports</title>
+
+ <para>With the <option>-XPackageImports</option> flag, GHC allows
+ import declarations to be qualified by the package name that the
+ module is intended to be imported from. For example:</para>
+
+<programlisting>
+import "network" Network.Socket
+</programlisting>
+
+ <para>would import the module <literal>Network.Socket</literal> from
+ the package <literal>network</literal> (any version). This may
+ be used to disambiguate an import when the same module is
+ available from multiple packages, or is present in both the
+ current package being built and an external package.</para>
+
+ <para>Note: you probably don't need to use this feature, it was
+ added mainly so that we can build backwards-compatible versions of
+ packages when APIs change. It can lead to fragile dependencies in
+ the common case: modules occasionally move from one package to
+ another, rendering any package-qualified imports broken.</para>
</sect2>
+<sect2 id="syntax-stolen">
+<title>Summary of stolen syntax</title>
+
+ <para>Turning on an option that enables special syntax
+ <emphasis>might</emphasis> cause working Haskell 98 code to fail
+ to compile, perhaps because it uses a variable name which has
+ become a reserved word. This section lists the syntax that is
+ "stolen" by language extensions.
+ We use
+ notation and nonterminal names from the Haskell 98 lexical syntax
+ (see the Haskell 98 Report).
+ We only list syntax changes here that might affect
+ existing working programs (i.e. "stolen" syntax). Many of these
+ extensions will also enable new context-free syntax, but in all
+ cases programs written to use the new syntax would not be
+ compilable without the option enabled.</para>
+
+<para>There are two classes of special
+ syntax:
+
+ <itemizedlist>
+ <listitem>
+ <para>New reserved words and symbols: character sequences
+ which are no longer available for use as identifiers in the
+ program.</para>
+ </listitem>
+ <listitem>
+ <para>Other special syntax: sequences of characters that have
+ a different meaning when this particular option is turned
+ on.</para>
+ </listitem>
+ </itemizedlist>
+
+The following syntax is stolen:
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <literal>forall</literal>
+ <indexterm><primary><literal>forall</literal></primary></indexterm>
+ </term>
+ <listitem><para>
+ Stolen (in types) by: <option>-XScopedTypeVariables</option>,
+ <option>-XLiberalTypeSynonyms</option>,
+ <option>-XRank2Types</option>,
+ <option>-XRankNTypes</option>,
+ <option>-XPolymorphicComponents</option>,
+ <option>-XExistentialQuantification</option>
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>mdo</literal>
+ <indexterm><primary><literal>mdo</literal></primary></indexterm>
+ </term>
+ <listitem><para>
+ Stolen by: <option>-XRecursiveDo</option>,
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>foreign</literal>
+ <indexterm><primary><literal>foreign</literal></primary></indexterm>
+ </term>
+ <listitem><para>
+ Stolen by: <option>-XForeignFunctionInterface</option>,
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>rec</literal>,
+ <literal>proc</literal>, <literal>-<</literal>,
+ <literal>>-</literal>, <literal>-<<</literal>,
+ <literal>>>-</literal>, and <literal>(|</literal>,
+ <literal>|)</literal> brackets
+ <indexterm><primary><literal>proc</literal></primary></indexterm>
+ </term>
+ <listitem><para>
+ Stolen by: <option>-XArrows</option>,
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>?<replaceable>varid</replaceable></literal>,
+ <literal>%<replaceable>varid</replaceable></literal>
+ <indexterm><primary>implicit parameters</primary></indexterm>
+ </term>
+ <listitem><para>
+ Stolen by: <option>-XImplicitParams</option>,
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>[|</literal>,
+ <literal>[e|</literal>, <literal>[p|</literal>,
+ <literal>[d|</literal>, <literal>[t|</literal>,
+ <literal>$(</literal>,
+ <literal>$<replaceable>varid</replaceable></literal>
+ <indexterm><primary>Template Haskell</primary></indexterm>
+ </term>
+ <listitem><para>
+ Stolen by: <option>-XTemplateHaskell</option>,
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>[:<replaceable>varid</replaceable>|</literal>
+ <indexterm><primary>quasi-quotation</primary></indexterm>
+ </term>
+ <listitem><para>
+ Stolen by: <option>-XQuasiQuotes</option>,
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <replaceable>varid</replaceable>{<literal>#</literal>},
+ <replaceable>char</replaceable><literal>#</literal>,
+ <replaceable>string</replaceable><literal>#</literal>,
+ <replaceable>integer</replaceable><literal>#</literal>,
+ <replaceable>float</replaceable><literal>#</literal>,
+ <replaceable>float</replaceable><literal>##</literal>,
+ <literal>(#</literal>, <literal>#)</literal>,
+ </term>
+ <listitem><para>
+ Stolen by: <option>-XMagicHash</option>,
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+</para>
+</sect2>
</sect1>
<title>Liberalised type synonyms</title>
<para>
-Type synonyms are like macros at the type level, and
+Type synonyms are like macros at the type level, but Haskell 98 imposes many rules
+on individual synonym declarations.
+With the <option>-XLiberalTypeSynonyms</option> extension,
GHC does validity checking on types <emphasis>only after expanding type synonyms</emphasis>.
-That means that GHC can be very much more liberal about type synonyms than Haskell 98:
+That means that GHC can be very much more liberal about type synonyms than Haskell 98.
+
<itemizedlist>
<listitem> <para>You can write a <literal>forall</literal> (including overloading)
in a type synonym, thus:
</listitem>
<listitem><para>
-You can write an unboxed tuple in a type synonym:
+If you also use <option>-XUnboxedTuples</option>,
+you can write an unboxed tuple in a type synonym:
<programlisting>
type Pr = (# Int, Int #)
</para>
<para>
-What this allows us to do is to package heterogenous values
+What this allows us to do is to package heterogeneous values
together with a bunch of functions that manipulate them, and then treat
that collection of packages in a uniform manner. You can express
quite a bit of object-oriented-like programming this way.
data NumInst a
= Num a => MkNumInst (NumInst a)
</programlisting>
-Notice that, unlike the situation when declaring an existental, there is
+Notice that, unlike the situation when declaring an existential, there is
no <literal>forall</literal>, because the <literal>Num</literal> constrains the
-data type's univerally quantified type variable <literal>a</literal>.
+data type's universally quantified type variable <literal>a</literal>.
A constructor may have both universal and existential type variables: for example,
the following two declarations are equivalent:
<programlisting>
but for a GADT the arguments to the type constructor can be arbitrary monotypes.
For example, in the <literal>Term</literal> data
type above, the type of each constructor must end with <literal>Term ty</literal>, but
-the <literal>ty</literal> may not be a type variable (e.g. the <literal>Lit</literal>
+the <literal>ty</literal> need not be a type variable (e.g. the <literal>Lit</literal>
constructor).
</para></listitem>
<listitem><para>
+It's is permitted to declare an ordinary algebraic data type using GADT-style syntax.
+What makes a GADT into a GADT is not the syntax, but rather the presence of data constructors
+whose result type is not just <literal>T a b</literal>.
+</para></listitem>
+
+<listitem><para>
You cannot use a <literal>deriving</literal> clause for a GADT; only for
an ordinary data type.
</para></listitem>
</programlisting>
</para></listitem>
+<listitem><para>
+When pattern-matching against data constructors drawn from a GADT,
+for example in a <literal>case</literal> expression, the following rules apply:
+<itemizedlist>
+<listitem><para>The type of the scrutinee must be rigid.</para></listitem>
+<listitem><para>The type of the result of the <literal>case</literal> expression must be rigid.</para></listitem>
+<listitem><para>The type of any free variable mentioned in any of
+the <literal>case</literal> alternatives must be rigid.</para></listitem>
+</itemizedlist>
+A type is "rigid" if it is completely known to the compiler at its binding site. The easiest
+way to ensure that a variable a rigid type is to give it a type signature.
+</para></listitem>
+
</itemizedlist>
</para>
You must supply a context (in the example the context is <literal>(Eq a)</literal>),
exactly as you would in an ordinary instance declaration.
(In contrast the context is inferred in a <literal>deriving</literal> clause
-attached to a data type declaration.) These <literal>deriving instance</literal>
-rules obey the same rules concerning form and termination as ordinary instance declarations,
-controlled by the same flags; see <xref linkend="instance-decls"/>. </para>
+attached to a data type declaration.)
+
+A <literal>deriving instance</literal> declaration
+must obey the same rules concerning form and termination as ordinary instance declarations,
+controlled by the same flags; see <xref linkend="instance-decls"/>.
+</para>
+<para>
+Unlike a <literal>deriving</literal>
+declaration attached to a <literal>data</literal> declaration, the instance can be more specific
+than the data type (assuming you also use
+<literal>-XFlexibleInstances</literal>, <xref linkend="instance-rules"/>). Consider
+for example
+<programlisting>
+ data Foo a = Bar a | Baz String
+
+ deriving instance Eq a => Eq (Foo [a])
+ deriving instance Eq a => Eq (Foo (Maybe a))
+</programlisting>
+This will generate a derived instance for <literal>(Foo [a])</literal> and <literal>(Foo (Maybe a))</literal>,
+but other types such as <literal>(Foo (Int,Bool))</literal> will not be an instance of <literal>Eq</literal>.
+</para>
<para>The stand-alone syntax is generalised for newtypes in exactly the same
way that ordinary <literal>deriving</literal> clauses are generalised (<xref linkend="newtype-deriving"/>).
These restrictions ensure that context reduction terminates: each reduction
step makes the problem smaller by at least one
constructor. Both the Paterson Conditions and the Coverage Condition are lifted
-if you give the <option>-fallow-undecidable-instances</option>
+if you give the <option>-XUndecidableInstances</option>
flag (<xref linkend="undecidable-instances"/>).
You can find lots of background material about the reason for these
restrictions in the paper <ulink
<emphasis>Each universally quantified type variable
<literal>tvi</literal> must be reachable from <literal>type</literal></emphasis>.
-A type variable <literal>a</literal> is "reachable" if it it appears
-in the same constraint as either a type variable free in in
+A type variable <literal>a</literal> is "reachable" if it appears
+in the same constraint as either a type variable free in
<literal>type</literal>, or another reachable type variable.
A value with a type that does not obey
this reachability restriction cannot be used without introducing
GHC has three flags to control higher-rank types:
<itemizedlist>
<listitem><para>
- <option>-XPolymorphicComponents</option>: data constructors (only) can have polymorphic argment types.
+ <option>-XPolymorphicComponents</option>: data constructors (only) can have polymorphic argument types.
</para></listitem>
<listitem><para>
<option>-XRank2Types</option>: any function (including data constructors) can have a rank-2 type.
its free type variables (<ulink
url="http://www.haskell.org/onlinereport/decls.html#sect4.1.2">Section
4.1.2</ulink>
-of the Haskel Report).
+of the Haskell Report).
Lexically scoped type variables affect this implicit quantification rules
as follows: any type variable that is in scope is <emphasis>not</emphasis> universally
quantified. For example, if type variable <literal>a</literal> is in scope,
signature simply constrains the type of the pattern in the obvious way.
</para>
<para>
-Unlike expression and declaration type signatures, pattern type signatures are not implictly generalised.
-The pattern in a <emphasis>patterm binding</emphasis> may only mention type variables
+Unlike expression and declaration type signatures, pattern type signatures are not implicitly generalised.
+The pattern in a <emphasis>pattern binding</emphasis> may only mention type variables
that are already in scope. For example:
<programlisting>
f :: forall a. [a] -> (Int, [a])
</itemizedlist></para></listitem>
<listitem><para>
+ A quasi-quotation can appear in either a pattern context or an
+ expression context and is also written in Oxford brackets:
+ <itemizedlist>
+ <listitem><para> <literal>[:<replaceable>varid</replaceable>| ... |]</literal>,
+ where the "..." is an arbitrary string; a full description of the
+ quasi-quotation facility is given in <xref linkend="th-quasiquotation"/>.</para></listitem>
+ </itemizedlist></para></listitem>
+
+ <listitem><para>
A name can be quoted with either one or two prefix single quotes:
<itemizedlist>
<listitem><para> <literal>'f</literal> has type <literal>Name</literal>, and names the function <literal>f</literal>.
That is, <literal>''</literal><replaceable>thing</replaceable> interprets <replaceable>thing</replaceable> in a type context.
</para></listitem>
</itemizedlist>
- These <literal>Names</literal> can be used to construct Template Haskell expressions, patterns, delarations etc. They
+ These <literal>Names</literal> can be used to construct Template Haskell expressions, patterns, declarations etc. They
may also be given as an argument to the <literal>reify</literal> function.
</para>
</listitem>
</itemizedlist>
-(Compared to the original paper, there are many differnces of detail.
+(Compared to the original paper, there are many differences of detail.
The syntax for a declaration splice uses "<literal>$</literal>" not "<literal>splice</literal>".
The type of the enclosed expression must be <literal>Q [Dec]</literal>, not <literal>[Q Dec]</literal>.
Type splices are not implemented, and neither are pattern splices or quotations.
</orderedlist>
</sect2>
+<sect2 id="th-quasiquotation"> <title> Template Haskell Quasi-quotation </title>
+<para>Quasi-quotation allows patterns and expressions to be written using
+programmer-defined concrete syntax; the motivation behind the extension and
+several examples are documented in
+"<ulink url="http://www.eecs.harvard.edu/~mainland/ghc-quasiquoting/">Why It's
+Nice to be Quoted: Quasiquoting for Haskell</ulink>" (Proc Haskell Workshop
+2007). The example below shows how to write a quasiquoter for a simple
+expression language.</para>
+
+<para>
+In the example, the quasiquoter <literal>expr</literal> is bound to a value of
+type <literal>Language.Haskell.TH.Quote.QuasiQuoter</literal> which contains two
+functions for quoting expressions and patterns, respectively. The first argument
+to each quoter is the (arbitrary) string enclosed in the Oxford brackets. The
+context of the quasi-quotation statement determines which of the two parsers is
+called: if the quasi-quotation occurs in an expression context, the expression
+parser is called, and if it occurs in a pattern context, the pattern parser is
+called.</para>
+
+<para>
+Note that in the example we make use of an antiquoted
+variable <literal>n</literal>, indicated by the syntax <literal>'int:n</literal>
+(this syntax for anti-quotation was defined by the parser's
+author, <emphasis>not</emphasis> by GHC). This binds <literal>n</literal> to the
+integer value argument of the constructor <literal>IntExpr</literal> when
+pattern matching. Please see the referenced paper for further details regarding
+anti-quotation as well as the description of a technique that uses SYB to
+leverage a single parser of type <literal>String -> a</literal> to generate both
+an expression parser that returns a value of type <literal>Q Exp</literal> and a
+pattern parser that returns a value of type <literal>Q Pat</literal>.
+</para>
+
+<para>In general, a quasi-quote has the form
+<literal>[$<replaceable>quoter</replaceable>| <replaceable>string</replaceable> |]</literal>.
+The <replaceable>quoter</replaceable> must be the name of an imported quoter; it
+cannot be an arbitrary expression. The quoted <replaceable>string</replaceable>
+can be arbitrary, and may contain newlines.
+</para>
+<para>
+Quasiquoters must obey the same stage restrictions as Template Haskell, e.g., in
+the example, <literal>expr</literal> cannot be defined
+in <literal>Main.hs</literal> where it is used, but must be imported.
+</para>
+
+<programlisting>
+
+{- Main.hs -}
+module Main where
+
+import Expr
+
+main :: IO ()
+main = do { print $ eval [$expr|1 + 2|]
+ ; case IntExpr 1 of
+ { [$expr|'int:n|] -> print n
+ ; _ -> return ()
+ }
+ }
+
+
+{- Expr.hs -}
+module Expr where
+
+import qualified Language.Haskell.TH as TH
+import Language.Haskell.TH.Quasi
+
+data Expr = IntExpr Integer
+ | AntiIntExpr String
+ | BinopExpr BinOp Expr Expr
+ | AntiExpr String
+ deriving(Show, Typeable, Data)
+
+data BinOp = AddOp
+ | SubOp
+ | MulOp
+ | DivOp
+ deriving(Show, Typeable, Data)
+
+eval :: Expr -> Integer
+eval (IntExpr n) = n
+eval (BinopExpr op x y) = (opToFun op) (eval x) (eval y)
+ where
+ opToFun AddOp = (+)
+ opToFun SubOp = (-)
+ opToFun MulOp = (*)
+ opToFun DivOp = div
+
+expr = QuasiQuoter parseExprExp parseExprPat
+
+-- Parse an Expr, returning its representation as
+-- either a Q Exp or a Q Pat. See the referenced paper
+-- for how to use SYB to do this by writing a single
+-- parser of type String -> Expr instead of two
+-- separate parsers.
+
+parseExprExp :: String -> Q Exp
+parseExprExp ...
+
+parseExprPat :: String -> Q Pat
+parseExprPat ...
+</programlisting>
+
+<para>Now run the compiler:
+</para>
+<programlisting>
+$ ghc --make -XQuasiQuotes Main.hs -o main
+</programlisting>
+
+<para>Run "main" and here is your output:</para>
+
+<programlisting>
+$ ./main
+3
+1
+</programlisting>
+
+</sect2>
+
</sect1>
<!-- ===================== Arrow notation =================== -->
<replaceable>word</replaceable> that GHC understands are described
in the following sections; any pragma encountered with an
unrecognised <replaceable>word</replaceable> is (silently)
- ignored.</para>
+ ignored. The layout rule applies in pragmas, so the closing <literal>#-}</literal>
+ should start in a column to the right of the opening <literal>{-#</literal>. </para>
<para>Certain pragmas are <emphasis>file-header pragmas</emphasis>. A file-header
pragma must precede the <literal>module</literal> keyword in the file.
don't recommend using this approach with GHC.</para>
</sect2>
- <sect2 id="deprecated-pragma">
- <title>DEPRECATED pragma</title>
- <indexterm><primary>DEPRECATED</primary>
- </indexterm>
+ <sect2 id="warning-deprecated-pragma">
+ <title>WARNING and DEPRECATED pragmas</title>
+ <indexterm><primary>WARNING</primary></indexterm>
+ <indexterm><primary>DEPRECATED</primary></indexterm>
- <para>The DEPRECATED pragma lets you specify that a particular
- function, class, or type, is deprecated. There are two
- forms.
+ <para>The WARNING pragma allows you to attach an arbitrary warning
+ to a particular function, class, or type.
+ A DEPRECATED pragma lets you specify that
+ a particular function, class, or type is deprecated.
+ There are two ways of using these pragmas.
<itemizedlist>
<listitem>
- <para>You can deprecate an entire module thus:</para>
+ <para>You can work on an entire module thus:</para>
<programlisting>
module Wibble {-# DEPRECATED "Use Wobble instead" #-} where
...
</programlisting>
+ <para>Or:</para>
+<programlisting>
+ module Wibble {-# WARNING "This is an unstable interface." #-} where
+ ...
+</programlisting>
<para>When you compile any module that import
<literal>Wibble</literal>, GHC will print the specified
message.</para>
</listitem>
<listitem>
- <para>You can deprecate a function, class, type, or data constructor, with the
- following top-level declaration:</para>
+ <para>You can attach a warning to a function, class, type, or data constructor, with the
+ following top-level declarations:</para>
<programlisting>
{-# DEPRECATED f, C, T "Don't use these" #-}
+ {-# WARNING unsafePerformIO "This is unsafe; I hope you know what you're doing" #-}
</programlisting>
<para>When you compile any module that imports and uses any
of the specified entities, GHC will print the specified
message.</para>
- <para> You can only deprecate entities declared at top level in the module
+ <para> You can only attach to entities declared at top level in the module
being compiled, and you can only use unqualified names in the list of
- entities being deprecated. A capitalised name, such as <literal>T</literal>
+ entities. A capitalised name, such as <literal>T</literal>
refers to <emphasis>either</emphasis> the type constructor <literal>T</literal>
<emphasis>or</emphasis> the data constructor <literal>T</literal>, or both if
- both are in scope. If both are in scope, there is currently no way to deprecate
- one without the other (c.f. fixities <xref linkend="infix-tycons"/>).</para>
+ both are in scope. If both are in scope, there is currently no way to
+ specify one without the other (c.f. fixities
+ <xref linkend="infix-tycons"/>).</para>
</listitem>
</itemizedlist>
- Any use of the deprecated item, or of anything from a deprecated
- module, will be flagged with an appropriate message. However,
- deprecations are not reported for
- (a) uses of a deprecated function within its defining module, and
- (b) uses of a deprecated function in an export list.
+ Warnings and deprecations are not reported for
+ (a) uses within the defining module, and
+ (b) uses in an export list.
The latter reduces spurious complaints within a library
in which one module gathers together and re-exports
the exports of several others.
</para>
<para>You can suppress the warnings with the flag
- <option>-fno-warn-deprecations</option>.</para>
+ <option>-fno-warn-warnings-deprecations</option>.</para>
</sect2>
<sect2 id="inline-noinline-pragma">
<programlisting>
key_function :: Int -> String -> (Bool, Double)
-
-#ifdef __GLASGOW_HASKELL__
{-# INLINE key_function #-}
-#endif
</programlisting>
- <para>(You don't need to do the C pre-processor carry-on
- unless you're going to stick the code through HBC—it
- doesn't like <literal>INLINE</literal> pragmas.)</para>
-
<para>The major effect of an <literal>INLINE</literal> pragma
is to declare a function's “cost” to be very low.
The normal unfolding machinery will then be very keen to
function "<literal>f</literal>" has a number of other effects:
<itemizedlist>
<listitem><para>
-No funtions are inlined into <literal>f</literal>. Otherwise
+No functions are inlined into <literal>f</literal>. Otherwise
GHC might inline a big function into <literal>f</literal>'s right hand side,
making <literal>f</literal> big; and then inline <literal>f</literal> blindly.
</para></listitem>
All of these effects are aimed at ensuring that what gets inlined is
exactly what you asked for, no more and no less.
</para>
+<para>GHC ensures that inlining cannot go on forever: every mutually-recursive
+group is cut by one or more <emphasis>loop breakers</emphasis> that is never inlined
+(see <ulink url="http://research.microsoft.com/%7Esimonpj/Papers/inlining/index.htm">
+Secrets of the GHC inliner, JFP 12(4) July 2002</ulink>).
+GHC tries not to select a function with an INLINE pragma as a loop breaker, but
+when there is no choice even an INLINE function can be selected, in which case
+the INLINE pragma is ignored.
+For example, for a self-recursive function, the loop breaker can only be the function
+itself, so an INLINE pragma is always ignored.</para>
+
<para>Syntactically, an <literal>INLINE</literal> pragma for a
function can be put anywhere its type signature could be
put.</para>
<literal>UniqueSupply</literal> monad code, we have:</para>
<programlisting>
-#ifdef __GLASGOW_HASKELL__
{-# INLINE thenUs #-}
{-# INLINE returnUs #-}
-#endif
</programlisting>
<para>See also the <literal>NOINLINE</literal> pragma (<xref
linkend="noinline-pragma"/>).</para>
+
+ <para>Note: the HBC compiler doesn't like <literal>INLINE</literal> pragmas,
+ so if you want your code to be HBC-compatible you'll have to surround
+ the pragma with C pre-processor directives
+ <literal>#ifdef __GLASGOW_HASKELL__</literal>...<literal>#endif</literal>.</para>
+
</sect3>
<sect3 id="noinline-pragma">
there was no pragma).
</para></listitem>
<listitem>
- <para>"<literal>INLINE[~k] f</literal>" means: be willing to inline
+ <para>"<literal>NOINLINE[~k] f</literal>" means: be willing to inline
<literal>f</literal>
until phase <literal>k</literal>, but from phase
<literal>k</literal> onwards do not inline it.
<para>
The programmer can specify rewrite rules as part of the source program
-(in a pragma). GHC applies these rewrite rules wherever it can, provided (a)
-the <option>-O</option> flag (<xref linkend="options-optimise"/>) is on,
-and (b) the <option>-frules-off</option> flag
-(<xref linkend="options-f"/>) is not specified, and (c) the
-<option>-fglasgow-exts</option> (<xref linkend="options-language"/>)
-flag is active.
-</para>
-
-<para>
+(in a pragma).
Here is an example:
<programlisting>
{-# RULES
- "map/map" forall f g xs. map f (map g xs) = map (f.g) xs
- #-}
+ "map/map" forall f g xs. map f (map g xs) = map (f.g) xs
+ #-}
</programlisting>
-
+</para>
+<para>
+Use the debug flag <option>-ddump-simpl-stats</option> to see what rules fired.
+If you need more information, then <option>-ddump-rule-firings</option> shows you
+each individual rule firing in detail.
</para>
<sect2>
From a syntactic point of view:
<itemizedlist>
-<listitem>
+<listitem>
<para>
- There may be zero or more rules in a <literal>RULES</literal> pragma.
+ There may be zero or more rules in a <literal>RULES</literal> pragma, separated by semicolons (which
+ may be generated by the layout rule).
</para>
</listitem>
<listitem>
+<para>
+The layout rule applies in a pragma.
+Currently no new indentation level
+is set, so if you put several rules in single RULES pragma and wish to use layout to separate them,
+you must lay out the starting in the same column as the enclosing definitions.
+<programlisting>
+ {-# RULES
+ "map/map" forall f g xs. map f (map g xs) = map (f.g) xs
+ "map/append" forall f xs ys. map f (xs ++ ys) = map f xs ++ map f ys
+ #-}
+</programlisting>
+Furthermore, the closing <literal>#-}</literal>
+should start in a column to the right of the opening <literal>{-#</literal>.
+</para>
+</listitem>
+<listitem>
<para>
Each rule has a name, enclosed in double quotes. The name itself has
no significance at all. It is only used when reporting how many times the rule fired.
<programlisting>
{-# RULES
"map/map" [2] forall f g xs. map f (map g xs) = map (f.g) xs
- #-}
+ #-}
</programlisting>
The "[2]" means that the rule is active in Phase 2 and subsequent phases. The inverse
notation "[~2]" is also accepted, meaning that the rule is active up to, but not including,
</listitem>
-<listitem>
-
-<para>
- Layout applies in a <literal>RULES</literal> pragma. Currently no new indentation level
-is set, so you must lay out your rules starting in the same column as the
-enclosing definitions.
-</para>
-</listitem>
<listitem>
-
<para>
Each variable mentioned in a rule must either be in scope (e.g. <function>map</function>),
or bound by the <literal>forall</literal> (e.g. <function>f</function>, <function>g</function>, <function>xs</function>). The variables bound by
<listitem>
<para>
- Rules are automatically exported from a module, just as instance declarations are.
+ All rules are implicitly exported from the module, and are therefore
+in force in any module that imports the module that defined the rule, directly
+or indirectly. (That is, if A imports B, which imports C, then C's rules are
+in force when compiling A.) The situation is very similar to that for instance
+declarations.
+</para>
+</listitem>
+
+<listitem>
+
+<para>
+Inside a RULE "<literal>forall</literal>" is treated as a keyword, regardless of
+any other flag settings. Furthermore, inside a RULE, the language extension
+<option>-XScopedTypeVariables</option> is automatically enabled; see
+<xref linkend="scoped-type-variables"/>.
</para>
</listitem>
+<listitem>
+<para>
+Like other pragmas, RULE pragmas are always checked for scope errors, and
+are typechecked. Typechecking means that the LHS and RHS of a rule are typechecked,
+and must have the same type. However, rules are only <emphasis>enabled</emphasis>
+if the <option>-fenable-rewrite-rules</option> flag is
+on (see <xref linkend="rule-semantics"/>).
+</para>
+</listitem>
</itemizedlist>
</para>
</sect2>
-<sect2>
+<sect2 id="rule-semantics">
<title>Semantics</title>
<para>
<itemizedlist>
<listitem>
-
<para>
-Rules are only applied if you use the <option>-O</option> flag.
+Rules are enabled (that is, used during optimisation)
+by the <option>-fenable-rewrite-rules</option> flag.
+This flag is implied by <option>-O</option>, and may be switched
+off (as usual) by <option>-fno-enable-rewrite-rules</option>.
+(NB: enabling <option>-fenable-rewrite-rules</option> without <option>-O</option>
+may not do what you expect, though, because without <option>-O</option> GHC
+ignores all optimisation information in interface files;
+see <option>-fignore-interface-pragmas</option>, <xref linkend="options-f"/>.)
+Note that <option>-fenable-rewrite-rules</option> is an <emphasis>optimisation</emphasis> flag, and
+has no effect on parsing or typechecking.
</para>
</listitem>
<listitem>
<para>
- The LHS and RHS of a rule are typechecked, and must have the
-same type.
-
-</para>
-</listitem>
-<listitem>
-
-<para>
GHC makes absolutely no attempt to verify that the LHS and RHS
of a rule have the same meaning. That is undecidable in general, and
infeasible in most interesting cases. The responsibility is entirely the programmer's!
terminating. For example:
<programlisting>
- "loop" forall x,y. f x y = f y x
+ "loop" forall x y. f x y = f y x
</programlisting>
This rule will cause the compiler to go into an infinite loop.
<listitem>
<para>
- In the earlier phases of compilation, GHC inlines <emphasis>nothing
-that appears on the LHS of a rule</emphasis>, because once you have substituted
-for something you can't match against it (given the simple minded
-matching). So if you write the rule
-
+Ordinary inlining happens at the same time as rule rewriting, which may lead to unexpected
+results. Consider this (artificial) example
<programlisting>
- "map/map" forall f,g. map f . map g = map (f.g)
-</programlisting>
+f x = x
+{-# RULES "f" f True = False #-}
-this <emphasis>won't</emphasis> match the expression <literal>map f (map g xs)</literal>.
-It will only match something written with explicit use of ".".
-Well, not quite. It <emphasis>will</emphasis> match the expression
+g y = f y
-<programlisting>
-wibble f g xs
+h z = g True
</programlisting>
-
-where <function>wibble</function> is defined:
-
+Since <literal>f</literal>'s right-hand side is small, it is inlined into <literal>g</literal>,
+to give
<programlisting>
-wibble f g = map f . map g
+g y = y
</programlisting>
-
-because <function>wibble</function> will be inlined (it's small).
-
-Later on in compilation, GHC starts inlining even things on the
-LHS of rules, but still leaves the rules enabled. This inlining
-policy is controlled by the per-simplification-pass flag <option>-finline-phase</option><emphasis>n</emphasis>.
-
+Now <literal>g</literal> is inlined into <literal>h</literal>, but <literal>f</literal>'s RULE has
+no chance to fire.
+If instead GHC had first inlined <literal>g</literal> into <literal>h</literal> then there
+would have been a better chance that <literal>f</literal>'s RULE might fire.
</para>
-</listitem>
-<listitem>
-
<para>
- All rules are implicitly exported from the module, and are therefore
-in force in any module that imports the module that defined the rule, directly
-or indirectly. (That is, if A imports B, which imports C, then C's rules are
-in force when compiling A.) The situation is very similar to that for instance
-declarations.
+The way to get predictable behaviour is to use a NOINLINE
+pragma on <literal>f</literal>, to ensure
+that it is not inlined until its RULEs have had a chance to fire.
</para>
</listitem>
-
</itemizedlist>
</para>
</para>
<para>
- However, when external for is generated (via
+ However, when external core is generated (via
<option>-fext-core</option>), there will be Notes attached to the
expressions <function>show</function> and <varname>x</varname>.
The core function declaration for <function>f</function> is:
;;; Local Variables: ***
;;; mode: xml ***
;;; sgml-parent-document: ("users_guide.xml" "book" "chapter" "sect1") ***
+ ;;; ispell-local-dictionary: "british" ***
;;; End: ***
-->