syntax for preset locals without using dummy args with defaults
Andrew McGregor
andrew at indranet.co.nz
Mon Jan 13 15:18:52 EST 2003
--On Monday, January 13, 2003 18:17:35 +0200 Beni Cherniavsky
<cben at techunix.technion.ac.il> wrote:
> On 2003-01-11, Bengt Richter wrote:
>
>> My first choice would be a new keyword to provide a place other than the
>> parameter list to specify the def-time code that generates the local
>> bindings in question (e.g., z above):
>>
>> def foo(x, y=default):
>> preset: z=some_expression
>> ...
>>
>> IOW, the suite of "preset:" would be compiled to be executed at def-time
>> rather than call-time. I.e., the code would go into the same context as
>> the code that evaluates default parameter expressions, not into the body
>> of the call-time function code. Having a full suite would allow
>> exception handling and raising in that context, and uncaught exceptions
>> would propagate the same way def-time default value expression
>> exceptions do.
>>
> That's precisely the problem with it. Consider the lisp/scheme way to
> create functions with preset bindings, (including the "static" behaviour,
> since python's restrictions against changing bindings in outer scopes
> don't apply):
>
> (let ((z zome_expression))
> (define (foo x y)
> ...))
>
> Note that the binding is computed when the function is created and not
> when it's run - and that's precisely how it's written. Currently I can
> blindly assume that the body of a def is not executed immediately. With
> your preset syntax, I must be wary when reading defs. It'd be like lisp's
> backquote, a.k.a. semi-quote (which allows special markers inside the
> quoted expression to "unquote" parts of it) that requires more attention
> from the reader than simple quoting.
More like a macro with some quoted some unquoted arguments than partial
quoting. Of course, that's exactly what let *is*.
> 1. Most would probably consider this a YAGNI for adding a new keyword.
>
> 2. I see no elegant syntax to allow multiple bindings on the same level
> (e.g. let and not "poor-man's let*"). For multiple bindings that
> are not inter-dependent, nesting the lets is visually sub-optimal...
> The closest thing in python for simultatneous bindings is augmented
> assignment but it was not designed for this case (no var-value pairs
> ordering and doesn't continue for many lines.
How about:
with:
z = some_expression
z1 = some_other_expression
# for consistency, should allow this too.
def quux(bar):
do_something()
do:
def foo(x, y=default):
do_stuff()
One could of course use 'let' instead of 'with'. This nests, too, and
provides a tidy way to statically rebind things locally for both
performance and readability (for instance, the 'self' threads).
This moves the def-time stuff to somewhere that is explicitly done at def
time, and looks like it.
> 3. The same reason why Python avoids nesting scopes in e.g. a for loop:
> currently, the scope-creating constructs (def & class) make all
> inner assignments have a new scope. So introducing anything that
> behaves otherwise would make scoping less consistent and "harder to
> explain". On the other hand, it would also make it much easier to use
> and I believe the later should win.
I tend to agree.
Andrew
More information about the Python-list
mailing list