<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class="">It’s a little complicated.</div><div class=""><br class=""></div><div class="">there is many clauses with many scopes in one function, or one case or others, <span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">we</span> call it <span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">neighbor</span> clause scope.</div><div class=""><br class=""></div><div class="">local scope is based on clauses or comprehensions</div><div class="">there is two type of local scope<br class=""><div class="">shadowed and non_shadowed</div><div class="">for function clause, named function clause</div><div class="">the scope rule is shadowed:</div><div class="">binding in pattens like function parameter, named function name, will shadow previous binding outside scope</div><div class="">new binding in expressions will not seen outside scope or in <span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">neighbor</span> <span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">clause</span> scope, it could be used repeatedly</div><div class="">```</div><div class="">fun(A) -> A1 = A + 1, A1 end,</div><div class="">fun Name(A) -> A1 = Name(A -1), A1; (0) -> A1 = 0, A1 end</div><div class="">[A || A <- As]</div><div class="">```</div><div class="">for comprehension</div><div class=""><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">the scope rule is also shadowed but with two level: comprehension and generate</div></div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><font color="#000000" class="">binding in pattens in comprehension generate, will not only shadow previous binding outside comprehension, and also shadow previous binding inside </font>comprehension</div><div class=""><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">new binding in expression </span><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">in comprehension generate </span><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">not seen outside </span><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">comprehension</span> <span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">generate</span></div><div class=""><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">new binding in expression in comprehension without generate </span><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">not seen outside </span><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">comprehension, but usable in next expressions in </span><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">comprehension</span></div><div class=""><br class=""></div><div class="">```</div><div class=""><div class="">test_lc(A) -></div><div class="">    A_1 = [{A_3, B}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">      </span>   || B <- [begin A_1 = A + 2, A_1 end],</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>      begin A_1 = A + 3, A_1, true end,</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>      A_2 <- [begin A_2 = A_1 + 1, A_2 end],</div><div class="">              is_ok(A_2 + 3, begin A_3 = A_2 + 4, A_3 end),</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>      true],</div><div class="">    A_1.</div></div><div class="">```</div><div class="">for case clause, if clause, try catch clause,  receive after clause</div><div class="">the scope rule is non-shadowed:</div><div class=""><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">binding in clause pattens is same as previous binding outside scope</span></div><div class="">new binding in expressions will not seen in <span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">neighbor</span> <span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">clause</span> scope, it could be used repeatedly</div><div class="">but outside soup, unless the binding with same name is bind in all <span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">neighbor</span> clause <span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">scope</span>, you will get an compile time unsafe error</div><div class="">example:</div><div class=""><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">```</span></div><div class=""><div class=""><div class="">test(A, A1) -></div><div class="">    case A of</div><div class="">        A1 -></div><div class="">            A2 = 3,</div><div class="">            A3 = 2,</div><div class="">            A3;</div><div class="">        A  -></div><div class="">            A2 = 4,</div><div class="">            A2</div><div class="">    end,</div><div class="">    A2,</div><div class=""><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">    A3. %% variable 'A3' unsafe in 'case'</span></div></div></div><div class=""><font color="#000000" class="">```</font></div><div class=""><font color="#000000" class=""><br class=""></font></div><div class=""><font color="#000000" class="">```</font></div><div class=""><div><div>hello(A = 1, A1 = 2)</div><div>[A = 1|[A1 = 2]]</div><div>{A = 1, A1 = 2}</div><div>#hello{world1 = (A = 1), world2 = (A1 = 2)}</div><div>#{world1 => (A = 1), world2 => (A1 = 2)}</div><div>(A = 1) + (A1 = 2)</div><div>```</div><div>these expression has it's scope group</div><div>for this scope, we name it argument scope</div><div>every variable binded in scope could not used in <span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">neighbor</span> scope, but avaliable outside scope group</div><div>for example</div><div>```</div><div>1> (A = A1) + (A1 = 2).</div><div>* 1: variable 'A1' is unbound</div><div>1> (A = 1) + (A1 = A).</div><div>* 1: variable 'A' is unbound</div><div>1> ((A = 1) + (A1 = 2)), A1.</div><div>2</div><div>```</div><div>but usually user don't write code this style, you could just ignore it.</div><div><br class=""></div><div>Previous conclusion is studied by test in erlang-otp R23.</div></div><div><br class=""><blockquote type="cite" class=""><div class="">2021年9月17日 08:23,Yao Bao <<a href="mailto:free7by@163.com" class="">free7by@163.com</a>> 写道:</div><br class="Apple-interchange-newline"><div class=""><div class="">Hello,<br class=""><br class="">I'm trying to understand the scope rules which Erlang has.<br class=""><br class="">As far as I know, Erlang has no global scope (data), and the local scope is based on function clauses. Is there anything else related to scope rules but I am not aware of?<br class=""><br class="">I explored the documentation, but cannot find the description/definition of scope rules in it (Erlang Reference Manual).<br class="">If we missed this description/definition, should we add it into the reference manual?<br class=""><br class="">Yao<br class=""><br class=""></div></div></blockquote></div><br class=""></div></div></body></html>