Side effects

The noSideEffect pragma is used to mark a proc/iterator that can have only side effects through parameters. This means that the proc/iterator only changes locations that are reachable from its parameters and the return value only depends on the parameters. If none of its parameters have the type var, ref, ptr, cstring, or proc, then no locations are modified.

In other words, a routine has no side effects if it does not access a threadlocal or global variable and it does not call any routine that has a side effect.

It is a static error to mark a proc/iterator to have no side effect if the compiler cannot verify this.

As a special semantic rule, the built-in debugEcho pretends to be free of side effects so that it can be used for debugging routines marked as noSideEffect.

func is syntactic sugar for a proc with no side effects:

  1. func `+` (x, y: int): int

To override the compiler’s side effect analysis a {.noSideEffect.} cast pragma block can be used:

  1. func f() =
  2. {.cast(noSideEffect).}:
  3. echo "test"

Side effects are usually inferred. The inference for side effects is analogous to the inference for exception tracking.

When the compiler cannot infer side effects, as is the case for imported functions, one can annotate them with the sideEffect pragma.