<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">
<div class="">Hello community!</div>
<div class=""><br class="">
</div>
<div class="">I’d like to pitch an idea for a user-friendly way for functions to pull values from an arbitrary environment. Let me introduce the concept with a motivational&nbsp;example before I dig into dirty syntax and semantics. Note that I intentionally removed
 many pieces of code from my examples, but I guess everybody will be able to understand the context.<br class="">
<br class="">
Say you are writing a visitor (with the pattern of the same name) for an AST to implement an interpreter:<br class="">
<br class="">
</div>
<div class=""><span class="" style="font-variant-ligatures: no-common-ligatures;">
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">class</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;Interpreter:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Visitor</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;{</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">&nbsp; &nbsp; func</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;visit(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">_</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">BinExpr</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)
 &nbsp; &nbsp;{&nbsp;</span><span class="" style="color: rgb(0, 132, 0);">/* ... */&nbsp;</span>}</div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">&nbsp; &nbsp; func</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;visit(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">_</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Literal</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)
 &nbsp; &nbsp;{&nbsp;</span><span class="" style="color: rgb(0, 132, 0);">/* ... */&nbsp;</span>}</div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">&nbsp; &nbsp; func</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;visit(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">_</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Scope</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)
 &nbsp; &nbsp; &nbsp;{&nbsp;</span><span class="" style="color: rgb(0, 132, 0);">/* ... */&nbsp;</span>}</div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">&nbsp; &nbsp; func</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;visit(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">_</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Identifier</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)
 {&nbsp;</span><span class="" style="color: rgb(0, 132, 0);">/* ... */&nbsp;</span>}</div>
</div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">}</span></div>
<div class=""><span class="" style="font-variant-ligatures: no-common-ligatures;"><br class="">
</span></div>
<div class="">Although this design pattern is often recommended for AST processing, managing data as we go down the tree can be cumbersome. The problem is that we need to store all intermediate results as we climb up the tree in some instance member, because
 we can’t use the return type of the&nbsp;<font face="Menlo" class="" style="font-size: 11px;">visit(_:)</font>&nbsp;method, as we would do with a recursive function:</div>
<div class=""><br class="">
</div>
<div class="">
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">class</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;Interpreter:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Visitor</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;{</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">func</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;visit(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">_</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">BinExpr</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)
 {</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; node.lhs.accept(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">self</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">let</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;lhs
 = accumulator!</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; node.rhs.accept(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">self</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">let</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;rhs
 = accumulator!</span></div>
<div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span class="Apple-tab-span" style="white-space: pre;"></span><span class="" style="color: rgb(0, 132, 0);">/* ... */</span><span class="" style="font-variant-ligatures: no-common-ligatures;"></span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; }</span></div>
<div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span class="" style="font-variant-ligatures: no-common-ligatures;"></span><br class="">
</div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">func</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;visit(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">_</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Literal</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)
 &nbsp; &nbsp;{&nbsp;</span><span class="" style="color: rgb(0, 132, 0);">/* ... */&nbsp;</span>}</div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">&nbsp; &nbsp; func</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;visit(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">_</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Scope</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)
 &nbsp; &nbsp; &nbsp;{&nbsp;</span><span class="" style="color: rgb(0, 132, 0);">/* ... */&nbsp;</span>}</div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">&nbsp; &nbsp; func</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;visit(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">_</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Identifier</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)
 {&nbsp;</span><span class="" style="color: rgb(0, 132, 0);">/* ... */&nbsp;</span>}</div>
<div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span class="" style="font-variant-ligatures: no-common-ligatures;"></span><br class="">
</div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">var</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;accumulator:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Int</span><span class="" style="font-variant-ligatures: no-common-ligatures;">?
 =&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">nil</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);"><br class="">
</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">&nbsp; &nbsp;&nbsp;</span><span class="" style="color: rgb(0, 132, 0);">/* ... */</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">}</span></div>
</div>
</div>
<div class=""><br class="">
</div>
<div class="">As our interpreter will grow and need more visitors to “return” a value, we’ll be forced to add more and more stored properties to its definition. Besides, the state of those properties is difficult to debug, as it can quickly become unclear what
 depth of the tree they should be associated to. In fact, it is as if all these properties acted as global variables.</div>
