diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-04-14 14:53:31 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-04-14 14:53:31 +0200 |
commit | 8c09ffd36d8ec4e134ee6e5156aa46f4245cfa2a (patch) | |
tree | 43074e54c80f0c356707650f890b2e4397160798 /doc | |
parent | 7c879d9b0fada910bf6afc0a64d327f318a829de (diff) | |
download | Nim-8c09ffd36d8ec4e134ee6e5156aa46f4245cfa2a.tar.gz |
manual: many additions and improvements
Diffstat (limited to 'doc')
-rw-r--r-- | doc/manual.rst | 109 |
1 files changed, 68 insertions, 41 deletions
diff --git a/doc/manual.rst b/doc/manual.rst index e41d5c406..ea5a2462e 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -598,6 +598,16 @@ whitespace (this parsing change was introduced with version 0.13.0): echo($foo) +Spacing also determines whether ``(a, b)`` is parsed as an the argument list +of a call or whether it is parsed as a tuple constructor: + +.. code-block:: nim + echo(1, 2) # pass 1 and 2 to echo + +.. code-block:: nim + echo (1, 2) # pass the tuple (1, 2) to echo + + Grammar ------- @@ -953,8 +963,8 @@ provides for ``string`` representation. proc `$`(p: Person): string = # `$` always returns a string result = p.name & " is " & - $p.age & # we *need* the `$` in front of p.age, which - # is natively an integer, to convert it to + $p.age & # we *need* the `$` in front of p.age which + # is natively an integer to convert it to # a string " years old." @@ -1176,6 +1186,18 @@ of the assignment operator is described in `type-bound-operations-operator`_. # the same, but less readable: person = ("Peter", 30) +A tuple with one unnamed field can be constructed with the parentheses and a +trailing comma: + +.. code-block:: nim + proc echoUnaryTuple(a: (int,)) = + echo a[0] + + echoUnaryTuple (1,) + + +In fact, a trailing comma is allowed for every tuple construction. + The implementation aligns the fields for best access performance. The alignment is compatible with the way the C compiler does it. @@ -3237,21 +3259,28 @@ with the *method call syntax* achieve the same. But setting a value is different; for this a special setter syntax is needed: .. code-block:: nim - + # Module asocket type Socket* = ref object of RootObj - FHost: int # cannot be accessed from the outside of the module - # the `F` prefix is a convention to avoid clashes since - # the accessors are named `host` + host: int # cannot be accessed from the outside of the module proc `host=`*(s: var Socket, value: int) {.inline.} = - ## setter of hostAddr - s.FHost = value + ## setter of hostAddr. + ## This accesses the 'host' field and is not a recursive call to + ## ``host=`` because the builtin dot access is preferred if it is + ## avaliable: + s.host = value proc host*(s: Socket): int {.inline.} = ## getter of hostAddr - s.FHost + ## This accesses the 'host' field and is not a recursive call to + ## ``host`` because the builtin dot access is preferred if it is + ## avaliable: + s.host +.. code-block:: nim + # module B + import asocket var s: Socket new s s.host = 34 # same as `host=`(s, 34) @@ -3298,7 +3327,7 @@ visible in both places). The closure environment may be allocated on the heap or on the stack if the compiler determines that this would be safe. Creating closures in loops -~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~ Since closures capture local variables by reference it is often not wanted behavior inside loop bodies. See `closureScope <system.html#closureScope>`_ @@ -3321,6 +3350,20 @@ Procs as expressions can appear both as nested procs and inside top level executable code. +Func +---- + +The ``func`` keyword introduces a shortcut for a `noSideEffect`:idx: proc. + +.. code-block:: nim + func binarySearch[T](a: openArray[T]; elem: T): int + +Is short for: + +.. code-block:: nim + proc binarySearch[T](a: openArray[T]; elem: T): int {.noSideEffect.} + + Do notation ----------- @@ -4132,8 +4175,7 @@ The following example shows a generic binary tree can be modelled: proc newNode*[T](data: T): BinaryTree[T] = # constructor for a node - new(result) - result.data = data + result = BinaryTree(le: nil, ri: nil, data: data) proc add*[T](root: var BinaryTree[T], n: BinaryTree[T]) = # insert a node into the tree @@ -4179,7 +4221,8 @@ The following example shows a generic binary tree can be modelled: for str in preorder(root): stdout.writeLine(str) -The ``T`` is called a `generic type parameter`:idx:. +The ``T`` is called a `generic type parameter`:idx: or +a `type variable`:idx:. Is operator @@ -6258,30 +6301,12 @@ As a special semantic rule, the built-in `debugEcho <system.html#debugEcho>`_ pretends to be free of side effects, so that it can be used for debugging routines marked as ``noSideEffect``. -**Future directions**: ``func`` may become a keyword and syntactic sugar for a -proc with no side effects: +``func`` is syntactic sugar for a proc with no side effects: .. code-block:: nim func `+` (x, y: int): int -destructor pragma ------------------ - -The ``destructor`` pragma is used to mark a proc to act as a type destructor. -Its usage is deprecated, see `type bound operations`_ instead. - -override pragma ---------------- - -See `type bound operations`_ instead. - -procvar pragma --------------- -The ``procvar`` pragma is used to mark a proc that it can be passed to a -procedural variable. - - compileTime pragma ------------------ The ``compileTime`` pragma is used to mark a proc or variable to be used at @@ -6348,7 +6373,9 @@ memory, but nothing worse happens. final pragma ------------ The ``final`` pragma can be used for an object type to specify that it -cannot be inherited from. +cannot be inherited from. Note that inheritance is only available for +objects that inherit from an existing object (via the ``object of SuperType`` +syntax) or that have been marked as ``inheritable``. shallow pragma @@ -6363,7 +6390,7 @@ structure: .. code-block:: nim type NodeKind = enum nkLeaf, nkInner - Node {.final, shallow.} = object + Node {.shallow.} = object case kind: NodeKind of nkLeaf: strVal: string @@ -6850,7 +6877,7 @@ underlying C ``struct`` in a ``sizeof`` expression: .. code-block:: Nim type DIR* {.importc: "DIR", header: "<dirent.h>", - final, pure, incompleteStruct.} = object + pure, incompleteStruct.} = object Compile pragma @@ -6983,7 +7010,7 @@ pragmas this allows *sloppy* interfacing with libraries written in C++: irr = "<irrlicht/irrlicht.h>" type - IrrlichtDeviceObj {.final, header: irr, + IrrlichtDeviceObj {.header: irr, importcpp: "IrrlichtDevice".} = object IrrlichtDevice = ptr IrrlichtDeviceObj @@ -7006,7 +7033,7 @@ via the ``namespace::identifier`` notation: .. code-block:: nim type - IrrlichtDeviceObj {.final, header: irr, + IrrlichtDeviceObj {.header: irr, importcpp: "irr::IrrlichtDevice".} = object @@ -7129,8 +7156,8 @@ Wrapping destructors Since Nim generates C++ directly, any destructor is called implicitly by the C++ compiler at the scope exits. This means that often one can get away with not wrapping the destructor at all! However when it needs to be invoked -explicitly, it needs to be wrapped. But the pattern language already provides -everything that is required for that: +explicitly, it needs to be wrapped. The pattern language provides +everything that is required: .. code-block:: nim proc destroyFoo(this: var Foo) {.importcpp: "#.~Foo()".} @@ -7297,7 +7324,7 @@ pragma description const FooBar {.intdefine.}: int = 5 echo FooBar -.. code-block:: bash +:: nim c -d:FooBar=42 foobar.c In the above example, providing the -d flag causes the symbol @@ -7452,7 +7479,7 @@ instructs the compiler to pass the type by value to procs: .. code-block:: nim type - Vector {.bycopy, pure.} = object + Vector {.bycopy.} = object x, y, z: float |