========================= Nim Experimental Features ========================= :Authors: Andreas Rumpf :Version: |nimversion| .. contents:: About this document =================== This document describes features of Nim that are to be considered experimental. Some of these are not covered by the ``.experimental`` pragma or ``--experimental`` switch because they are already behind a special syntax and one may want to use Nim libraries using these features without using them oneself. **Note**: Unless otherwise indicated, these features are not to be removed, but refined and overhauled. Package level objects ===================== Every Nim module resides in a (nimble) package. An object type can be attached to the package it resides in. If that is done, the type can be referenced from other modules as an `incomplete`:idx: object type. This feature allows to break up recursive type dependencies across module boundaries. Incomplete object types are always passed ``byref`` and can only be used in pointer like contexts (``var/ref/ptr IncompleteObject``) in general since the compiler does not yet know the size of the object. To complete an incomplete object the ``package`` pragma has to be used. ``package`` implies ``byref``. As long as a type ``T`` is incomplete, neither ``sizeof(T)`` nor runtime type information for ``T`` is available. Example: .. code-block:: nim # module A (in an arbitrary package) type Pack.SomeObject = object ## declare as incomplete object of package 'Pack' Triple = object a, b, c: ref SomeObject ## pointers to incomplete objects are allowed ## Incomplete objects can be used as parameters: proc myproc(x: SomeObject) = discard .. code-block:: nim # module B (in package "Pack") type SomeObject* {.package.} = object ## Use 'package' to complete the object s, t: string x, y: int Void type ========= The ``void`` type denotes the absence of any type. Parameters of type ``void`` are treated as non-existent, ``void`` as a return type means that the procedure does not return a value: .. code-block:: nim proc nothing(x, y: void): void = echo "ha" nothing() # writes "ha" to stdout The ``void`` type is particularly useful for generic code: .. code-block:: nim proc callProc[T](p: proc (x: T), x: T) = when T is void: p() else: p(x) proc intProc(x: int) = discard proc emptyProc() = discard callProc[int](intProc, 12) callProc[void](emptyProc) However, a ``void`` type cannot be inferred in generic code: .. code-block:: nim callProc(emptyProc) # Error: type mismatch: got (proc ()) # but expected one of: # callProc(p: proc (T), x: T) The ``void`` type is only valid for parameters and return types; other symbols cannot have the type ``void``. Covariance ========== Covariance in Nim can be introduced only through pointer-like types such as ``ptr`` and ``ref``. Sequence, Array and OpenArray types, instantiated with pointer-like types will be considered covariant if and only if they are also immutable. The introduction of a ``var`` modifier or additional ``ptr`` or ``ref`` indirections would result in invariant treatment of these types. ``proc`` types are currently always invariant, but future versions of Nim may relax this rule. User-defined generic types may also be covariant with respect to some of their parameters. By default, all generic params are considered invariant, but you may choose the apply the prefix modifier ``in`` to a parameter to make it contravariant or ``out`` to make it covariant:
mode = ScriptMode.Verbose
proc build() =
echo "building nim... "
exec "sleep 10"
exec "nonexistant command"
echo getCurrentDir()
echo "hello"
build()