diff options
Diffstat (limited to 'doc/manual')
-rw-r--r-- | doc/manual/exceptions.txt | 2 | ||||
-rw-r--r-- | doc/manual/ffi.txt | 30 | ||||
-rw-r--r-- | doc/manual/generics.txt | 12 | ||||
-rw-r--r-- | doc/manual/lexing.txt | 2 | ||||
-rw-r--r-- | doc/manual/locking.txt | 6 | ||||
-rw-r--r-- | doc/manual/pragmas.txt | 44 | ||||
-rw-r--r-- | doc/manual/procs.txt | 10 | ||||
-rw-r--r-- | doc/manual/special_ops.txt | 3 | ||||
-rw-r--r-- | doc/manual/stmts.txt | 3 | ||||
-rw-r--r-- | doc/manual/syntax.txt | 50 | ||||
-rw-r--r-- | doc/manual/templates.txt | 26 | ||||
-rw-r--r-- | doc/manual/trmacros.txt | 18 | ||||
-rw-r--r-- | doc/manual/type_rel.txt | 54 | ||||
-rw-r--r-- | doc/manual/typedesc.txt | 32 | ||||
-rw-r--r-- | doc/manual/types.txt | 20 |
15 files changed, 164 insertions, 148 deletions
diff --git a/doc/manual/exceptions.txt b/doc/manual/exceptions.txt index e7af65386..d06c13df4 100644 --- a/doc/manual/exceptions.txt +++ b/doc/manual/exceptions.txt @@ -155,4 +155,4 @@ Exception hierarchy The exception tree is defined in the `system <system.html>`_ module: -.. include:: exception_hierarchy_fragment.txt +.. include:: ../exception_hierarchy_fragment.txt diff --git a/doc/manual/ffi.txt b/doc/manual/ffi.txt index f08be6ad3..d7d9596d2 100644 --- a/doc/manual/ffi.txt +++ b/doc/manual/ffi.txt @@ -16,11 +16,19 @@ spelled*: .. code-block:: proc printf(formatstr: cstring) {.header: "<stdio.h>", importc: "printf", varargs.} -Note that this pragma is somewhat of a misnomer: Other backends will provide +Note that this pragma is somewhat of a misnomer: Other backends do provide the same feature under the same name. Also, if one is interfacing with C++ -the `ImportCpp pragma <nimc.html#importcpp-pragma>`_ and +the `ImportCpp pragma <manual.html#implementation-specific-pragmas-importcpp-pragma>`_ and interfacing with Objective-C the `ImportObjC pragma -<nimc.html#importobjc-pragma>`_ can be used. +<manual.html#implementation-specific-pragmas-importobjc-pragma>`_ can be used. + +The string literal passed to ``importc`` can be a format string: + +.. code-block:: Nim + proc p(s: cstring) {.importc: "prefix$1".} + +In the example the external name of ``p`` is set to ``prefixp``. Only ``$1`` +is available and a literal dollar sign must be written as ``$$``. Exportc pragma @@ -33,9 +41,19 @@ name is the Nim identifier *exactly as spelled*: .. code-block:: Nim proc callme(formatstr: cstring) {.exportc: "callMe", varargs.} -Note that this pragma is somewhat of a misnomer: Other backends will provide +Note that this pragma is somewhat of a misnomer: Other backends do provide the same feature under the same name. +The string literal passed to ``exportc`` can be a format string: + +.. code-block:: Nim + proc p(s: string) {.exportc: "prefix$1".} = + echo s + +In the example the external name of ``p`` is set to ``prefixp``. Only ``$1`` +is available and a literal dollar sign must be written as ``$$``. + + Extern pragma ------------- @@ -46,7 +64,9 @@ mangling. The string literal passed to ``extern`` can be a format string: proc p(s: string) {.extern: "prefix$1".} = echo s -In the example the external name of ``p`` is set to ``prefixp``. +In the example the external name of ``p`` is set to ``prefixp``. Only ``$1`` +is available and a literal dollar sign must be written as ``$$``. + Bycopy pragma diff --git a/doc/manual/generics.txt b/doc/manual/generics.txt index 07d98b289..c1c6467e7 100644 --- a/doc/manual/generics.txt +++ b/doc/manual/generics.txt @@ -232,16 +232,6 @@ type signatures of the required operations, but since type inference and default parameters are still applied in the provided block, it's also possible to encode usage protocols that do not reveal implementation details. -As a special rule providing further convenience when writing concepts, any -type value appearing in a callable expression will be treated as a variable of -the designated type for overload resolution purposes, unless the type value was -passed in its explicit ``typedesc[T]`` form: - -.. code-block:: nim - type - OutputStream = concept s - write(var s, string) - Much like generics, concepts are instantiated exactly once for each tested type and any static code included within them is also executed once. @@ -303,7 +293,7 @@ definition): var lastId = 0 - template genId*: expr = + template genId*: untyped = bind lastId inc(lastId) lastId diff --git a/doc/manual/lexing.txt b/doc/manual/lexing.txt index 4187a60a4..4d03023c3 100644 --- a/doc/manual/lexing.txt +++ b/doc/manual/lexing.txt @@ -116,7 +116,7 @@ operator characters instead. The following keywords are reserved and cannot be used as identifiers: .. code-block:: nim - :file: keywords.txt + :file: ../keywords.txt Some keywords are unused; they are reserved for future developments of the language. diff --git a/doc/manual/locking.txt b/doc/manual/locking.txt index b14c98636..c00efdd91 100644 --- a/doc/manual/locking.txt +++ b/doc/manual/locking.txt @@ -48,7 +48,7 @@ semantics and should not be used directly! It should only be used in templates that also implement some form of locking at runtime: .. code-block:: nim - template lock(a: TLock; body: stmt) = + template lock(a: TLock; body: untyped) = pthread_mutex_lock(a) {.locks: [a].}: try: @@ -64,7 +64,7 @@ model low level lockfree mechanisms: var dummyLock {.compileTime.}: int var atomicCounter {.guard: dummyLock.}: int - template atomicRead(x): expr = + template atomicRead(x): untyped = {.locks: [dummyLock].}: memoryReadBarrier() x @@ -167,7 +167,7 @@ the runtime check is required to ensure a global ordering for two locks ``a`` and ``b`` of the same lock level: .. code-block:: nim - template multilock(a, b: ptr TLock; body: stmt) = + template multilock(a, b: ptr TLock; body: untyped) = if cast[ByteAddress](a) < cast[ByteAddress](b): pthread_mutex_lock(a) pthread_mutex_lock(b) diff --git a/doc/manual/pragmas.txt b/doc/manual/pragmas.txt index f89194c9a..70fc4a914 100644 --- a/doc/manual/pragmas.txt +++ b/doc/manual/pragmas.txt @@ -55,7 +55,7 @@ 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. +Its usage is deprecated, see `type bound operations`_ instead. override pragma --------------- @@ -213,7 +213,7 @@ statement as seen in stack backtraces: .. code-block:: nim - template myassert*(cond: expr, msg = "") = + template myassert*(cond: untyped, msg = "") = if not cond: # change run-time line information of the 'raise' statement: {.line: InstantiationInfo().}: @@ -518,11 +518,16 @@ Example: .. code-block:: nim {.experimental.} + type + FooId = distinct int + BarId = distinct int + using + foo: FooId + bar: BarId - proc useUsing(dest: var string) = - using dest - add "foo" - add "bar" + proc useUsing(bar, foo) = + echo "bar is of type BarId" + echo "foo is of type FooId" Implementation Specific Pragmas @@ -1006,3 +1011,30 @@ debugging: # ... complex code here that produces crashes ... +compile time define pragmas +--------------------------- + +The pragmas listed here can be used to optionally accept values from +the -d/--define option at compile time. + +The implementation currently provides the following possible options (various +others may be added later). + +=============== ============================================ +pragma description +=============== ============================================ +intdefine Reads in a build-time define as an integer +strdefine Reads in a build-time define as a string +=============== ============================================ + +.. code-block:: nim + 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 +``FooBar`` to be overwritten at compile time, printing out 42. If the +``-d:FooBar=42`` were to be omitted, the default value of 5 would be +used. diff --git a/doc/manual/procs.txt b/doc/manual/procs.txt index 9ce92de0d..ea6866845 100644 --- a/doc/manual/procs.txt +++ b/doc/manual/procs.txt @@ -215,6 +215,12 @@ the closure and its enclosing scope (i.e. any modifications made to them are 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>`_ +for details on how to change this behavior. Anonymous Procs --------------- @@ -223,7 +229,7 @@ Procs can also be treated as expressions, in which case it's allowed to omit the proc's name. .. code-block:: nim - var cities = @["Frankfurt", "Tokyo", "New York"] + var cities = @["Frankfurt", "Tokyo", "New York", "Kyiv"] cities.sort(proc (x,y: string): int = cmp(x.len, y.len)) @@ -619,7 +625,7 @@ Note that ``system.finished`` is error prone to use because it only returns 3 0 -Instead this code has be used: +Instead this code has to be used: .. code-block:: nim var c = mycount # instantiate the iterator diff --git a/doc/manual/special_ops.txt b/doc/manual/special_ops.txt index 702693423..1c7136bec 100644 --- a/doc/manual/special_ops.txt +++ b/doc/manual/special_ops.txt @@ -4,6 +4,9 @@ Special Operators dot operators ------------- +**Note**: Dot operators are still experimental and so need to be enabled +via ``{.experimental.}``. + Nim offers a special family of dot operators that can be used to intercept and rewrite proc call and field access attempts, referring to previously undeclared symbol names. They can be used to provide a diff --git a/doc/manual/stmts.txt b/doc/manual/stmts.txt index 65c810cf7..318738063 100644 --- a/doc/manual/stmts.txt +++ b/doc/manual/stmts.txt @@ -577,6 +577,9 @@ name ``c`` should default to type ``Context``, ``n`` should default to The ``using`` section uses the same indentation based grouping syntax as a ``var`` or ``let`` section. +Note that ``using`` is not applied for ``template`` since untyped template +parameters default to the type ``system.untyped``. + If expression ------------- diff --git a/doc/manual/syntax.txt b/doc/manual/syntax.txt index ca3b582ca..89f8ca707 100644 --- a/doc/manual/syntax.txt +++ b/doc/manual/syntax.txt @@ -19,10 +19,8 @@ other binary operators are left-associative. proc `^/`(x, y: float): float = # a right-associative division operator result = x / y - echo 12 ^/ 4 ^/ 8 # 24.0 (4 / 8 = 0.5, then - 12 / 0.5 = 24.0) - echo 12 / 4 / 8 # 0.375 (12 / 4 = 3.0, then - 3 / 8 = 0.375) + echo 12 ^/ 4 ^/ 8 # 24.0 (4 / 8 = 0.5, then 12 / 0.5 = 24.0) + echo 12 / 4 / 8 # 0.375 (12 / 4 = 3.0, then 3 / 8 = 0.375) Precedence ---------- @@ -72,53 +70,11 @@ Whether an operator is used a prefix operator is also affected by preceeding whi echo($foo) -Strong spaces -------------- - -The number of spaces preceding a non-keyword operator affects precedence -if the experimental parser directive ``#?strongSpaces`` is used. Indentation -is not used to determine the number of spaces. If 2 or more operators have the -same number of preceding spaces the precedence table applies, so ``1 + 3 * 4`` -is still parsed as ``1 + (3 * 4)``, but ``1+3 * 4`` is parsed as ``(1+3) * 4``: - -.. code-block:: nim - #? strongSpaces - if foo+4 * 4 == 8 and b&c | 9 ++ - bar: - echo "" - # is parsed as - if ((foo+4)*4 == 8) and (((b&c) | 9) ++ bar): echo "" - - -Furthermore whether an operator is used a prefix operator is affected by the -number of spaces: - -.. code-block:: nim - #? strongSpaces - echo $foo - # is parsed as - echo($foo) - -This also affects whether ``[]``, ``{}``, ``()`` are parsed as constructors -or as accessors: - -.. code-block:: nim - #? strongSpaces - echo (1,2) - # is parsed as - echo((1,2)) - -Only 0, 1, 2, 4 or 8 spaces are allowed to specify precedence and it is -enforced that infix operators have the same amount of spaces before and after -them. This rules does not apply when a newline follows after the operator, -then only the preceding spaces are considered. - - Grammar ------- The grammar's start symbol is ``module``. -.. include:: grammar.txt +.. include:: ../grammar.txt :literal: diff --git a/doc/manual/templates.txt b/doc/manual/templates.txt index b60fe632e..be5c6fa18 100644 --- a/doc/manual/templates.txt +++ b/doc/manual/templates.txt @@ -57,8 +57,7 @@ A template where every parameter is ``untyped`` is called an `immediate`:idx: template. For historical reasons templates can be explicitly annotated with an ``immediate`` pragma and then these templates do not take part in overloading resolution and the parameters' types are *ignored* by the -compiler. Explicit immediate templates are about to be deprecated in later -versions of the compiler. +compiler. Explicit immediate templates are now deprecated. **Note**: For historical reasons ``stmt`` is an alias for ``typed`` and ``expr`` an alias for ``untyped``, but new code should use the newer, @@ -159,7 +158,7 @@ bound from the definition scope of the template: var lastId = 0 - template genId*: expr = + template genId*: untyped = inc(lastId) lastId @@ -181,7 +180,7 @@ In templates identifiers can be constructed with the backticks notation: .. code-block:: nim - template typedef(name: expr, typ: typedesc) {.immediate.} = + template typedef(name: untyped, typ: typedesc) = type `T name`* {.inject.} = typ `P name`* {.inject.} = ref `T name` @@ -242,7 +241,7 @@ template cannot be accessed in the instantiation context: .. code-block:: nim - template newException*(exceptn: typedesc, message: string): expr = + template newException*(exceptn: typedesc, message: string): untyped = var e: ref exceptn # e is implicitly gensym'ed here new(e) @@ -264,7 +263,7 @@ is ``gensym`` and for ``proc``, ``iterator``, ``converter``, ``template``, template parameter, it is an inject'ed symbol: .. code-block:: nim - template withFile(f, fn, mode: expr, actions: stmt): stmt {.immediate.} = + template withFile(f, fn, mode: untyped, actions: untyped): untyped = block: var f: File # since 'f' is a template param, it's injected implicitly ... @@ -298,7 +297,7 @@ rewritten to ``f(x)``. Therefore the dot syntax has some limiations when it is used to invoke templates/macros: .. code-block:: nim - template declareVar(name: expr): stmt = + template declareVar(name: untyped) = const name {.inject.} = 45 # Doesn't compile: @@ -325,8 +324,7 @@ Macros ====== A macro is a special kind of low level template. Macros can be used -to implement `domain specific languages`:idx:. Like templates, macros come in -the 2 flavors *immediate* and *ordinary*. +to implement `domain specific languages`:idx:. While macros enable advanced compile-time code transformations, they cannot change Nim's syntax. However, this is no real restriction because @@ -351,7 +349,7 @@ variable number of arguments: # ``macros`` module: import macros - macro debug(n: varargs[expr]): stmt = + macro debug(n: varargs[untyped]): untyped = # `n` is a Nim AST that contains the whole macro invocation # this macro returns a list of statements: result = newNimNode(nnkStmtList, n) @@ -406,7 +404,7 @@ builtin can be used for that: .. code-block:: nim import macros - macro debug(n: varargs[expr]): stmt = + macro debug(n: varargs[typed]): untyped = result = newNimNode(nnkStmtList, n) for i in 0..n.len-1: # we can bind symbols in scope via 'bindSym': @@ -454,7 +452,7 @@ regular expressions: .. code-block:: nim import macros - macro case_token(n: stmt): stmt = + macro case_token(n: untyped): untyped = # creates a lexical analyzer from regular expressions # ... (implementation is an exercise for the reader :-) discard @@ -486,14 +484,14 @@ Whole routines (procs, iterators etc.) can also be passed to a template or a macro via the pragma notation: .. code-block:: nim - template m(s: stmt) = discard + template m(s: untyped) = discard proc p() {.m.} = discard This is a simple syntactic transformation into: .. code-block:: nim - template m(s: stmt) = discard + template m(s: untyped) = discard m: proc p() = discard diff --git a/doc/manual/trmacros.txt b/doc/manual/trmacros.txt index 446896e28..0845cebf5 100644 --- a/doc/manual/trmacros.txt +++ b/doc/manual/trmacros.txt @@ -135,7 +135,7 @@ The ``|`` operator The ``|`` operator if used as infix operator creates an ordered choice: .. code-block:: nim - template t{0|1}(): expr = 3 + template t{0|1}(): untyped = 3 let a = 1 # outputs 3: echo a @@ -144,7 +144,7 @@ The matching is performed after the compiler performed some optimizations like constant folding, so the following does not work: .. code-block:: nim - template t{0|1}(): expr = 3 + template t{0|1}(): untyped = 3 # outputs 1: echo 1 @@ -161,7 +161,7 @@ A pattern expression can be bound to a pattern parameter via the ``expr{param}`` notation: .. code-block:: nim - template t{(0|1|2){x}}(x: expr): expr = x+1 + template t{(0|1|2){x}}(x: untyped): untyped = x+1 let a = 1 # outputs 2: echo a @@ -173,7 +173,7 @@ The ``~`` operator The ``~`` operator is the **not** operator in patterns: .. code-block:: nim - template t{x = (~x){y} and (~x){z}}(x, y, z: bool): stmt = + template t{x = (~x){y} and (~x){z}}(x, y, z: bool) = x = y if x: x = z @@ -200,7 +200,7 @@ to ``&(a, b, c)``: for i in 1..len(s)-1: result.add s[i] inc calls - template optConc{ `&&` * a }(a: string): expr = &&a + template optConc{ `&&` * a }(a: string): untyped = &&a let space = " " echo "my" && (space & "awe" && "some " ) && "concat" @@ -239,7 +239,7 @@ all the arguments, but also the matched operators in reverse polish notation: proc mat21(): Matrix = result.dummy = 21 - macro optM{ (`+`|`-`|`*`) ** a }(a: Matrix): expr = + macro optM{ (`+`|`-`|`*`) ** a }(a: Matrix): untyped = echo treeRepr(a) result = newCall(bindSym"mat21") @@ -273,7 +273,7 @@ parameter is of the type ``varargs`` it is treated specially and it can match template optWrite{ write(f, x) ((write|writeLine){w})(f, y) - }(x, y: varargs[expr], f: File, w: expr) = + }(x, y: varargs[untyped], f: File, w: untyped) = w(f, x, y) @@ -288,8 +288,8 @@ implemented with term rewriting: proc p(x, y: int; cond: bool): int = result = if cond: x + y else: x - y - template optP1{p(x, y, true)}(x, y: expr): expr = x + y - template optP2{p(x, y, false)}(x, y: expr): expr = x - y + template optP1{p(x, y, true)}(x, y: untyped): untyped = x + y + template optP2{p(x, y, false)}(x, y: untyped): untyped = x - y Example: Hoisting diff --git a/doc/manual/type_rel.txt b/doc/manual/type_rel.txt index d62cf65c3..5b68f73aa 100644 --- a/doc/manual/type_rel.txt +++ b/doc/manual/type_rel.txt @@ -313,42 +313,78 @@ matches better than just ``T`` then. Automatic dereferencing ----------------------- -If the `experimental mode <experimental pragma>`_ is active and no other match +If the `experimental mode <#pragmas-experimental-pragma>`_ is active and no other match is found, the first argument ``a`` is dereferenced automatically if it's a pointer type and overloading resolution is tried with ``a[]`` instead. +Automatic self insertions +------------------------- -Lazy type resolution for expr ------------------------------ +Starting with version 0.14 of the language, Nim supports ``field`` as a +shortcut for ``self.field`` comparable to the `this`:idx: keyword in Java +or C++. This feature has to be explicitly enabled via a ``{.this: self.}`` +statement pragma. This pragma is active for the rest of the module: + +.. code-block:: nim + type + Parent = object of RootObj + parentField: int + Child = object of Parent + childField: int + + {.this: self.} + proc sumFields(self: Child): int = + result = parentField + childField + # is rewritten to: + # result = self.parentField + self.childField + +Instead of ``self`` any other identifier can be used too, but +``{.this: self.}`` will become the default directive for the whole language +eventually. + +In addition to fields, routine applications are also rewritten, but only +if no other interpretation of the call is possible: + +.. code-block:: nim + proc test(self: Child) = + echo childField, " ", sumFields() + # is rewritten to: + echo self.childField, " ", sumFields(self) + # but NOT rewritten to: + echo self, self.childField, " ", sumFields(self) + + +Lazy type resolution for untyped +-------------------------------- **Note**: An `unresolved`:idx: expression is an expression for which no symbol lookups and no type checking have been performed. Since templates and macros that are not declared as ``immediate`` participate in overloading resolution it's essential to have a way to pass unresolved -expressions to a template or macro. This is what the meta-type ``expr`` +expressions to a template or macro. This is what the meta-type ``untyped`` accomplishes: .. code-block:: nim - template rem(x: expr) = discard + template rem(x: untyped) = discard rem unresolvedExpression(undeclaredIdentifier) -A parameter of type ``expr`` always matches any argument (as long as there is +A parameter of type ``untyped`` always matches any argument (as long as there is any argument passed to it). But one has to watch out because other overloads might trigger the argument's resolution: .. code-block:: nim - template rem(x: expr) = discard + template rem(x: untyped) = discard proc rem[T](x: T) = discard # undeclared identifier: 'unresolvedExpression' rem unresolvedExpression(undeclaredIdentifier) -``expr`` is the only metatype that is lazy in this sense, the other -metatypes ``stmt`` and ``typedesc`` are not lazy. +``untyped`` and ``varargs[untyped]`` are the only metatype that are lazy in this sense, the other +metatypes ``typed`` and ``typedesc`` are not lazy. Varargs matching diff --git a/doc/manual/typedesc.txt b/doc/manual/typedesc.txt index de1d84d7d..6922d77e4 100644 --- a/doc/manual/typedesc.txt +++ b/doc/manual/typedesc.txt @@ -77,38 +77,6 @@ Once bound, typedesc params can appear in the rest of the proc signature: declareVariableWithType int, 42 -When used with macros and .compileTime. procs on the other hand, the compiler -does not need to instantiate the code multiple times, because types then can be -manipulated using the unified internal symbol representation. In such context -typedesc acts as any other type. One can create variables, store typedesc -values inside containers and so on. For example, here is how one can create -a type-safe wrapper for the unsafe `printf` function from C: - -.. code-block:: nim - macro safePrintF(formatString: string{lit}, args: varargs[expr]): expr = - var i = 0 - for c in formatChars(formatString): - var expectedType = case c - of 'c': char - of 'd', 'i', 'x', 'X': int - of 'f', 'e', 'E', 'g', 'G': float - of 's': string - of 'p': pointer - else: EOutOfRange - - var actualType = args[i].getType - inc i - - if expectedType == EOutOfRange: - error c & " is not a valid format character" - elif expectedType != actualType: - error "type mismatch for argument ", i, ". expected type: ", - expectedType.name, ", actual type: ", actualType.name - - # keep the original callsite, but use cprintf instead - result = callsite() - result[0] = newIdentNode(!"cprintf") - Overload resolution can be further influenced by constraining the set of types that will match the typedesc param: diff --git a/doc/manual/types.txt b/doc/manual/types.txt index a1596bcea..1e2dc857f 100644 --- a/doc/manual/types.txt +++ b/doc/manual/types.txt @@ -435,7 +435,9 @@ has the same type. Arrays always have a fixed length which is specified at compile time (except for open arrays). They can be indexed by any ordinal type. A parameter ``A`` may be an *open array*, in which case it is indexed by integers from 0 to ``len(A)-1``. An array expression may be constructed by the -array constructor ``[]``. +array constructor ``[]``. The element type of this array expression is +inferred from the type of the first element. All other elements need to be +implicitly convertable to this type. Sequences are similar to arrays but of dynamic length which may change during runtime (like strings). Sequences are implemented as growable arrays, @@ -460,6 +462,8 @@ Example: x = [1, 2, 3, 4, 5, 6] # [] is the array constructor y = @[1, 2, 3, 4, 5, 6] # the @ turns the array into a sequence + let z = [1.0, 2, 3, 4] # the type of z is array[0..3, float] + The lower bound of an array or sequence may be received by the built-in proc ``low()``, the higher bound by ``high()``. The length may be received by ``len()``. ``low()`` for a sequence or an open array always returns @@ -539,12 +543,12 @@ not wrapped in another implicit array construction: takeV([123, 2, 1]) # takeV's T is "int", not "array of int" -``varargs[expr]`` is treated specially: It matches a variable list of arguments +``varargs[typed]`` is treated specially: It matches a variable list of arguments of arbitrary type but *always* constructs an implicit array. This is required so that the builtin ``echo`` proc does what is expected: .. code-block:: nim - proc echo*(x: varargs[expr, `$`]) {...} + proc echo*(x: varargs[typed, `$`]) {...} echo @[1, 2, 3] # prints "@[1, 2, 3]" and not "123" @@ -694,7 +698,7 @@ branch switch ``system.reset`` has to be used. Set type -------- -.. include:: sets_fragment.txt +.. include:: ../sets_fragment.txt Reference and pointer types --------------------------- @@ -1082,7 +1086,7 @@ But it seems all this boilerplate code needs to be repeated for the ``Euro`` currency. This can be solved with templates_. .. code-block:: nim - template additive(typ: typedesc): stmt = + template additive(typ: typedesc) = proc `+` *(x, y: typ): typ {.borrow.} proc `-` *(x, y: typ): typ {.borrow.} @@ -1090,18 +1094,18 @@ currency. This can be solved with templates_. proc `+` *(x: typ): typ {.borrow.} proc `-` *(x: typ): typ {.borrow.} - template multiplicative(typ, base: typedesc): stmt = + template multiplicative(typ, base: typedesc) = proc `*` *(x: typ, y: base): typ {.borrow.} proc `*` *(x: base, y: typ): typ {.borrow.} proc `div` *(x: typ, y: base): typ {.borrow.} proc `mod` *(x: typ, y: base): typ {.borrow.} - template comparable(typ: typedesc): stmt = + template comparable(typ: typedesc) = proc `<` * (x, y: typ): bool {.borrow.} proc `<=` * (x, y: typ): bool {.borrow.} proc `==` * (x, y: typ): bool {.borrow.} - template defineCurrency(typ, base: expr): stmt = + template defineCurrency(typ, base: untyped) = type typ* = distinct base additive(typ) |