manual: many additions and improvements
This commit is contained in:
parent
7c879d9b0f
commit
8c09ffd36d
1 changed files with 68 additions and 41 deletions
109
doc/manual.rst
109
doc/manual.rst
|
|
@ -598,6 +598,16 @@ whitespace (this parsing change was introduced with version 0.13.0):
|
||||||
echo($foo)
|
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
|
Grammar
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
@ -953,8 +963,8 @@ provides for ``string`` representation.
|
||||||
|
|
||||||
proc `$`(p: Person): string = # `$` always returns a string
|
proc `$`(p: Person): string = # `$` always returns a string
|
||||||
result = p.name & " is " &
|
result = p.name & " is " &
|
||||||
$p.age & # we *need* the `$` in front of p.age, which
|
$p.age & # we *need* the `$` in front of p.age which
|
||||||
# is natively an integer, to convert it to
|
# is natively an integer to convert it to
|
||||||
# a string
|
# a string
|
||||||
" years old."
|
" years old."
|
||||||
|
|
||||||
|
|
@ -1176,6 +1186,18 @@ of the assignment operator is described in `type-bound-operations-operator`_.
|
||||||
# the same, but less readable:
|
# the same, but less readable:
|
||||||
person = ("Peter", 30)
|
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
|
The implementation aligns the fields for best access performance. The alignment
|
||||||
is compatible with the way the C compiler does it.
|
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:
|
different; for this a special setter syntax is needed:
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
|
# Module asocket
|
||||||
type
|
type
|
||||||
Socket* = ref object of RootObj
|
Socket* = ref object of RootObj
|
||||||
FHost: int # cannot be accessed from the outside of the module
|
host: 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`
|
|
||||||
|
|
||||||
proc `host=`*(s: var Socket, value: int) {.inline.} =
|
proc `host=`*(s: var Socket, value: int) {.inline.} =
|
||||||
## setter of hostAddr
|
## setter of hostAddr.
|
||||||
s.FHost = value
|
## 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.} =
|
proc host*(s: Socket): int {.inline.} =
|
||||||
## getter of hostAddr
|
## 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
|
var s: Socket
|
||||||
new s
|
new s
|
||||||
s.host = 34 # same as `host=`(s, 34)
|
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.
|
or on the stack if the compiler determines that this would be safe.
|
||||||
|
|
||||||
Creating closures in loops
|
Creating closures in loops
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Since closures capture local variables by reference it is often not wanted
|
Since closures capture local variables by reference it is often not wanted
|
||||||
behavior inside loop bodies. See `closureScope <system.html#closureScope>`_
|
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.
|
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
|
Do notation
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
|
@ -4132,8 +4175,7 @@ The following example shows a generic binary tree can be modelled:
|
||||||
|
|
||||||
proc newNode*[T](data: T): BinaryTree[T] =
|
proc newNode*[T](data: T): BinaryTree[T] =
|
||||||
# constructor for a node
|
# constructor for a node
|
||||||
new(result)
|
result = BinaryTree(le: nil, ri: nil, data: data)
|
||||||
result.data = data
|
|
||||||
|
|
||||||
proc add*[T](root: var BinaryTree[T], n: BinaryTree[T]) =
|
proc add*[T](root: var BinaryTree[T], n: BinaryTree[T]) =
|
||||||
# insert a node into the tree
|
# 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):
|
for str in preorder(root):
|
||||||
stdout.writeLine(str)
|
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
|
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
|
pretends to be free of side effects, so that it can be used for debugging
|
||||||
routines marked as ``noSideEffect``.
|
routines marked as ``noSideEffect``.
|
||||||
|
|
||||||
**Future directions**: ``func`` may become a keyword and syntactic sugar for a
|
``func`` is syntactic sugar for a proc with no side effects:
|
||||||
proc with no side effects:
|
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
func `+` (x, y: int): int
|
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
|
compileTime pragma
|
||||||
------------------
|
------------------
|
||||||
The ``compileTime`` pragma is used to mark a proc or variable to be used at
|
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
|
final pragma
|
||||||
------------
|
------------
|
||||||
The ``final`` pragma can be used for an object type to specify that it
|
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
|
shallow pragma
|
||||||
|
|
@ -6363,7 +6390,7 @@ structure:
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
type
|
type
|
||||||
NodeKind = enum nkLeaf, nkInner
|
NodeKind = enum nkLeaf, nkInner
|
||||||
Node {.final, shallow.} = object
|
Node {.shallow.} = object
|
||||||
case kind: NodeKind
|
case kind: NodeKind
|
||||||
of nkLeaf:
|
of nkLeaf:
|
||||||
strVal: string
|
strVal: string
|
||||||
|
|
@ -6850,7 +6877,7 @@ underlying C ``struct`` in a ``sizeof`` expression:
|
||||||
.. code-block:: Nim
|
.. code-block:: Nim
|
||||||
type
|
type
|
||||||
DIR* {.importc: "DIR", header: "<dirent.h>",
|
DIR* {.importc: "DIR", header: "<dirent.h>",
|
||||||
final, pure, incompleteStruct.} = object
|
pure, incompleteStruct.} = object
|
||||||
|
|
||||||
|
|
||||||
Compile pragma
|
Compile pragma
|
||||||
|
|
@ -6983,7 +7010,7 @@ pragmas this allows *sloppy* interfacing with libraries written in C++:
|
||||||
irr = "<irrlicht/irrlicht.h>"
|
irr = "<irrlicht/irrlicht.h>"
|
||||||
|
|
||||||
type
|
type
|
||||||
IrrlichtDeviceObj {.final, header: irr,
|
IrrlichtDeviceObj {.header: irr,
|
||||||
importcpp: "IrrlichtDevice".} = object
|
importcpp: "IrrlichtDevice".} = object
|
||||||
IrrlichtDevice = ptr IrrlichtDeviceObj
|
IrrlichtDevice = ptr IrrlichtDeviceObj
|
||||||
|
|
||||||
|
|
@ -7006,7 +7033,7 @@ via the ``namespace::identifier`` notation:
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
type
|
type
|
||||||
IrrlichtDeviceObj {.final, header: irr,
|
IrrlichtDeviceObj {.header: irr,
|
||||||
importcpp: "irr::IrrlichtDevice".} = object
|
importcpp: "irr::IrrlichtDevice".} = object
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -7129,8 +7156,8 @@ Wrapping destructors
|
||||||
Since Nim generates C++ directly, any destructor is called implicitly by the
|
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
|
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
|
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
|
explicitly, it needs to be wrapped. The pattern language provides
|
||||||
everything that is required for that:
|
everything that is required:
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
proc destroyFoo(this: var Foo) {.importcpp: "#.~Foo()".}
|
proc destroyFoo(this: var Foo) {.importcpp: "#.~Foo()".}
|
||||||
|
|
@ -7297,7 +7324,7 @@ pragma description
|
||||||
const FooBar {.intdefine.}: int = 5
|
const FooBar {.intdefine.}: int = 5
|
||||||
echo FooBar
|
echo FooBar
|
||||||
|
|
||||||
.. code-block:: bash
|
::
|
||||||
nim c -d:FooBar=42 foobar.c
|
nim c -d:FooBar=42 foobar.c
|
||||||
|
|
||||||
In the above example, providing the -d flag causes the symbol
|
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
|
.. code-block:: nim
|
||||||
type
|
type
|
||||||
Vector {.bycopy, pure.} = object
|
Vector {.bycopy.} = object
|
||||||
x, y, z: float
|
x, y, z: float
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue