diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-04-14 08:42:45 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-04-14 08:42:53 +0200 |
commit | c6f15c53f458ec0138d006edcaca349281fda753 (patch) | |
tree | 5465dc77af558286defa5a7fc7bf8745a8bf431d /doc/manual/effects.txt | |
parent | 3d1d163efff446bd420a150114b7914c7b34798e (diff) | |
download | Nim-c6f15c53f458ec0138d006edcaca349281fda753.tar.gz |
merge the different manual/*.rst include files. Was too hard to find the corresponding sections otherwise. Hope it means the manual is more likely to be kept up to date.
Diffstat (limited to 'doc/manual/effects.txt')
-rw-r--r-- | doc/manual/effects.txt | 129 |
1 files changed, 0 insertions, 129 deletions
diff --git a/doc/manual/effects.txt b/doc/manual/effects.txt deleted file mode 100644 index 254a43fbb..000000000 --- a/doc/manual/effects.txt +++ /dev/null @@ -1,129 +0,0 @@ -Effect system -============= - -Exception tracking ------------------- - -Nim supports exception tracking. The `raises`:idx: pragma can be used -to explicitly define which exceptions a proc/iterator/method/converter is -allowed to raise. The compiler verifies this: - -.. code-block:: nim - proc p(what: bool) {.raises: [IOError, OSError].} = - if what: raise newException(IOError, "IO") - else: raise newException(OSError, "OS") - -An empty ``raises`` list (``raises: []``) means that no exception may be raised: - -.. code-block:: nim - proc p(): bool {.raises: [].} = - try: - unsafeCall() - result = true - except: - result = false - - -A ``raises`` list can also be attached to a proc type. This affects type -compatibility: - -.. code-block:: nim - type - Callback = proc (s: string) {.raises: [IOError].} - var - c: Callback - - proc p(x: string) = - raise newException(OSError, "OS") - - c = p # type error - - -For a routine ``p`` the compiler uses inference rules to determine the set of -possibly raised exceptions; the algorithm operates on ``p``'s call graph: - -1. Every indirect call via some proc type ``T`` is assumed to - raise ``system.Exception`` (the base type of the exception hierarchy) and - thus any exception unless ``T`` has an explicit ``raises`` list. - However if the call is of the form ``f(...)`` where ``f`` is a parameter - of the currently analysed routine it is ignored. The call is optimistically - assumed to have no effect. Rule 2 compensates for this case. -2. Every expression of some proc type within a call that is not a call - itself (and not nil) is assumed to be called indirectly somehow and thus - its raises list is added to ``p``'s raises list. -3. Every call to a proc ``q`` which has an unknown body (due to a forward - declaration or an ``importc`` pragma) is assumed to - raise ``system.Exception`` unless ``q`` has an explicit ``raises`` list. -4. Every call to a method ``m`` is assumed to - raise ``system.Exception`` unless ``m`` has an explicit ``raises`` list. -5. For every other call the analysis can determine an exact ``raises`` list. -6. For determining a ``raises`` list, the ``raise`` and ``try`` statements - of ``p`` are taken into consideration. - -Rules 1-2 ensure the following works: - -.. code-block:: nim - proc noRaise(x: proc()) {.raises: [].} = - # unknown call that might raise anything, but valid: - x() - - proc doRaise() {.raises: [IOError].} = - raise newException(IOError, "IO") - - proc use() {.raises: [].} = - # doesn't compile! Can raise IOError! - noRaise(doRaise) - -So in many cases a callback does not cause the compiler to be overly -conservative in its effect analysis. - - -Tag tracking ------------- - -The exception tracking is part of Nim's `effect system`:idx:. Raising an -exception is an *effect*. Other effects can also be defined. A user defined -effect is a means to *tag* a routine and to perform checks against this tag: - -.. code-block:: nim - type IO = object ## input/output effect - proc readLine(): string {.tags: [IO].} - - proc no_IO_please() {.tags: [].} = - # the compiler prevents this: - let x = readLine() - -A tag has to be a type name. A ``tags`` list - like a ``raises`` list - can -also be attached to a proc type. This affects type compatibility. - -The inference for tag tracking is analogous to the inference for -exception tracking. - - -Read/Write tracking -------------------- - -**Note**: Read/write tracking is not yet implemented! - -The inference for read/write tracking is analogous to the inference for -exception tracking. - - -Effects pragma --------------- - -The ``effects`` pragma has been designed to assist the programmer with the -effects analysis. It is a statement that makes the compiler output all inferred -effects up to the ``effects``'s position: - -.. code-block:: nim - proc p(what: bool) = - if what: - raise newException(IOError, "IO") - {.effects.} - else: - raise newException(OSError, "OS") - -The compiler produces a hint message that ``IOError`` can be raised. ``OSError`` -is not listed as it cannot be raised in the branch the ``effects`` pragma -appears in. |