Re: An object-capability subset of Python
"Brett Cannon" <[email protected]>
| Newsgroups | gmane.comp.lang.e.general |
|---|---|
| Message-ID | <[email protected]> |
On Fri, Aug 15, 2008 at 10:37 AM, Mark Seaborn <mrs-ChQETwBkFSdCgCasaBwmdgC/[email protected]> wrote: > "Brett Cannon" <[email protected]> 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