diff options
author | Araq <rumpf_a@web.de> | 2013-09-03 23:46:41 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2013-09-03 23:46:41 +0200 |
commit | 40b379859c1f0775718a873a0ba58d32510855aa (patch) | |
tree | 5e45f929dba481fb2413d2f28587a1dbc65b2bb5 /doc | |
parent | 891f871ba71b0b6e136fea13e5be0bd3e0860fea (diff) | |
parent | 6fa72c5d9d9662e6657ddf5c670dc56dc2748ecc (diff) | |
download | Nim-40b379859c1f0775718a873a0ba58d32510855aa.tar.gz |
resolved the conflict
Diffstat (limited to 'doc')
-rw-r--r-- | doc/keywords.txt | 2 | ||||
-rw-r--r-- | doc/manual.txt | 128 |
2 files changed, 125 insertions, 5 deletions
diff --git a/doc/keywords.txt b/doc/keywords.txt index 2a775cd94..fa3ce4786 100644 --- a/doc/keywords.txt +++ b/doc/keywords.txt @@ -7,7 +7,7 @@ finally for from generic if import in include interface is isnot iterator lambda let -macro method mixin mod +macro method mixin using mod nil not notin object of or out proc ptr diff --git a/doc/manual.txt b/doc/manual.txt index bc4e13e8e..914e6eaf5 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -2192,6 +2192,37 @@ Instead of: :"a"(`a`), "c"(`b`) """ +Using statement +--------------- + +The using statement provides syntactic convenience for procs that heavily use a +single contextual parameter. When applied to a variable or a constant, it will +instruct Nimrod to automatically consider the used symbol as a hidden leading +parameter for any procedure calls, following the using statement in the current +scope. Thus, it behaves much like the hidden `this` parameter available in some +object-oriented programming languages. + +.. code-block:: nimrod + + var s = socket() + using s + + connect(host, port) + send(data) + + while true: + let line = readLine(timeout) + ... + + +When applied to a callable symbol, it brings the designated symbol in the +current scope. Thus, it can be used to disambiguate between imported symbols +from different modules having the same name. + +.. code-block:: nimrod + import windows, sdl + using sdl.SetTimer + If expression ------------- @@ -3218,14 +3249,69 @@ the dot syntax: proc `[]`(m: TMatrix, row, col: int): TMatrix.T = m.data[col * high(TMatrix.Columns) + row] -If anonymous type classes are used, the ``type`` operator can be used to -discover the instantiated type of each param. +Alternatively, the `type` operator can be used over the proc params for similar +effect when anonymous or distinct type classes are used. + +When a generic type is instantiated with a type class instead of a concrete +type, this results in another more specific type class: + +.. code-block:: nimrod + seq[ref object] # Any sequence storing references to any object type + + type T1 = auto + proc foo(s: seq[T1], e: T1) + # seq[T1] is the same as just `seq`, but T1 will be allowed to bind + # to a single type, while the signature is being matched + + TMatrix[Ordinal] # Any TMatrix instantiation using integer values + +As seen in the previous example, in such instantiations, it's not necessary to +supply all type parameters of the generic type, because any missing ones will +be inferred to have the equivalent of the `any` type class and thus they will +match anything without discrimination. User defined type classes ------------------------- -To be written. +The user-defined type classes are available in two flavours - declarative and +imperative. Both are used to specify an arbitrary set of requirements that the +matched type must satisfy. + +Declarative type classes are written in the following form: + +.. code-block:: nimrod + type + Comparable = generic x, y + (x < y) is bool + + Container[T] = generic c + c.len is ordinal + items(c) is iterator + for value in c: + type(value) is T + + +The identifiers following the `generic` keyword are treated as variables of +the matched type and the body of the type class consists of arbitrary code that +must be valid under these circumstances. + +Specifically, the type class will be matched if: + +a) all of the expressions within the body can be compiled for the tested type +b) all statically evaluatable boolean expressions in the body must be true + +Please note that the `is` operator allows you to easily verify the precise 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 doesn't reveal implementation details. + +.. code-block:: nimrod + +Much like generics, the user defined type classes will be instantiated exactly +once for each tested type and any static code included within them will also be +executed once. + Return Type Inference @@ -3937,7 +4023,7 @@ the ordinary AST predicates: template ex{a = b + c}(a: int{noalias}, b, c: int) = # this transformation is only valid if 'b' and 'c' do not alias 'a': a = b - inc a, b + inc a, c Pattern operators @@ -4439,6 +4525,40 @@ be destructed at its scope exit. Later versions of the language will improve the support of destructors. +delegator pragma +---------------- + +The delegator pragma can be used to intercept and rewrite proc call and field +access attempts referring to previously undeclared symbol names. It can be used +to provide a fluent interface to objects lying outside the static confines of +the Nimrod's type system such as values from dynamic scripting languages or +dynamic file formats such as JSON or XML. + +A delegator is a special form of the `()` operator marked with the delagator +pragma. When Nimrod encounters an expression that cannot be resolved by the +standard overload resolution, any delegators in the current scope will be +matched against a rewritten form of the expression following the standard +signature matching rules. In the rewritten expression, the name of the unknown +proc or field name is inserted as an additional static string parameter always +appearing in the leading position: + +.. code-block:: nimrod + a.b => delegator("b", a) + a.b(c, d) => delegator("b", a, c) + a b, c, d => delegator("a", b, c, d) + + +The delegators can be any callable symbol type (procs, templates, macros) +depending on the desired effect: + +.. code-block:: nimrod + proc `()` (field: string, js: PJsonNode): JSON {.delegator.} = js[field] + + var js = parseJson("{ x: 1, y: 2}") + echo js.x # outputs 1 + echo js.y # outputs 2 + + procvar pragma -------------- The `procvar`:idx: pragma is used to mark a proc that it can be passed to a |