<div class=""><br class="">
</div>
<div class="">The problem gets even bigger when we need to&nbsp;<i class="">pass</i>&nbsp;variables to a particular execution of a&nbsp;<span class="" style="font-family: Menlo; font-size: 11px;">visit(_:)</span>. Not only do we need to add a stored property to represent
 each “argument”, but we also have to store them in stacks so that a nested calls to a particular visit can get their own “evaluation context”. Consider for instance the implementation of the&nbsp;<font face="Menlo" class="" style="font-size: 11px;">visit(</font><span class="" style="color: rgb(186, 45, 162); font-family: Menlo; font-size: 11px;">_</span><font face="Menlo" class="" style="font-size: 11px;">&nbsp;node:&nbsp;</font><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">Identifier</span><font face="Menlo" class="" style="font-size: 11px;">)</font>,
 assuming that the language our AST represents would support lexical scoping.</div>
<div class=""><br class="">
</div>
<div class="">
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">class</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;Interpreter:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Visitor</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;{</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
&nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(0, 132, 0);">/* ... */</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;">
<span class="" style="font-variant-ligatures: no-common-ligatures;"></span><br class="">
</div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;">
<span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">&nbsp; &nbsp; func</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;visit(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">_</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Scope</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)
 {</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; symbols.append([:])</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;">
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">&nbsp; &nbsp; &nbsp; &nbsp; for</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;child&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">in</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node.children
 {</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; child.accept(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">self</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; }</span></div>
</div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; symbols.removeLast()</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;">
&nbsp; &nbsp; }</div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;">
<br class="">
</div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">func</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;visit(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">_</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Identifier</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)
 {</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; accumulator = symbols.last![node.name]!</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; }</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;">
<br class="">
<span class="" style="font-variant-ligatures: no-common-ligatures;"></span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">var</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;symbols
 = [[String: Int]]()</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">}</span></div>
</div>
</span></div>
<div class=""><br class="">
</div>
<div class="">We could instead create another instance of our visitor to set manage those evaluation contexts. But that would require us to explicitly copy all the variables associated to those contexts, which could potentially be inefficient and error prone.</div>
<div class=""><br class="">
</div>
<div class="">In fact, this last point is also true when dealing with recursive functions. For instance, our&nbsp;<span class="" style="font-family: Menlo; font-size: 11px;">visit(</span><span class="" style="color: rgb(186, 45, 162); font-family: Menlo; font-size: 11px;">_</span><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;node:&nbsp;</span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">Identifier</span><span class="" style="font-family: Menlo; font-size: 11px;">)</span>&nbsp;method
 could be rewritten as:</div>
<div class=""><br class="">
</div>
<div class="">
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">func</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;interpret(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">_</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;identifier:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Identifier</span><span class="" style="font-variant-ligatures: no-common-ligatures;">,&nbsp;symbols:
 [</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">String</span><span class="" style="font-variant-ligatures: no-common-ligatures;">:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Value</span><span class="" style="font-variant-ligatures: no-common-ligatures;">])
 -&gt;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Int</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;{&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 132, 0);">/*
 ... */</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;}</span></div>
</div>
<div class=""><br class="">
</div>
<div class="">so that its evaluation context is passed as a parameter. But this also requires all other functions to also pass this argument, even if their execution does not require the parameter.</div>
<div class=""><br class="">
</div>
<div class=""><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">func</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;">&nbsp;interpret(</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">_</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;">&nbsp;binExpr:&nbsp;</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">BinExpr</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;">,
 symbols: [</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">String</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;">:&nbsp;</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Value</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;">])
 -&gt;&nbsp;</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Int</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;">&nbsp;{</span></div>
<div class="" style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">let</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;lhs =
 interpret(</span><span class="" style="font-variant-ligatures: no-common-ligatures;">node.lhs.accept,&nbsp;</span>symbols:&nbsp;symbols)</div>
<div class="" style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;">
&nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(0, 132, 0);">/* ... */</span></div>
<div class=""><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;">}</span></div>
<div class=""><br class="">
</div>
<div class="">This technique consisting of passing parameters through a function just so that another function called deeper in the stack can get its variable is actually quite common. Sadly, it clouds all signatures with many parameters, which make it more
 difficult to reason about what a particular function actually needs from its caller. Note also that this overuses the running stack, putting many unnecessary values in all execution frames.</div>
<div class=""><br class="">
</div>
<div class="">The idea I’d like to pitch is to offer a mechanism to address this issue. Namely, I’d like a way to provide a function with an environment when using its parameter and/or return type is not an option, or when doing so would add unnecessary complexity
 to its signature (like illustrated above). While this mechanism would share similarities with how functions (and closures) are able to capture variables when they are declared, it would differ in the fact that these environment would depend on the execution
 frame prior to that of a particular function call rather than the function declaration/definition.</div>
<div class=""><br class="">
</div>
<div class="">First, one would declare a&nbsp;<i class="">contextual variable:</i></div>
<div class=""><br class="">
</div>
<div class=""><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">context var</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;">&nbsp;symbols:
 [String: Int]?</span></div>
<div class=""><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;"><br class="">
</span></div>
<div class="">Such contextual variables could be seen as stacks, whose values are typed with that of the variable. In that particular example, the type of the context&nbsp;<font face="Menlo" class="" style="font-size: 11px;">symbols</font>&nbsp;would be&nbsp;<font face="Menlo" class="" style="font-size: 11px;">[String:
 Int]</font>. The optional is needed to explicitly represent the fact that a context may not always be set, but this could be inferred as well. One would be able to set the value a contextual variable, effectively pushing a value on the stack it represent,
 before entering a new execution frame:</div>
<div class=""><br class="">
</div>
<div class=""><span class="" style="font-family: Menlo; font-size: 11px; color: rgb(186, 45, 162);">set</span><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;symbols = [:]&nbsp;</span><span class="" style="color: rgb(186, 45, 162); font-family: Menlo; font-size: 11px;">in</span><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;{</span></div>
<div class="">
<div class="" style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">for</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;child&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">in</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node.children
 {</span></div>
<div class="" style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; child.accept(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">self</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)</span></div>
<div class="" style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; }</span></div>
</div>
<div class=""><span class="" style="font-family: Menlo; font-size: 11px;">}</span></div>
<div class=""><span class="" style="font-family: Menlo; font-size: 11px;"><br class="">
</span></div>
<div class="">In the above example, the contextual variable&nbsp;<span class="" style="font-family: Menlo; font-size: 11px;">symbols</span>&nbsp;would represent an empty dictionary for all execution frames above that of the context scope (delimited by braces). Extracting
 a value from a context would boils down to reading an optional value:</div>
<div class=""><br class="">
</div>
<div class="">
<div class="" style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;">
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">guard</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">let</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;val
 = symbols?[node.name]&nbsp;<span class="" style="color: rgb(186, 45, 162);">else</span>&nbsp;{</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; fatalError(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">&quot;undefined symbol:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">\</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">(</span><span class="" style="font-variant-ligatures: no-common-ligatures;">node.name</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">)</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">&quot;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)</span></div>
<div class="" style="margin: 0px; line-height: normal;">}</div>
<div class="" style="margin: 0px; line-height: normal;">accumulator = val</div>
</div>
</div>
<div class=""><br class="">
</div>
<div class="">And as contextual variables would actually be stacks, one could push another value on the top of them to setup for another evaluation context. Hence, would we call&nbsp;<span class="" style="font-family: Menlo; font-size: 11px; color: rgb(186, 45, 162);">set</span><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;symbols
 = [:]&nbsp;</span><span class="" style="color: rgb(186, 45, 162); font-family: Menlo; font-size: 11px;">in&nbsp;</span><span class="" style="font-family: Menlo; font-size: 11px;">{&nbsp;</span><span class="" style="color: rgb(0, 132, 0); font-family: Menlo; font-size: 11px;">/*
 ... */</span><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;}</span>&nbsp;again, the contextual variable&nbsp;<span class="" style="font-family: Menlo; font-size: 11px;">symbols</span>&nbsp;would represent another empty dictionary as long as our new context
 would be alive:</div>
<div class=""><br class="">
</div>
<div class="">
<div class=""><span class="" style="font-family: Menlo; font-size: 11px; color: rgb(186, 45, 162);">set</span><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;symbols =&nbsp;</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;">[</span><span class="" style="color: rgb(209, 47, 27); font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;">&quot;foo&quot;</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;">:&nbsp;</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures; color: rgb(39, 42, 216);">1</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;">]</span><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;</span><span class="" style="color: rgb(186, 45, 162); font-family: Menlo; font-size: 11px;">in</span><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;{</span></div>
<div class="">
<div class="" style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;">
&nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">set</span>&nbsp;symbols =&nbsp;<span class="" style="font-variant-ligatures: no-common-ligatures;">[</span><span class="" style="color: rgb(209, 47, 27); font-variant-ligatures: no-common-ligatures;">&quot;foo</span><span class="" style="color: rgb(209, 47, 27);">&quot;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(39, 42, 216);">2</span><span class="" style="font-variant-ligatures: no-common-ligatures;">]</span>&nbsp;<span class="" style="color: rgb(186, 45, 162);">in</span>&nbsp;{</div>
</div>
<div class="" style="margin: 0px; line-height: normal;"><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp; print(symbols![</span></font><span class="" style="font-family: Menlo; font-size: 11px; color: rgb(209, 47, 27); font-variant-ligatures: no-common-ligatures;">&quot;foo</span><font color="#d12f1b" face="Menlo" class=""><span class="" style="font-size: 11px;">”</span></font><font face="Menlo" class=""><span class="" style="font-size: 11px;">]!)</span></font></div>
<div class="" style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;">
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(0, 132, 0);">// Prints 2</span></div>
<div class="" style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;">
&nbsp; &nbsp; }</div>
<div class="" style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;">
&nbsp; &nbsp; print(<font face="Menlo" class="" style="font-size: 12px;"><span class="" style="font-size: 11px;">symbols![</span></font><span class="" style="color: rgb(209, 47, 27); font-variant-ligatures: no-common-ligatures;">&quot;foo</span><font color="#d12f1b" face="Menlo" class="" style="font-size: 12px;"><span class="" style="font-size: 11px;">”</span></font><font face="Menlo" class="" style="font-size: 12px;"><span class="" style="font-size: 11px;">]!</span></font>)</div>
<div class="" style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;">
&nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(0, 132, 0);">// Prints 1</span></div>
<div class=""><span class="" style="font-family: Menlo; font-size: 11px;">}</span></div>
</div>
<div class=""><span class="" style="font-family: Menlo; font-size: 11px;"><br class="">
</span></div>
<div class="">The advantage of that approach is threefold.</div>
<div class="">
<ol class="MailOutline">
<li class="">It lets us provide an environment to functions that can’t receive more parameters or return custom values. This is particularly useful when dealing with libraries that provide an entry to define custom behaviour, but fix the API of the functions
 they expect (e.g. a visitor protocol). In those instances, capture by closure is not always possible/desirable.</li><li class="">In large function hierarchy, it lets us provide deep functions with variables, without the need to pass them in every single function call just in the off chance one function may need it deeper in the call graph.</li><li class="">It better defines the notion of stacked environment, so that one can “override” an execution context, which is often desirable when processing recursive structures such as trees or graphs. In particular, it is very useful when not all functions
 require all data that are passed down the tree.</li></ol>
<div class=""><br class="">
</div>
</div>
<div class="">Using our contextual variables, one could rewrite our motivational example as follows:</div>
<div class=""><br class="">
</div>
<div class=""><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">class</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;">&nbsp;Interpreter:&nbsp;</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Visitor</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;">&nbsp;{</span></div>
<div class="">
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">func</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;visit(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">_</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">BinExpr</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)
 {</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">let</span>&nbsp;lhs, rhs :&nbsp;</span><span class="" style="color: rgb(112, 61, 170);">Int</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-tab-span" style="white-space: pre;"></span><span class="" style="color: rgb(186, 45, 162);">set</span>&nbsp;accumulator
 =&nbsp;<span class="" style="color: rgb(186, 45, 162);">nil</span>&nbsp;<font color="#ba2da2" class="">in</font>&nbsp;{</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">node.lhs.accept(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">self</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)</span></div>
<div class="" style="margin: 0px; line-height: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lhs = accumulator!</div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; }</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-tab-span" style="white-space: pre;"></span><span class="" style="color: rgb(186, 45, 162);">set</span>&nbsp;accumulator
 =&nbsp;<span class="" style="color: rgb(186, 45, 162);">nil</span>&nbsp;</span><font color="#ba2da2" class="">in&nbsp;</font>{</div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">node.lhs.accept(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">self</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)</span></div>
<div class="" style="margin: 0px; line-height: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rhs = accumulator!</div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; }</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;"><br class="">
</span></div>
<div class="" style="margin: 0px; line-height: normal;">
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">switch</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node.op
 {</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">case</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">&quot;&#43;&quot;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">:</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; accumulator = lhs &#43; rhs</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">case</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">&quot;-&quot;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">:</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; accumulator = lhs - rhs</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">default</span><span class="" style="font-variant-ligatures: no-common-ligatures;">:</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fatalError(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">&quot;unexpected
 operator&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">\</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">(</span><span class="" style="font-variant-ligatures: no-common-ligatures;">node.op</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">)&quot;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; }</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; }</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;"><br class="">
</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">func</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;visit(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">_</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Literal</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)
 {</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; accumulator = node.val</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; }</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;"><br class="">
</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">
<div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">&nbsp; &nbsp; func</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;visit(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">_</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Scope</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)
 {</span></div>
<div class="" style="margin: 0px; line-height: normal; min-height: 13px;">
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-tab-span" style="white-space: pre;"></span><span class="" style="color: rgb(186, 45, 162);">set</span>&nbsp;symbols = [:]</span>&nbsp;<font color="#ba2da2" class="">in</font>&nbsp;{</div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">for</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;child&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">in</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node.children
 {</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; child.accept(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">self</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; }</span></div>
</div>
<div class="" style="margin: 0px; line-height: normal; min-height: 13px;">&nbsp; &nbsp; }</div>
</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;"><br class="">
</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">func</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;visit(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">_</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;node:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Identifier</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)
 {</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">guard</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">let</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;val
 = symbols?[node.name]&nbsp;<span class="" style="color: rgb(186, 45, 162);">else</span>&nbsp;{</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">fatalError(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">&quot;undefined
 symbol</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">\</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">(</span><span class="" style="font-variant-ligatures: no-common-ligatures;">node.name</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">)</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">&quot;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)</span></div>
<div class="" style="margin: 0px; line-height: normal;">&nbsp; &nbsp; &nbsp; &nbsp; }</div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span>accumulator = val</div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; }</span></div>
</span></div>
</span></div>
</div>
</span></div>
<div class="" style="margin: 0px; line-height: normal; min-height: 13px;"><span class="" style="font-variant-ligatures: no-common-ligatures;"></span><br class="">
</div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">context var</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;accumulator:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Int</span><span class="" style="font-variant-ligatures: no-common-ligatures;">?</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">&nbsp; &nbsp; context</span></span><span class="" style="color: rgb(186, 45, 162);">&nbsp;</span><span class="" style="color: rgb(186, 45, 162);">var</span>&nbsp;symbols:
 [String: Int]?</div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">}</span></div>
<div class=""><span class="" style="font-variant-ligatures: no-common-ligatures;"><br class="">
</span></div>
</div>
</div>
<div class="">It is no longer unclear what depth of the tree the&nbsp;<font face="Menlo" class="" style="font-size: 11px;">accumulator</font>&nbsp;variable should be associated with. The mechanism is handled automatically, preventing the programmer from incorrectly reading
 a value that was previously set for another descent. It is no longer needed to manually handle the stack management of the&nbsp;<span class="" style="font-family: Menlo; font-size: 11px;">symbols</span>&nbsp;variable, which was error prone in our previous implementation.</div>
<div class=""><br class="">
</div>
<div class="">The scope of contextual variables should not be limited to type declarations. One may want to declare them in the global scope of a module, so that they would be part of the API of a library. Imagine for instance a web framework library, using
 contextual variables to provide the context of a request handler:</div>
<div class=""><br class="">
</div>
<div class="">
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);">
<span class="" style="font-variant-ligatures: no-common-ligatures;">// In the framework ...</span></div>
</div>
<div class="">
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="" style="color: rgb(186, 45, 162);">public context</span>&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">var</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;authInfo:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">AuthInfo</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;">
<span class="" style="font-variant-ligatures: no-common-ligatures;"></span><br class="">
</div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;">
<div class="" style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);"><span class="" style="font-variant-ligatures: no-common-ligatures;">// In the user code ...</span></div>
</div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">framework.addHandler(for: URL(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">&quot;/index&quot;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">))
 {</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">guard</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">let</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;user
 = authInfo?.user&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">else</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;{</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">return</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;Redirect(to:
 URL(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">&quot;/login&quot;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">))</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; }</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;">
<span class="" style="font-variant-ligatures: no-common-ligatures;"></span><br class="">
</div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">return</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;Response(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">&quot;Welcome
 back&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">\</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">(</span><span class="" style="font-variant-ligatures: no-common-ligatures;">user.name</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">)!&quot;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">}</span></div>
</div>
<div class=""><br class="">
</div>
<div class="">In that example, one could imagine that the framework would set the contextual&nbsp;<font face="Menlo" class="" style="font-size: 11px;">authInfo</font>&nbsp;variable with the authentication information it would parse from the request before calling the
 registered handlers.</div>
<div class=""><br class="">
</div>
<div class="">This idea is not exactly new. In fact, people familiar with Python may recognise some similarities with how &quot;<font face="Menlo" class="" style="font-size: 11px;">with</font>&nbsp;statements&quot; work. Hence, it is not surprising that things one is able
 to do with Python’s contexts would be possible to do with contextual variables as presented above. Consider for instance the following class:</div>
<div class=""><br class="">
</div>
<div class="">
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">class</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;Connexion {</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">init</span><span class="" style="font-variant-ligatures: no-common-ligatures;">(to:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">URL</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)
 {&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 132, 0);">/* ... */</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;}</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;"><br class="">
</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">deinit</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;{</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">self</span><span class="" style="font-variant-ligatures: no-common-ligatures;">.disconnect()</span></div>
<div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;}</span></div>
</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;">
<span class="" style="font-variant-ligatures: no-common-ligatures;"></span><br class="">
</div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">func</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;disconnect()
 {&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 132, 0);">/* ... */</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;}</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;">
}<span class="" style="font-variant-ligatures: no-common-ligatures;"></span></div>
</div>
<div class=""><span class="" style="font-variant-ligatures: no-common-ligatures;"><br class="">
</span></div>
<div class="">Thanks to Swift’s memory lifecycle, instantiating an instance of&nbsp;<span class="" style="font-family: Menlo; font-size: 11px;">Connexion</span>&nbsp;as a contextual variable would automatically call its destructor when the context would get popped out.</div>
<div class=""><br class="">
</div>
<div class=""><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;"><span class="" style="color: rgb(186, 45, 162);">context</span>&nbsp;</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">var</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;">&nbsp;conn:&nbsp;</span><span class="" style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">Connexion</span></div>
<div class="">
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">
<span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="" style="color: rgb(186, 45, 162);">set</span>&nbsp;conn = Connexion(to: URL(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">&quot;<a href="http://some.url.com" class="">http://some.url.com</a>&quot;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">))&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">in</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;{</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);">
<span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">/* ... */</span></div>
<div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);">
<span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);">}&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures;">// the first connection is disconnected here</span></div>
</div>
<div class=""><br class="">
</div>
<div class="">I see many other applications for such contextual variables, but I think this email is long enough.</div>
<div class="">I’m looking forward to your thought and feedbacks.</div>
<div class=""><br class="">
</div>
<div class="">Best regards,</div>
<div class=""><br class="">
</div>
<br class="">
<div class="">
<div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">
Dimitri Racordon<br class="">
CUI, Université de Genève<br class="">
7, route de Drize, CH-1227 Carouge - Switzerland<br class="">
Phone: &#43;41 22 379 01 24</div>
</div>
<br class="">
</body>
</html>