From 6975e77d43de640d9d0ca933fe64dc6d2f161b97 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Fri, 6 Jun 2014 19:10:08 +0200 Subject: Adds docstring example to system.fieldPairs. --- lib/system.nim | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/system.nim b/lib/system.nim index c69a335e4..4a4872b98 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1767,9 +1767,38 @@ iterator fields*[S:tuple|object, T:tuple|object](x: S, y: T): tuple[a,b: expr] { ## in the loop body. iterator fieldPairs*[T: tuple|object](x: T): TObject {. magic: "FieldPairs", noSideEffect.} - ## iterates over every field of `x`. Warning: This really transforms - ## the 'for' and unrolls the loop. The current implementation also has a bug - ## that affects symbol binding in the loop body. + ## Iterates over every field of `x` returning their name and value. + ## + ## When you iterate over objects with different field types you have to use + ## the compile time ``when`` instead of a runtime ``if`` to select the code + ## you want to run for each type. To perform the comparison use the `is + ## operator `_. Example: + ## + ## .. code-block:: Nimrod + ## + ## type + ## Custom = object + ## foo: string + ## bar: bool + ## + ## proc `$`(x: Custom): string = + ## result = "Custom:" + ## for name, value in x.fieldPairs: + ## when value is bool: + ## result.add("\n\t" & name & " is " & $value) + ## else: + ## if value.isNil: + ## result.add("\n\t" & name & " (nil)") + ## else: + ## result.add("\n\t" & name & " '" & value & "'") + ## + ## Another way to do the same without ``when`` is to leave the task of + ## picking the appropriate code to a secondary proc which you overload for + ## each field type and pass the `value` to. + ## + ## Warning: This really transforms the 'for' and unrolls the loop. The + ## current implementation also has a bug that affects symbol binding in the + ## loop body. iterator fieldPairs*[S: tuple|object, T: tuple|object](x: S, y: T): tuple[ a, b: expr] {. magic: "FieldPairs", noSideEffect.} -- cgit 1.4.1-2-gfad0 From 7da3c5e71e485ef4326dcf415a297267a47ab971 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Fri, 6 Jun 2014 19:32:36 +0200 Subject: Adds do notation example to algorithm.sort. --- lib/pure/algorithm.nim | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib') diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index 37fbc948c..86d329763 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -150,6 +150,15 @@ proc sort*[T](a: var openArray[T], ## # overload: ## sort(myStrArray, system.cmp) ## + ## You can inline adhoc comparison procs with the `do notation + ## `_. Example: + ## + ## .. code-block:: nimrod + ## + ## people.sort do (x, y: Person) -> int: + ## result = cmp(x.surname, y.surname) + ## if result == 0: + ## result = cmp(x.name, y.name) var n = a.len var b: seq[T] newSeq(b, n div 2) -- cgit 1.4.1-2-gfad0 From 9009841d623d268c649f96bd0215b3013de35eeb Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Fri, 6 Jun 2014 19:53:39 +0200 Subject: Avoids temporal string in tables hashing example. --- lib/pure/collections/tables.nim | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 848f4b8ba..b5fc1737a 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -37,7 +37,8 @@ ## ## Piggyback on the already available string hash proc. ## ## ## ## Without this proc nothing works! -## result = hash(x.firstName & x.lastName) +## result = x.firstName.hash !& x.lastName.hash +## result = !$result ## ## var ## salaries = initTable[Person, int]() @@ -841,7 +842,8 @@ when isMainModule: ## Piggyback on the already available string hash proc. ## ## Without this proc nothing works! - result = hash(x.firstName & x.lastName) + result = x.firstName.hash !& x.lastName.hash + result = !$result var salaries = initTable[Person, int]() -- cgit 1.4.1-2-gfad0 From bde9d1ac0753e46c726dc63930539bb82d09f19d Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Fri, 6 Jun 2014 20:10:13 +0200 Subject: Adds to tables module example of reference type vs value type. --- lib/pure/collections/tables.nim | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index b5fc1737a..e51a04dd1 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -52,8 +52,25 @@ ## p2.lastName = "박" ## salaries[p2] = 45_000 ## -## **Note:** The data types declared here have *value semantics*: This means -## that ``=`` performs a copy of the hash table. +## **Note:** The data types declared here starting with the **T** prefix have +## *value semantics*: This means that ``=`` performs a copy of the hash table. +## On the other hand, types declared with the **P** prefix have *reference +## semantics*. Behaviour comparison: +## +## .. code-block:: nimrod +## var valueWords = initTable[string, string]() +## valueWords["teh"] = "the" +## var valueWordsClone = valueWords +## # Changing the clone won't change the original. +## valueWordsClone["teh"] = "thehehe" +## assert valueWords["teh"] != valueWordsClone["teh"] +## +## var refWords = newTable[string, string]() +## refWords["teh"] = "the" +## var refWordsShadow = refWords +## # Both the shadow and the original share the same data. +## refWordsShadow["teh"] = "thehehe" +## assert refWords["teh"] == refWordsShadow["teh"] import hashes, math @@ -861,3 +878,16 @@ when isMainModule: s2[p2] = 45_000 s3[p1] = 30_000 s3[p2] = 45_000 + + # Ref verification. + var valueWords = initTable[string, string]() + valueWords["teh"] = "the" + var valueWordsClone = valueWords + valueWordsClone["teh"] = "thehehe" + assert valueWords["teh"] != valueWordsClone["teh"] + + var refWords = newTable[string, string]() + refWords["teh"] = "the" + var refWordsShadow = refWords + refWordsShadow["teh"] = "thehehe" + assert refWords["teh"] == refWordsShadow["teh"] -- cgit 1.4.1-2-gfad0 From f45a1dbf1d1eaba511b6673c5955aa108430c165 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Fri, 6 Jun 2014 20:58:51 +0200 Subject: Adds brief intro to hashes module. --- lib/pure/hashes.nim | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pure/hashes.nim b/lib/pure/hashes.nim index 5784a96c1..740355e55 100644 --- a/lib/pure/hashes.nim +++ b/lib/pure/hashes.nim @@ -8,7 +8,34 @@ # ## This module implements efficient computations of hash values for diverse -## Nimrod types. +## Nimrod types. All the procs are based on these two building blocks: the `!& +## proc <#!&>`_ used to start or mix a hash value, and the `!$ proc <#!$>`_ +## used to *finish* the hash value. If you want to implement hash procs for +## your custom types you will end up writing the following kind of skeleton of +## code: +## +## .. code-block:: nimrod +## proc hash(x: Something): THash = +## ## Computes a THash from `x`. +## var h: THash = 0 +## # Iterate over parts of `x`. +## for xAtom in x: +## # Mix the atom with the partial hash. +## h = h !& xAtom +## # Finish the hash. +## result = !$h +## +## If your custom types contain fields for which there already is a hash proc, +## like for example objects made up of ``strings``, you can simply hash +## together the hash value of the individual fields: +## +## .. code-block:: nimrod +## proc hash(x: Something): THash = +## ## Computes a THash from `x`. +## var h: THash = 0 +## h = h &! hash(x.foo) +## h = h &! hash(x.bar) +## result = !$h import strutils -- cgit 1.4.1-2-gfad0 From 3f9ad7ef22dfea8fa58c378322581ab3b2ff48b2 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Fri, 6 Jun 2014 21:55:20 +0200 Subject: Documents -d: in the compiler guide and hyperlinks assert/defined. --- doc/nimrodc.txt | 12 ++++++++++++ lib/system.nim | 20 +++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt index e4f1c41dc..fea1037da 100644 --- a/doc/nimrodc.txt +++ b/doc/nimrodc.txt @@ -87,6 +87,18 @@ Level Description for compiler developers. ===== ============================================ + +Compile time symbols +-------------------- + +Through the ``-d:x`` or ``--define:x`` switch you can define compile time +symbols for conditional compilation. The defined switches can be checked in +source code with the `when statement `_ and +`defined proc `_. The typical use of this switch is to +enable builds in release mode (``-d:release``) where certain safety checks are +omitted for better performance. Another common use is the ``-d:ssl`` switch to +activate `SSL sockets `_. + Configuration files ------------------- diff --git a/lib/system.nim b/lib/system.nim index 4a4872b98..2f24f68b1 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -88,6 +88,15 @@ proc defined*(x: expr): bool {.magic: "Defined", noSideEffect.} ## when not defined(strutils.toUpper): ## # provide our own toUpper proc here, because strutils is ## # missing it. + ## + ## You can also check external symbols introduced through the compiler's + ## `-d:x switch `_ to enable build time + ## conditionals: + ## + ## .. code-block:: Nimrod + ## when not defined(release): + ## # Do here programmer friendly expensive sanity checks. + ## # Put here the normal code when defined(useNimRtl): {.deadCodeElim: on.} @@ -2812,10 +2821,15 @@ when true: THide(raiseAssert)(msg) template assert*(cond: bool, msg = "") = - ## provides a means to implement `programming by contracts`:idx: in Nimrod. + ## Raises ``EAssertionFailure`` with `msg` if `cond` is false. + ## + ## Provides a means to implement `programming by contracts`:idx: in Nimrod. ## ``assert`` evaluates expression ``cond`` and if ``cond`` is false, it - ## raises an ``EAssertionFailure`` exception. However, the compiler may - ## not generate any code at all for ``assert`` if it is advised to do so. + ## raises an ``EAssertionFailure`` exception. However, the compiler may not + ## generate any code at all for ``assert`` if it is advised to do so through + ## the ``-d:release`` or ``--assertions:off`` `command line switches + ## `_. + ## ## Use ``assert`` for debugging purposes only. bind instantiationInfo mixin failedAssertImpl -- cgit 1.4.1-2-gfad0 From af6abac4911be18bd92a9190ccbe39aa72ab1a79 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Tue, 10 Jun 2014 00:39:19 +0200 Subject: Revert "Adds to tables module example of reference type vs value type." This reverts commit bde9d1ac0753e46c726dc63930539bb82d09f19d. --- lib/pure/collections/tables.nim | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) (limited to 'lib') diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index e51a04dd1..b5fc1737a 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -52,25 +52,8 @@ ## p2.lastName = "박" ## salaries[p2] = 45_000 ## -## **Note:** The data types declared here starting with the **T** prefix have -## *value semantics*: This means that ``=`` performs a copy of the hash table. -## On the other hand, types declared with the **P** prefix have *reference -## semantics*. Behaviour comparison: -## -## .. code-block:: nimrod -## var valueWords = initTable[string, string]() -## valueWords["teh"] = "the" -## var valueWordsClone = valueWords -## # Changing the clone won't change the original. -## valueWordsClone["teh"] = "thehehe" -## assert valueWords["teh"] != valueWordsClone["teh"] -## -## var refWords = newTable[string, string]() -## refWords["teh"] = "the" -## var refWordsShadow = refWords -## # Both the shadow and the original share the same data. -## refWordsShadow["teh"] = "thehehe" -## assert refWords["teh"] == refWordsShadow["teh"] +## **Note:** The data types declared here have *value semantics*: This means +## that ``=`` performs a copy of the hash table. import hashes, math @@ -878,16 +861,3 @@ when isMainModule: s2[p2] = 45_000 s3[p1] = 30_000 s3[p2] = 45_000 - - # Ref verification. - var valueWords = initTable[string, string]() - valueWords["teh"] = "the" - var valueWordsClone = valueWords - valueWordsClone["teh"] = "thehehe" - assert valueWords["teh"] != valueWordsClone["teh"] - - var refWords = newTable[string, string]() - refWords["teh"] = "the" - var refWordsShadow = refWords - refWordsShadow["teh"] = "thehehe" - assert refWords["teh"] == refWordsShadow["teh"] -- cgit 1.4.1-2-gfad0