I am considering developing a PEP for enabling a mechanism to assign to
free variables in a closure (nested function). 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.
Furthermore,
after seeing numerous kludges to "solve" the problem with a mutable
object, like a list, as the free variable do not seem
"Pythonic." 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. Adding a keyword such as "<span style="font-family: courier new,monospace;">use</span>" that would follow similar semantics as "<span style="font-family: courier new,monospace;">global</span>"
does today. A nested scope could declare names with this keyword
to enable assignment to such names to change the closest parent's
binding. The semantic would be to keep the behavior we experience
today but tell the compiler/interpreter that a name declared with the "<span style="font-family: courier new,monospace;">use</span>"
keyword would explicitly use an enclosing scope. 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. The semantics for how this interacts with
the global scope would also need to be defined (should "<span style="font-family: courier new,monospace;">use</span>" 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>
a = 6<br>
def incrementer() :<br>
<span style="font-weight: bold;">use</span> a<br>
<span style="font-style: italic;">#use a, inc <-- list of names okay too</span><br>
a += inc<br>
return a<br>
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 "<span style="font-family: courier new,monospace;">use</span>"
keyword for those names--but one could argue that this is in keeping
with one of Python's philosophies that "Explicit is better than
implicit" (<a href="http://www.python.org/peps/pep-0020.html" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">PEP 20</a>). This approach also has to deal with a user declaring a name with "
<span style="font-family: courier new,monospace;">use</span>" that is a named parameter--this would be a semantic error that could be handled like "<span style="font-family: courier new,monospace;">global</span>
" does today with a SyntaxError.<br>
<br>
2. Adding a keyword such as <span style="font-family: courier new,monospace;"></span>"<span style="font-family: courier new,monospace;">scope</span>" that would behave similarly to JavaScript's "<span style="font-family: courier new,monospace;">
var</span>"
keyword. 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. This approach has similar
benefits to my first approach, but is clearly more top-down than the
first approach. Subsequent "<span style="font-family: courier new,monospace;">scope</span>"
declarations would create a new binding at the declaring scope for the
declaring and child scopes to use. This could potentially be a
gotcha for users expecting the binding semantics in place today.
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>
<span style="font-style: italic;">#scope inc <-- allow scope declaration for bound parameters (not a big fan of this)</span><br>
<span style="font-style: italic;">
</span> <span style="font-weight: bold;">scope</span> a = 6<span style="font-style: italic;"></span><br>
def incrementer() :<br>
a += inc<br>
return a<br>
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 "<span style="font-family: courier new,monospace;">var</span>"
or more static languages that allow re-declaring names at lower
scopes. I am less in favor of this, because I don't think it
feels very "Pythonic".<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. I do believe the Python name binding semantics
have issues (for which the "<span style="font-family: courier new,monospace;">global</span>"
keyword was born), but I feel that the "fixing" the Python semantic to
a more "Ruby-like" one adds as many problems as it solves since the
"Ruby-like" one is just as implicit in nature. 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. 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>