3 ms·
There are two reasons why I disagree that `with` shouldn't be a function. The first is evaluation order; the proposed function form has will leak resources if t
by deathanatos 9y ago
There are two reasons why I disagree that `with` shouldn't be a function. The first is evaluation order; the proposed function form has will leak resources if the latter argument's expression raises, that is, in:
with(obtain_resource(), make_function_to_process_resource())
if `make_function_to_process_resource` raises, we leak the resource. You can, of course, pass a function as the first argument to fix this…
with(lambda: obtain_resource(), make_function_to_process_resource())
and we're good again, but I think this is why the syntax is nice. It's sugar.
The other problem would be lexical scoping:
with(lambda: open('foo'), |fobj|:
data = fobj.read() # data is bound to the wrong scope!
)
Assuming we're ignoring Python 2, we can work around that,
data = None
with(lambda: open('foo'), |fobj|:
nonlocal data
data = fobj.read() # data is bound to the wrong scope!
)
The sugar gets sweeter.
(I suppose we could also copy how Ruby does scoping/binding, since we're copying syntax. I also think this is why a let keyword is nice.)
I don't think the above arguments invalidate his general argument for a better multi-line lambda syntax, just the argument for with-as-a-function. (Though he was using that to support multi-line lambdas as a potential use-case, and I don't think that's really the case.) I'm just not as bothered by having to def a function, in practice…