When I access a global array in a proc, the proc can't be a func:
var
x: array[5, int]
x = [1, 2, 3, 4, 5]
# This is fine
proc access(index: int): auto =
x[index]
# This gives "'func_access' can have side effects"
func func_access(index: int): auto =
x[index]
Is this because my index might be out of bounds and the side-effect is an exception?
If so, can I tell the compiler that I don't care in this case? (I get the same compilation error when checks are off.)
Accessing any non constant globals from functions is considered impure so if you want to overload the "func checker" you can do the following:
var
x: array[5, int]
x = [1, 2, 3, 4, 5]
# This is fine
proc access(index: int): auto =
x[index]
# This gives "'func_access' can have side effects"
func func_access(index: int): auto =
{.noSideEffect.}:
result = x[index]
As per https://nim-lang.org/docs/manual.html#pragmas-nosideeffect-pragma :
This means that the proc/iterator only changes locations that are reachable from its parameters and the return value only depends on the arguments.
Accessing global variables is considered a side effect since then the return value might not depend on the arguments only.
@ElegantBeef: thanks. That satisfied the compiler.
@Yardanico: OK. So the compiler isn't really complaining that there might be a side effect - my proc doesn't change any data - but that we don't have referential transparency (which is true).
A function in Nim is similar to a function in math. It must not have side effect and it always returns same output from same input.
If a function use global variable, the output from the function can be changed when the value of global variable is changed. Even if your code never change that global variable, declaring it with var means it can be modified and you might add a code that modifys it.
If compiler checks global variables used in a function is never modified and allow a function to use it, you can not add any proc that modify these global variables without changing code in the function while these global variables declared with var.