[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