[e-lang] An object-capability subset of Python
Mark Seaborn
mrs at mythic-beasts.com
Fri Aug 15 12:37:08 CDT 2008
"Brett Cannon" <brett at python.org> wrote:
> Another option, Mark, would be to prevent access to the free variables
> in a closure from outside of a function. If you plug that you can use
> closures to provide your private namespace much like you do in
> JavaScript. The perk with this is there is a chance of actually
> getting this back into the language by removing the __closure__
> attribute on functions (or at least I am contemplating trying this at
> some point).
I assume you are suggesting a Cajita style scheme where objects are
built out of function closures, with one function per method. There's
an example of that in this post by Ka-Ping Yee from 2003:
http://mail.python.org/pipermail/python-dev/2003-March/034287.html
The problem with this is:
* By itself it doesn't help with defining encapsulated objects via
class definitions, so it doesn't help with the bulk of existing
Python code.
* It's quite awkward to write code in this style. It's harder than in
Javascript because of Python's variable binding semantics and other
syntactic shortcuts.
For example, this code does not work, because the second "count" does
not refer to the first "count" in the enclosing scope. The assignment
introduces a new binding inside "get_next":
def make_counter():
count = 0
def get_next():
count += 1
return count
return get_next
PEP 3104 [1] is introducing a "nonlocal" declaration that allows this
to be written correctly as:
def make_counter():
count = 0
def get_next():
nonlocal count
count += 1
return count
return get_next
But this syntax won't appear until Python 3.0 which hasn't been
released yet, and the syntax is not entirely obvious. I think
"nonlocal" declarations will be OK and useful for the occasional use,
but if it has to be done for every other method definition it will get
tedious pretty quickly.
Suppose you define an object with multiple methods like this:
def make_point(x, y):
def get_x():
return x
def get_y():
return y
return MakeObject({"get_x": get_x, "get_y": get_y})
In order to combine the closures into an object, you have to mention
each method name three times, which is tedious. (We could get that
down to two times per method by using the __name__ attribute of the
functions, although I would be reluctant to rely on __name__.)
Javascript does not have this problem because the methods can be
defined inline inside a single expression. Python, with its
separation of expressions and statements (which comes from its
indentation-based block syntax), does not allow that, except for
lambda expressions, which can only contain a single expression.
There's also an efficiency issue. In the Cajita-style scheme, an
object with N methods requires O(N) allocations, whereas using Python
classes does not require these allocations.
Regards,
Mark
[1] http://www.python.org/dev/peps/pep-3104/
More information about the e-lang
mailing list