"no variable or argument declarations are necessary."

Bengt Richter bokr at oz.net
Thu Oct 6 02:14:38 EDT 2005


On 5 Oct 2005 09:27:04 GMT, Duncan Booth <duncan.booth at invalid.invalid> wrote:

>Antoon Pardon wrote:
>
>> It also is one possibility to implement writable closures.
>> 
>> One could for instace have a 'declare' have the effect that
>> if on a more inner scope such a declared variable is (re)bound it
>> will rebind the declared variable instead of binding a local name.
>
>That is one possibility, but I think that it would be better to use a 
>keyword at the point of the assigment to indicate assignment to an outer 
>scope. This fits with the way 'global' works: you declare at (or near) the 
>assignment that it is going to a global variable, not in some far away part 
>of the code, so the global nature of the assignment is clearly visible. The 
>'global' keyword itself would be much improved if it appeared on the same 
>line as the assignment rather than as a separate declaration.
>
>e.g. something like:
>
>var1 = 0
>
>def f():
>  var2 = 0
>
>  def g():
>     outer var2 = 1 # Assign to outer variable
>     global var1 = 1 # Assign to global

IMO you don't really need all that cruft most of the time. E.g., what if ':='
meant 'assign to variable wherever it is (and it must exist), searching according
to normal variable resolution order (fresh coinage, vro for short ;-), starting with
local, then lexically enclosing and so forth out to module global (but not to builtins).'

If you wanted to assign/rebind past a local var shadowing an enclosing variable var, you'd have
to use e.g. vro(1).var = expr instead of var := expr.  Sort of analogous to
type(self).mro()[1].method(self, ...)   Hm, vro(1).__dict__['var'] = expr could conceivably
force binding at the vro(1) scope specifically, and not search outwards. But for that there
would be optimization issues I think, since allowing an arbitrary binding would force a real
dict creation on the fly to hold the the new name slot.

BTW, if/when we can push a new namespace on top of the vro stack with a 'with namespace: ...' or such,
vro(0) would still be at the top, and vro(1) will be the local before the with, and := can still
be sugar for find-and-rebind.

Using := and not finding something to rebind would be a NameError. Ditto for
vro(n).nonexistent_name_at_level_n_or_outwards. vro(-1) could refer global module scope
and vro(-2) go inwards towards local scope at vro(0). So vro(-1).gvar=expr would
give you the effect of globals()['gvar']=expr with a pre-existence check.

The pre-existence requirement would effectively be a kind of declaration requirement for
the var := expr usage, and an initialization to a particular type could enhance inference.
Especially if you could have a decorator for statements in general, not just def's, and
you could then have a sticky-types decoration that would say certain bindings may be inferred
to stick to their initial binding's object's type.

Rambling uncontrollably ;-)
My .02USD ;-)

Regards,
Bengt Richter



More information about the Python-list mailing list