diff --git a/mkdocs/docs/circom-language/scoping.md b/mkdocs/docs/circom-language/scoping.md index cd956f716..82366ccb6 100644 --- a/mkdocs/docs/circom-language/scoping.md +++ b/mkdocs/docs/circom-language/scoping.md @@ -1,30 +1,30 @@ # Scoping -Circom has static scoping like C and Rust. However, we have that signals and components must have global scoping and hence they should be defined at the top-level block of the template that defines them. +Circom has static scoping like C and Rust. However, we have that signals and components must have global scoping and hence they should be defined at the top-level block of the template that defines them or, since circom 2.1.5, inside (nested) `if` blocks, but only if conditions are known at compilation time. ```text -pragma circom 2.0.0; +pragma circom 2.1.5; -template Multiplier2 (N) { +template Cubes (N) { //Declaration of signals. - signal input in; - signal output out; + signal input in[N]; + signal output out[N]; //Statements. - out <== in; - signal input x; - if(N > 0){ - signal output out2; - out2 <== x; + for (var i = 0; i < N; i++) { + signal aux; + aux <== in[i]*in[i]; + out[i] <== aux*in[i]; } } -component main = Multiplier2(5); +component main = Cubes(5); ``` -Signal `out2` must be declared at the top-level block. The next compilation error is produced: _"`out2` is outside the initial scope"_. +Signal `aux` cannot be declared in the block of the `for` instruction. The next compilation error is produced: _"`aux` Is outside the initial scope"_. + +Instead the following program compiles correctly. -Since circom 2.1.5, signals and components can be now declared inside `if` blocks, but only if the condition is known at compilation time. ```text pragma circom 2.1.5; template A(n){ @@ -40,11 +40,11 @@ template A(n){ component main = A(5); ``` -In the previous example, the condition `i < n` is known at compilation time, and then the declaration of signal `out` is allowed. However, if the condition where `in < n`, it is not known at compilation time and we output an error, because the declaration in this case is not allowed. +since the condition `i < n` is known at compilation time, and then the declaration of signal `out` is allowed. However, if the condition was `in < n`, since it is not known at compilation time, it would output an error message because the declaration in that case is not allowed. +In any case, we apply a static scoping like in C++ or Rust, and a signal declared inside an if block is only visible inside the block it is declared. - -Regarding visibility, a signal x of component c is also visible in the template t that has declared c, using the notation c.x. No access to signals of nested sub-components is allowed. For instance, if c is built using another component d, the signals of d cannot be accessed from t. This can be seen in the next code: +Regarding visibility of signals of subcomponent, a signal `x` of component `c` is also visible in the template `t` that has declared `c`, using the notation `c.x`, if `x` is an input or and output of `c`. No access to intermediate signals of sub-components or signals of nested sub-components is allowed. For instance, if `c` is built using another component `d`, the signals of `d` cannot be accessed from `t`. This can be seen in the next code: ```text pragma circom 2.0.0; @@ -68,8 +68,6 @@ template t(){ component main = t(); ``` - -This code produces a compilation error since we cannot access `comp2` of component `c3`. +That rises and error on `c3.comp2.x`: _"Signal not found in component: only accesses to input/output signals are allowed"_. A var can be defined at any block and its visibility is reduced to the block like in C or Rust. -