[e-lang] An object-capability subset of Python
Brett Cannon
brett at python.org
Fri Aug 15 13:16:35 CDT 2008
On Fri, Aug 15, 2008 at 10:37 AM, Mark Seaborn <mrs at mythic-beasts.com> wrote:
> "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
>
Basically.
> 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.
>
Nope, and I never thought any solution I came up with that could
possibly end up in Python itself would.
But you can still uses classes to define code. Just off the top of my head::
def new_instance():
private = 42
class Foo(object):
def get(self): return private
return Foo()
> * 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.
>
Never said it was an elegant solution. =)
> 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.
3.0 is scheduled for the first week of October, so it won't be much longer.
> 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.
>
As I said, I don't claim what I have proposed is elegant or perfect,
just that it allows for the possibility of some form of private
namespace that could be acceptable enough to be integrated into
Python.
-Brett
More information about the e-lang
mailing list