Skip to content
Snippets Groups Projects
Forked from Glasgow Haskell Compiler / GHC
18384 commits behind the upstream repository.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
glasgow_exts.rst 559.27 KiB

.. index::
single: language, GHC extensions

As with all known Haskell systems, GHC implements some extensions to the
standard Haskell language. They can all be enabled or disabled by command line
flags or language pragmas. By default GHC understands the most recent Haskell
version it supports, plus a handful of extensions.

Some of the Glasgow extensions serve to give you access to the
underlying facilities with which we implement Haskell. Thus, you can get
at the Raw Iron, if you are willing to write some non-portable code at a
more primitive level. You need not be “stuck” on performance because of
the implementation costs of Haskell's "high-level" features—you can
always code "under" them. In an extreme case, you can write all your
time-critical code in C, and then just glue it together with Haskell!

Before you get too carried away working at the lowest level (e.g.,
sloshing ``MutableByteArray#``\ s around your program), you may wish to
check if there are libraries that provide a "Haskellised veneer" over
the features you want. The separate
`libraries documentation <../libraries/index.html>`__ describes all the
libraries that come with GHC.

.. _options-language:

Language options
================

.. index::
single: language; option
single: options; language
single: extensions; options controlling

The language extensions control what variation of the language are
permitted.

Language options can be controlled in two ways:

- Every language option can switched on by a command-line flag
"``-X...``" (e.g. ``-XTemplateHaskell``), and switched off by the
flag "``-XNo...``"; (e.g. ``-XNoTemplateHaskell``).

- Language options recognised by Cabal can also be enabled using the
``LANGUAGE`` pragma, thus ``{-# LANGUAGE TemplateHaskell #-}`` (see
:ref:`language-pragma`).

GHC supports these language options:

.. extension-print::
:type: table

Although not recommended, the deprecated :ghc-flag:`-fglasgow-exts` flag enables
a large swath of the extensions supported by GHC at once.

.. ghc-flag:: -fglasgow-exts
:shortdesc: Deprecated. Enable most language extensions;
see :ref:`options-language` for exactly which ones.
:type: dynamic
:reverse: -fno-glasgow-exts
:category: misc

The flag ``-fglasgow-exts`` is equivalent to enabling the following extensions:

.. include:: what_glasgow_exts_does.rst

Enabling these options is the *only* effect of ``-fglasgow-exts``. We are trying
to move away from this portmanteau flag, and towards enabling features
individually.

.. _primitives:

Unboxed types and primitive operations
======================================

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 any luck, the code
you write will be optimised to the efficient unboxed version in any
case. And if it isn't, we'd like to know about it.

All these primitive data types and operations are exported by the
library ``GHC.Prim``, for which there is
:ghc-prim-ref:`detailed online documentation `. (This
documentation is generated from the file ``compiler/prelude/primops.txt.pp``.)

If you want to mention any of the primitive data types or operations in
your program, you must first import ``GHC.Prim`` to bring them into
scope. Many of them have names ending in ``#``, and to mention such names
you need the :extension:`MagicHash` extension.

The primops make extensive use of `unboxed types <#glasgow-unboxed>`__
and `unboxed tuples <#unboxed-tuples>`__, which we briefly summarise
here.

.. _glasgow-unboxed:

Unboxed types
-------------

Most types in GHC are boxed, which means that values of that type are
represented by a pointer to a heap object. The representation of a
Haskell ``Int``, for example, is a two-word heap object. An unboxed
type, however, is represented by the value itself, no pointers or heap
allocation are involved.

Unboxed types correspond to the “raw machine” types you would use in C:
``Int#`` (long int), ``Double#`` (double), ``Addr#`` (void \*), etc. The
*primitive operations* (PrimOps) on these types are what you might
expect; e.g., ``(+#)`` is addition on ``Int#``\ s, and is the
machine-addition that we all know and love—usually one instruction.

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.
(Note: a "boxed" type means that a value is represented by a pointer to a heap
object; a "lifted" type means that terms of that type may be bottom. See
the next paragraph for an example.)
We use the convention (but it is only a convention) that primitive
types, values, and operations have a ``#`` suffix (see
:ref:`magic-hash`). For some primitive types we have special syntax for
literals, also described in the `same section <#magic-hash>`__.

Primitive values are often represented by a simple bit-pattern, such as
``Int#``, ``Float#``, ``Double#``. But this is not necessarily the case:
a primitive value might be represented by a pointer to a heap-allocated
object. Examples include ``Array#``, the type of primitive arrays. Thus,
``Array#`` is an unlifted, boxed type. A
primitive array is heap-allocated because it is too big a value to fit
in a register, and would be too expensive to copy around; in a sense, it
is accidental that it is represented by a pointer. If a pointer
represents a primitive value, then it really does point to that value:
no unevaluated thunks, no indirections. Nothing can be at the other end
of the pointer than the primitive value. A numerically-intensive program
using unboxed types can go a *lot* faster than its “standard”
counterpart—we saw a threefold speedup on one example.