{-#Extensions
Modules in jhc are searched for based on their name as in other Haskell compilers. However in addition to searching for 'Data/Foo.hs' for the module 'Data.Foo', jhc will also search for 'Data.Foo.hs'.
foreign C imports may return multiple values. To indicate this is the case, use an unboxed tuple as the return value. The first return value will be the value the function directly returns, the rest will be passed as pointers at the end of the functions argument list. Only pure (non IO) functions may return multiple values.
-- frexp has C prototype
-- double frexp(double x, int *exp);
-- so it would normally have an import like so, requiring the IO module and
-- Storable to call what is otherwise a pure function.
foreign import ccall "math.h frexp" c_frexp :: Double -> Ptr CInt -> IO Double
-- This extension allows it to be declared as so
foreign import ccall "math.h frexp" c_frexp2 :: Double -> (# Double, CInt #)
-- The second return value is added as the last 'exp' parameter then read out
-- of the allocated memory. The contents of the memory passed into the function
-- is undefined.
The 'capi' calling convention may be used instead of 'ccall' for static imports. The convention means that the foreign function may not be addressable as an address, but rather may be implemnted as a macro, builtin, or other compiler specific feature. jhc will ensure that the routine is never used as a pointer and the headers specified in the dependency string are included anywhere the imported function appears. This differs from 'ccall' in that ccall makes no guarentees the given header file will be in scope and that a linker symbol of the exact name is exported.
dependecies in a foreign import may be written as p:foo.c or p:foo.h, this means that the file should be interpreted as part of the internal implementation of the package. jhc willl ensure the files do not clash with those of other packages that may have the same name. The files should be listed in the c-files and c-headers sections of the library config file.
jhc allows explicit namespaces in import and export lists. These may be used to restrict or modiy what is imported/exported by a declaration.
* 'type' - The name is a type, as in something defined by 'type', 'newtype',
or 'data', or the constructors of a kind declaration.
* 'class' - Specifies that the name is that of a class.
* 'data' - Specifies that the name is a data constructor.
* 'kind' - specifies that the name is a user defined kind.
In addition, another extension is that classes and types are in independent namespaces, so a type and a class of the same name may be in scope and not conflict.
Jhc allows users to define custom kinds when the -fuser-kinds extension is enabled. The syntax is:
data kind Nat = Z | S Nat
This will define a new kind 'Nat' and two types 'Z' and 'S' which inhabit it. The types introduced by kind declarations represent unboxed values with no values, So they have no run-time representation (notably, not even ⊥)
Jhc supports a standalone deriving mechanism under certain circumstances.
Jhc supports higher ranked polymorphism. jhc will never infer types of higher rank, however when the context unambiguously specifies a higher ranked type, it will be used. For instance, user supplied type annotations and arguments to data constructors defined to by polymorphic will get the correct polymorphic type.
Jhc supports first class existential types, using the 'exists' keyword. It also supports existential data types in a similar fashion to ghc.
Unboxed values in jhc are specified in a similar fashion to GHC however the lexical syntax is not changed to allow # in identifiers. # is still used in the syntax for various unboxed constructs, but normal Haskell rules apply to haskell identifiers. The convention is to suffix such types with '_' to indicate their status as unboxed. All unboxed values other than unboxed tuples are enabled by the -funboxed-value flag. For compatibility with GHC, the MagicHash extension name also turns on unboxed-values.
Jhc supports unboxed tuples with the same syntax as GHC, (# 2, 4 #) is an unboxed tuple of two numbers. Unboxed tuples are enabled with -funboxed-tuples. Unboxed tuples are kind-polymorphic, able to hold both boxed and unboxed values. (but not another unboxed tuple)
Unboxed strings are enabled with the -funboxed-values flag. They are specified like a normal string but have a '#' at the end. Unboxed strings have types 'BitsPtr_'.
Unboxed characters can be expressed by putting a hash after a normal character literal. Unboxed characters are of type Char_ which is a newtype of Bits32_ and defined in Jhc.Prim.Bits
Unboxed numbers are enabled with the -funboxed-values flag. They are postpended with a '#' such as in 3# or 4#. Jhc supports a limited form of type inference for unboxed numbers, if the type is fully specified by the environment and it is a suitable unboxed numeric type then that type is used. Otherwise it defaults to Int__. Whether the type is fully specifed follows the same rules as rank-n types. Unboxed numbers do the right thing for enumerations, so 0# can be used for the unboxed False value and the appropriate type will be infered.
To operate on unboxed vaules you need to bring the appropriate primitive operators into scope. You can do this via the special form of FFI declaration for importing primitives. Any C-- primitive may be imported as well as a variety of utility routines. the primitive import mechanism is 'smart' in that it will dig through newtypes and take care of boxing/unboxing values as needed. So you can import a primitive on Char and it will take care of boxing the value up in the 'Char' constructor as well as the Char_ newtype for Bits32_, ultimately choosing the right Bits32_ primitive. imported primitives are normal haskell declarations so may be exported/imported from modules or passed as higher order functions like normal.