[Python-ideas] easy thread-safety [was: fork]
Steven D'Aprano
steve at pearwood.info
Fri Aug 21 04:57:11 CEST 2015
On Thu, Aug 20, 2015 at 04:02:52PM -0400, Ron Adam wrote:
> The semantics is to have a way to make names (for mutable objects) in
> outer scopes not be visible to function defined in inner scopes.
Why would you want that? This is a serious question -- there is already
an easy way to ensure that two functions can't see the other's
variables: *don't* nest them. The reason for nesting them is to ensure
that the inner function *can* see the outer's variables. That's the
whole point of nesting.
So instead of this:
> def foo(x):
> """ Example of hiding a mutable object from inner scopes. """
> mutable items
> items = [1, 2, 3]
> def bar(y):
> """ can't see items here. So can't mutate it."""
> return -y
> return [bar(y)+x for y in items]
we can write this, with no new keyword, and it will work today:
def foo(x):
items = [1, 2, 3]
return [bar(y)+x for y in items]
def bar(y):
"""can't see items here. So can't mutate it."""
return -y
The only reason to nest bar inside foo is if you want bar to have access
to foo's namespace.
> So foo is able to protect items from being mutated by functions defined
> in it's scope.
But functions defined inside foo are under foo's control. They are part
of foo. foo can mutate items, say by calling items.append(1); why do you
think it matters whether the call to append comes from inside a
subfunction or not? Either way, it is still inside foo and part of
foo's responsibility.
The danger comes, not from the inside of foo, but from the outside of
foo. foo has no way of knowing whether some other function, let's call
it spam, has access to the *object* items (not the name!) and is
mutating it. That is a real danger in threaded programming, but your
proposal does nothing to protect against it. The danger comes from
shared mutable state, not nested namespaces.
> It may seem like it isn't needed, because you have control over what a
> function has access too... ie... just don't do that. But when you have
> many programmers working on large projects, things can get messy. And
> this helps with that, but also helps in the case of threads.
At the point that you're worried about a single function being so
complicated or big that developers might accidentally mutate a value
inside that function, worrying about nested functions is superfluous:
def spam(obj):
obj.mutate()
def foo():
obj = something_mutable() # Don't mutate it!
def inner():
obj.mutate()
# masses of code
# more masses of code
# even more code still
obj.mutate() # No protection offered against this
spam(obj) # or this
inner() # but this is protected against
Why bother singling out such an unlikely and specific source of
problems?
--
Steve
More information about the Python-ideas
mailing list