I am considering developing a PEP for enabling a mechanism to assign to
free variables in a closure (nested function).&nbsp; My rationale is that with the advent of <a href="http://www.python.org/peps/pep-0227.html" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">PEP 227</a>
<span>, P</span><span></span>ython
has proper nested lexical scopes, but can have undesirable behavior
(especially with new developers) when a user makes wants to make an
assignment to a free variable within a nested function.&nbsp;
Furthermore,
after seeing numerous kludges to &quot;solve&quot; the problem with a mutable
object, like a list, as the free variable do not seem
&quot;Pythonic.&quot;&nbsp; I have also seen mention that the use of classes can
mitigate this, but that seems, IMHO, heavy handed in cases when an
elegant solution using a closure would suffice and be more
appropriate--especially when Python
already has nested lexical scopes.<span></span><br>
<br>
I propose two possible approaches to solve this issue:<br>
<br>
1.&nbsp; Adding a keyword such as &quot;<span style="font-family: courier new,monospace;">use</span>&quot; that would follow similar semantics as &quot;<span style="font-family: courier new,monospace;">global</span>&quot;
does today.&nbsp; A nested scope could declare names with this keyword
to enable assignment to such names to change the closest parent's
binding.&nbsp; The semantic would be to keep the behavior we experience
today but tell the compiler/interpreter that a name declared with the &quot;<span style="font-family: courier new,monospace;">use</span>&quot;
keyword would explicitly use an enclosing scope.&nbsp; I personally like
this approach the most since it would seem to be in keeping with the
current way the language works and would probably be the most
backwards compatible.&nbsp; The semantics for how this interacts with
the global scope would also need to be defined (should &quot;<span style="font-family: courier new,monospace;">use</span>&quot; be equivalent to a global when no name exists all parent scopes, etc.)<br>
<br>
<div style="margin-left: 40px;"><span style="font-family: courier new,monospace;">def incgen( inc = 1 ) :<br>
&nbsp; a = 6<br>
&nbsp; def incrementer() :<br>
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">use</span> a<br>
&nbsp;&nbsp;&nbsp; <span style="font-style: italic;">#use a, inc &lt;-- list of names okay too</span><br>
&nbsp;&nbsp;&nbsp; a += inc<br>
&nbsp;&nbsp;&nbsp; return a<br>
&nbsp; return incrementer<br>
</span></div>

<br>
Of course, this approach suffers from a downside that every nested
scope that wanted to assign to a parent scope's name would need to have
the &quot;<span style="font-family: courier new,monospace;">use</span>&quot;
keyword for those names--but one could argue that this is in keeping
with one of Python's philosophies that &quot;Explicit is better than
implicit&quot; (<a href="http://www.python.org/peps/pep-0020.html" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">PEP 20</a>).&nbsp; This approach also has to deal with a user declaring a name with &quot;
<span style="font-family: courier new,monospace;">use</span>&quot; that is a named parameter--this would be a semantic error that could be handled like &quot;<span style="font-family: courier new,monospace;">global</span>
&quot; does today with a SyntaxError.<br>
<br>
2.&nbsp; Adding a keyword such as <span style="font-family: courier new,monospace;"></span>&quot;<span style="font-family: courier new,monospace;">scope</span>&quot; that would behave similarly to JavaScript's &quot;<span style="font-family: courier new,monospace;">
var</span>&quot;
keyword.&nbsp; A name could be declared with such a keyword optionally
and all nested scopes would use the declaring scope's binding when
accessing or assigning to a <span id="__firefox-findbar-search-id" style="background-color: yellow;"></span>particular name.&nbsp; This approach has similar
benefits to my first approach, but is clearly more top-down than the
first approach.&nbsp; Subsequent &quot;<span style="font-family: courier new,monospace;">scope</span>&quot;
declarations would create a new binding at the declaring scope for the
declaring and child scopes to use.&nbsp; This could potentially be a
gotcha for users expecting the binding semantics in place today.&nbsp;
Also the scope keyword would have to be allowed to be used on
parameters to allow such parameter names to be used in a similar
fashion in a child scope.<br>
<br>
<div style="margin-left: 40px;"><span style="font-family: courier new,monospace;">def incgen( inc = 1 ) :<br>
&nbsp; <span style="font-style: italic;">#scope inc &lt;-- allow scope declaration for bound parameters (not a big fan of this)</span><br>
<span style="font-style: italic;">
</span>&nbsp; <span style="font-weight: bold;">scope</span> a = 6<span style="font-style: italic;"></span><br>
&nbsp; def incrementer() :<br>
&nbsp;&nbsp;&nbsp; a += inc<br>
&nbsp;&nbsp;&nbsp; return a<br>
&nbsp; return incrementer<br>
</span></div>
<br>
This approach would be similar to languages like JavaScript that allow for explicit scope binding with the use of &quot;<span style="font-family: courier new,monospace;">var</span>&quot;
or more static languages that allow re-declaring names at lower
scopes.&nbsp; I am less in favor of this, because I don't think it
feels very &quot;Pythonic&quot;.<span style="font-family: courier new,monospace;"></span><br>
<br>
As a point of reference, some languages such as Ruby will only bind a
new name to a scope on assignment when an enclosing scope does not have
the name bound.&nbsp; I do believe the Python name binding semantics
have issues (for which the &quot;<span style="font-family: courier new,monospace;">global</span>&quot;
keyword was born), but I feel that the &quot;fixing&quot; the Python semantic to
a more &quot;Ruby-like&quot; one adds as many problems as it solves since the
&quot;Ruby-like&quot; one is just as implicit in nature.&nbsp; Not to mention the
backwards compatibility impact is probably much larger.<span style="font-family: courier new,monospace;"></span><br>
<br>I would like the community's opinion if there is enough out there
that think this would be a worthwile endevour--or if there is already
an initiative that I missed.&nbsp; Please let me know your questions,
comments.<br>
<br>
Best Regards,<br>
Almann<br clear="all"><br>-- <br>Almann T. Goo<br><a href="mailto:almann.goo@gmail.com" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">almann.goo@gmail.com</a>