Re: [Python-Dev] [Python-3000] Pre-pre PEP for 'super' keyword

2007-05-04 Thread Steve Holden
Tristan Seligmann wrote:
 * Guido van Rossum [EMAIL PROTECTED] [2007-04-29 18:19:20 -0700]:
 
 In my mind, 'if' and 'or' are syntax, whereas things like 'None' or
 'True' are values; even if None becomes an actual keyword, rather than
 a builtin.
 I'm sorry, but that is such an incredibly subjective difference that I
 can't do anything with it. String literals and numeric literals are
 syntax too, even though they are values. A keyword, or reserved word,
 is simply something that looks like an identifier but is converted
 into a different token (by the lexer or by something sitting between
 the lexer and the parse) before the parser sees it.
 
 Let me try a less subjective description. Things like None, 2.3, 'foo',
 True are values or expressions; I'm not certain exactly what the term
 for these is in Python's grammar, but I basically mean something that
 can be on the RHS of an assignment.. However, something like 'for' or
 'if' is part of some other grammatical construct, generally a statement
 or operator of some kind, so I tend to think of those differently.
 

How about a keyword is an identifier that appears as a literal in the 
grammar?

regards
  Steve
-- 
Steve Holden+1 571 484 6266   +1 800 494 3119
Holden Web LLC/Ltd   http://www.holdenweb.com
Skype: holdenweb  http://del.icio.us/steve.holden
-- Asciimercial -
Get on the web: Blog, lens and tag your way to fame!!
holdenweb.blogspot.comsquidoo.com/pythonology
tagged items: del.icio.us/steve.holden/python
All these services currently offer free registration!
-- Thank You for Reading 

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-3000] Pre-pre PEP for 'super' keyword

2007-04-30 Thread Ron Adam
Delaney, Timothy (Tim) wrote:

 What I'm proposing is that the `super = super_factory()` line be
 implicit in this case, resulting in the following code behaving
 identically:
 
 class A(object):
 def f(self):
 def inner():
 return 'A' + super.f()
 
 print inner()


As Guido pointed out it has some resemblance to how import works, but I 
also think there is resemblance to the context of how global is used.  So 
if it is made into a keyword, could it work like the global keyword?

class A(object):
def f(self):
def inner():
super f
return 'A' + f()

print inner()

Cheers,
Ron

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-3000] Pre-pre PEP for 'super' keyword

2007-04-30 Thread Tim Delaney
From: Delaney, Timothy (Tim) [EMAIL PROTECTED]

 Sorry - this is related to my proposal that the following two bits of
 code behave the same:

class A(object):
def f(self, *p, **kw):
super.f(*p, **kw)

class A(object):
def f(self, *p, **kw):
super(*p, **kw)

 But as has been pointed out, this creates an ambiguity with:

class A(object):
def f(self, *p, **kw):
super.__call__(*p, **kw)

 so I want to see if I can resolve it.

A 'super' instance would be callable, without being able to access it's 
__call__ method (because super.__call__ would refer to the base class method 
of that name).

But I find I really don't care. The only place where that would really 
matter IMO is if you want to find out if a 'super' instance is callable. 
Calling a base class __call__ method would not be ambiguous - the following 
two classes would work the same:

class A(object):
def __call__(self, *p, **kw):
return super.__call__(*p, **kw)

class A(object):
def __call__(self, *p, **kw):
return super(*p, **kw)

So, I guess my question is whether the most common case of calling the base 
class method with the same name is worth having some further syntactic sugar 
to avoid repetition? I think it is, but that would be your call Guido.

Cheers,

Tim Delaney 

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-3000] Pre-pre PEP for 'super' keyword

2007-04-30 Thread Calvin Spealman
On 4/30/07, Delaney, Timothy (Tim) [EMAIL PROTECTED] wrote:
 Guido van Rossum wrote:

  1. When a method is defined, the class is bound to it via an
 attribute
  (which in my version is called func_class).

  In Py3k all the func_XXX attrs are renamed __XXX__, so this would be
  __class__; but that's a name reserved for something else, so it would
  need to be something else.  E.g. __containing_class__.

 Yep - I've just used a placeholder name.

  Also, this would have to be done when the class is defined; when the
  method is being defined the class doesn't exist yet.

 Good point. Change that to at the first opportunity ;)

  2. Every non-static method has an implicit cell variable called
  'super'.
 
  I think you're using 'cell' in a different sense than it is normally
  used in Python's implementation. What you are looking for is called a
  local variable (I deduce this from your initialization of the cell
  with something computed from the first argument).

 Actually, I think I'm using the terminology correctly - I'm talking
 about an entry in co_cellvars. Given the following class:

 class A(object):
 def f(self):
 super = super_factory()

 def inner():
 return 'A' + super.f()

 print inner()

 the use of 'super' in both A.f and A.f.inner will produce an entry in
 A.f.func_code.co_cellvars and A.f.inner.func_code.co_freevars. What I'm
 proposing is that the `super = super_factory()` line be implicit in this
 case, resulting in the following code behaving identically:

 class A(object):
 def f(self):
 def inner():
 return 'A' + super.f()

 print inner()

I believe the direction my PEP took with all this is a good bit
primitive compared to this approach, although I still find value in it
because at least a prototype came out of it that can be used to test
the waters, regardless of if a more direct-in-the-language approach
would be superior.

However, I seem to think that if the __this_class__ PEP goes through,
your version can be simplified as well. No tricky stuffy things in
cells would be needed, but we can just expand the super 'keyword' to
__super__(__this_class__, self), which has been suggested at least
once. It seems this would be much simpler to implement, and it also
brings up a second point.

Also, I like that the super object is created at the beginning of the
function, which my proposal couldn't even do. It is more efficient if
you have multiple super calls, and gets around a problem I completely
missed: what happens if the instance name were rebound before the
implicit lookup of the instance object at the time of the super call?

  The issue of super() vs. super.__call__() ambiguity - I'll need to
  look at that when I get home.
 
  Sounds irrelevant -- if super is equivalent to
  __builtin__.__super__(class, firstarg) then super never gets
  called; the only thing ever done to it (in the normal course of
  things) is to request an attribute of it.

 Sorry - this is related to my proposal that the following two bits of
 code behave the same:

 class A(object):
 def f(self, *p, **kw):
 super.f(*p, **kw)

 class A(object):
 def f(self, *p, **kw):
 super(*p, **kw)

 But as has been pointed out, this creates an ambiguity with:

 class A(object):
 def f(self, *p, **kw):
 super.__call__(*p, **kw)

 so I want to see if I can resolve it.

Turns out, it doesn't. A lot of people expect it, but it turns out to
be simple. super(*p, **kw) is not equivalent to super.__call__(*p,
**kw) but to type(super).__call__.__get__(super, type(super))(*p,
**kw), due to operator methods being looked up on the type directly
and bound by the descriptor, without any lookup on the super object
itself. Thus, no attribute is ever done on the super object itself,
type(super).__getattribute__ is never invoked, and there is no problem
at all.

This also means we can still invoke super the old, explicit way.

I've already got my copy of the PEP updated to reflect this.

  super(ThisClass).method(...)  # ???
 
  The third exists so that you can create an unbound super instance
  which is useful for the oft-misunderstood autosuper example in my
  descrintro essay:
 
 http://www.python.org/download/releases/2.2.3/descrintro/#metaclass_exam
 ples
  .
 
  But since the latter is the hack that we're trying to replace with a
  proper implementation here, I suspect we can get away with only
  supporting the first two forms (and the third form is still supported
  using __builtin__.__super__).

 Yep - that's my thought as well. I think it would be very rare to need
 super(ThisClass), although it makes some sense that that would be what
 super means in a static method ...

Does super mean anything in a static method today?

-- 
Read my blog! I depend on your acceptance of my opinion! I am interesting!
http://ironfroggy-code.blogspot.com/

Re: [Python-Dev] [Python-3000] Pre-pre PEP for 'super' keyword

2007-04-30 Thread Tim Delaney
From: Calvin Spealman [EMAIL PROTECTED]

 I believe the direction my PEP took with all this is a good bit
 primitive compared to this approach, although I still find value in it
 because at least a prototype came out of it that can be used to test
 the waters, regardless of if a more direct-in-the-language approach
 would be superior.

I've been working on improved super syntax for quite a while now - my 
original approach was 'self.super' which used _getframe() and mro crawling 
too. I hit on using bytecode hacking to instantiate a super object at the 
start of the method to gain performance, which required storing the class in 
co_consts, etc. It turns out that using a metaclass then makes this a lot 
cleaner.

 However, I seem to think that if the __this_class__ PEP goes through,
 your version can be simplified as well. No tricky stuffy things in
 cells would be needed, but we can just expand the super 'keyword' to
 __super__(__this_class__, self), which has been suggested at least
 once. It seems this would be much simpler to implement, and it also
 brings up a second point.

 Also, I like that the super object is created at the beginning of the
 function, which my proposal couldn't even do. It is more efficient if
 you have multiple super calls, and gets around a problem I completely
 missed: what happens if the instance name were rebound before the
 implicit lookup of the instance object at the time of the super call?

You could expand it inline, but I think your second point is a strong 
argument against it. Also, sticking the super instance into a cell means 
that inner classes get access to it for free. Otherwise each inner class 
would *also* need to instantiate a super instance, and __this_class__ (or 
whatever it's called) would need to be in a cell for them to get access to 
it instead.

BTW, one of my test cases involves multiple super calls in the same method - 
there is a *very* large performance improvement by instantiating it once.

 I think it would be very rare to need
 super(ThisClass), although it makes some sense that that would be what
 super means in a static method ...

 Does super mean anything in a static method today?

Well, since all super instantiations are explicit currently, it can mean 
whatever you want it to.

class A(object):

@staticmethod
def f():
print super(A)
print super(A, A)

Cheers,

Tim Delaney 

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-3000] Pre-pre PEP for 'super' keyword

2007-04-30 Thread Calvin Spealman
On 4/30/07, Tim Delaney [EMAIL PROTECTED] wrote:
 I've been working on improved super syntax for quite a while now - my
 original approach was 'self.super' which used _getframe() and mro crawling
 too. I hit on using bytecode hacking to instantiate a super object at the
 start of the method to gain performance, which required storing the class in
 co_consts, etc. It turns out that using a metaclass then makes this a lot
 cleaner.

  However, I seem to think that if the __this_class__ PEP goes through,
  your version can be simplified as well. No tricky stuffy things in
  cells would be needed, but we can just expand the super 'keyword' to
  __super__(__this_class__, self), which has been suggested at least
  once. It seems this would be much simpler to implement, and it also
  brings up a second point.
 
  Also, I like that the super object is created at the beginning of the
  function, which my proposal couldn't even do. It is more efficient if
  you have multiple super calls, and gets around a problem I completely
  missed: what happens if the instance name were rebound before the
  implicit lookup of the instance object at the time of the super call?

 You could expand it inline, but I think your second point is a strong
 argument against it. Also, sticking the super instance into a cell means
 that inner classes get access to it for free. Otherwise each inner class
 would *also* need to instantiate a super instance, and __this_class__ (or
 whatever it's called) would need to be in a cell for them to get access to
 it instead.

 BTW, one of my test cases involves multiple super calls in the same method -
 there is a *very* large performance improvement by instantiating it once.

Note that I would now advocate the creation of the super object at the
beginning of function, and when I talk about expanding super to
super(__this_class__, self) I do mean doing it at the beginning of the
function, just like you are saying, so we're in agreement here.

-- 
Read my blog! I depend on your acceptance of my opinion! I am interesting!
http://ironfroggy-code.blogspot.com/
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-3000] Pre-pre PEP for 'super' keyword

2007-04-30 Thread Guido van Rossum
On 4/29/07, Delaney, Timothy (Tim) [EMAIL PROTECTED] wrote:
 Guido van Rossum wrote:
  2. Every non-static method has an implicit cell variable called
  'super'.
 
  I think you're using 'cell' in a different sense than it is normally
  used in Python's implementation. What you are looking for is called a
  local variable (I deduce this from your initialization of the cell
  with something computed from the first argument).

 Actually, I think I'm using the terminology correctly - I'm talking
 about an entry in co_cellvars. Given the following class:

 class A(object):
 def f(self):
 super = super_factory()

 def inner():
 return 'A' + super.f()

 print inner()

 the use of 'super' in both A.f and A.f.inner will produce an entry in
 A.f.func_code.co_cellvars and A.f.inner.func_code.co_freevars. What I'm
 proposing is that the `super = super_factory()` line be implicit in this
 case, resulting in the following code behaving identically:

 class A(object):
 def f(self):
 def inner():
 return 'A' + super.f()

 print inner()

OK, I see now. I thought you meant for the cell-ness to be related to
the basic implementation; but you meant it so that it woks correctly
inside nested functions. That's fine of course. You might clarify this
somewhere.

  The issue of super() vs. super.__call__() ambiguity - I'll need to
  look at that when I get home.
 
  Sounds irrelevant -- if super is equivalent to
  __builtin__.__super__(class, firstarg) then super never gets
  called; the only thing ever done to it (in the normal course of
  things) is to request an attribute of it.

 Sorry - this is related to my proposal that the following two bits of
 code behave the same:

 class A(object):
 def f(self, *p, **kw):
 super.f(*p, **kw)

 class A(object):
 def f(self, *p, **kw):
 super(*p, **kw)

 But as has been pointed out, this creates an ambiguity with:

 class A(object):
 def f(self, *p, **kw):
 super.__call__(*p, **kw)

 so I want to see if I can resolve it.

I think the shortcut is more confusing than helpful; I propose to drop
it for the sake of focusing on the essential.

  super(ThisClass).method(...)  # ???
 
  The third exists so that you can create an unbound super instance
  which is useful for the oft-misunderstood autosuper example in my
  descrintro essay:
 
  http://www.python.org/download/releases/2.2.3/descrintro/#metaclass_exampples
  .
 
  But since the latter is the hack that we're trying to replace with a
  proper implementation here, I suspect we can get away with only
  supporting the first two forms (and the third form is still supported
  using __builtin__.__super__).

 Yep - that's my thought as well. I think it would be very rare to need
 super(ThisClass), although it makes some sense that that would be what
 super means in a static method ...

But that doesn't work with the current (2.x) super, and hasn't been
requested AFAIK, so I'd suggest dropping the use case -- KISS again.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-3000] Pre-pre PEP for 'super' keyword

2007-04-29 Thread Jim Jewett
On 4/29/07, Tim Delaney [EMAIL PROTECTED] wrote:
 I've been intending to write up a PEP for fixing super, but I haven't had
 time to get to it.

Calvin Spealman has the most recent draft. I hope he will incorporate
this into his draft.

 1. 'super' becomes a keyword, that returns a super object for the instance
 method currently being executed.

So it is a keyword in the sense that None is a keyword; not in the
stronger sense that if is a keyword?

 4. super objects are callable, and calling them will execute the super
 method with the same name as the instance method currently being executed.
 Lookup of this method occurs when the instance method is entered.

 class A(object):
 def f(self):
 pass

 class B(A):
 def f(self):
 super() # Calls A.f(self)

 If you want name lookup to occur at the time of the call, you can explicitly
 specify the method name (just like with any other super attribute):

 class A(object):
 def f(self):
 pass

 class B(A):
 def f(self):
 super.f() # Calls A.f(self)

As long as you can be explicit, should the shortcut be a full
shortcut?  That is,

def f(self, a, b=c, *args, **kwargs):
super()# passes the exact arglist that f got

vs

def __init__(self, myvar, passed_var):
super.__init__(self, passed_var)# flags that you are
changing the args

-jJ
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-3000] Pre-pre PEP for 'super' keyword

2007-04-29 Thread Calvin Spealman
On 4/29/07, Jim Jewett [EMAIL PROTECTED] wrote:
 On 4/29/07, Tim Delaney [EMAIL PROTECTED] wrote:
  I've been intending to write up a PEP for fixing super, but I haven't had
  time to get to it.

 Calvin Spealman has the most recent draft. I hope he will incorporate
 this into his draft.

I will incorporate this into my draft, particularly taking care of the
issue with inner functions.

  1. 'super' becomes a keyword, that returns a super object for the instance
  method currently being executed.

 So it is a keyword in the sense that None is a keyword; not in the
 stronger sense that if is a keyword?

I would like to say super becomes a constant in the way that None is a
constant, and if there is some reason the implementation today or
tomorrow can benefit from actually making it a keyword, that won't
break anything if its already constant. One problem with an actual
keyword, is there is no other part of Python where an actual keyword
evaluates to something.

  4. super objects are callable, and calling them will execute the super
  method with the same name as the instance method currently being executed.
  Lookup of this method occurs when the instance method is entered.
 
  class A(object):
  def f(self):
  pass
 
  class B(A):
  def f(self):
  super() # Calls A.f(self)

This might run into the same issue I had to cover, where you get an
ambiguous situation trying to distinguish between calling super and
calling the __call__ method of the next class in the MRO.

We should absolutely avoid a situation in python now where X() differs
from X.__call__()

  If you want name lookup to occur at the time of the call, you can explicitly
  specify the method name (just like with any other super attribute):
 
  class A(object):
  def f(self):
  pass
 
  class B(A):
  def f(self):
  super.f() # Calls A.f(self)

 As long as you can be explicit, should the shortcut be a full
 shortcut?  That is,

 def f(self, a, b=c, *args, **kwargs):
 super()# passes the exact arglist that f got

I sure wish my previous complaints didn't hinder this, because I
really love the idea of being able to this, which would really
encourage more compatible method signatures, so you can use the
shortcut! I'm desperate for a solution that satisfies all the sides of
the equation.

 vs

 def __init__(self, myvar, passed_var):
 super.__init__(self, passed_var)# flags that you are
 changing the args

 -jJ



-- 
Read my blog! I depend on your acceptance of my opinion! I am interesting!
http://ironfroggy-code.blogspot.com/
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-3000] Pre-pre PEP for 'super' keyword

2007-04-29 Thread Guido van Rossum
On 4/29/07, Jim Jewett [EMAIL PROTECTED] wrote:
 So it is a keyword in the sense that None is a keyword; not in the
 stronger sense that if is a keyword?

Um, how do you see those two differ? Is 'if' a keyword in the same
sense as 'or', or in a different sense?

I realize that in Python 2.5, None is not a full-fledged keyword but
cannot be used as an assignment target. But that's only transitional.
In 3.0 I imagine it becoming a keyword in the grammar (whose only
appearance would be as one of the alternatives for 'atom'). And we're
talking 3.0 here.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-3000] Pre-pre PEP for 'super' keyword

2007-04-29 Thread Calvin Spealman
On 4/29/07, Guido van Rossum [EMAIL PROTECTED] wrote:
 On 4/29/07, Jim Jewett [EMAIL PROTECTED] wrote:
  So it is a keyword in the sense that None is a keyword; not in the
  stronger sense that if is a keyword?

 Um, how do you see those two differ? Is 'if' a keyword in the same
 sense as 'or', or in a different sense?

 I realize that in Python 2.5, None is not a full-fledged keyword but
 cannot be used as an assignment target. But that's only transitional.
 In 3.0 I imagine it becoming a keyword in the grammar (whose only
 appearance would be as one of the alternatives for 'atom'). And we're
 talking 3.0 here.

I think any concerns about it not being fit as a keyword would fall
under two catagories or varying validity:
1) Too many keywords is a valid concern, because it complicates the language.
2) It just doesn't feel like a keyword. Less valid, unless it
_really_ doesn't feel like a keyword.

It doesn't feel like a keyword. But it doesn't feel too much not like a keyword.

Anyway, I tried to address the concerns laid out, and I'm more than
happy to alter the PEP to actually say Lets implement this as a
keyword, and I actually meant to keep more agnostic on that point in
the proposal itself. I was more interested in covering the interface,
at least to begin, than the actual implementation. Although, being
able to have a solid, working reference implementation based on the
frame lookups and such is nice, so we can see how it will actually
work in real code, and even use it to backport code using the new
super to just about any recent Python version.

I also checked and PyPy does implement a sys._getframe() and a
IronPython currently doesn't, but seems to plan on it (there is a
placeholder, at present). I am not sure if notes on this belongs in
the PEP or not.

Draft Three follows for all. I think I'm turning off e-mail for the
rest of this evening, so I'll catch up tomorrow.

---

PEP: XXX
Title: New Super
Version: $Revision$
Last-Modified: $Date$
Author: Calvin Spealman [EMAIL PROTECTED]
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 28-Apr-2007
Python-Version: 2.6
Post-History: 28-Apr-2007, 29-Apr-2007 (1), 29-Apr-2007 (2)


Abstract


The PEP defines the proposal to enhance the super builtin to work implicitly
upon the class within which it is used and upon the instance the current
function was called on. The premise of the new super usage suggested is as
follows:

super.foo(1, 2)

to replace the old:

super(Foo, self).foo(1, 2)


Rationale
=

The current usage of super requires an explicit passing of both the class and
instance it must operate from, requiring a breaking of the DRY (Don't Repeat
Yourself) rule. This hinders any change in class name, and is often considered
a wart by many.


Specification
=

Within the specification section, some special terminology will be used to
distinguish similar and closely related concepts. Super type will refer to
the actual builtin type named super. Next Class/Type in the MRO will refer
to the class where attribute lookups will be performed by super, for example,
in the following, A is the Next class in the MRO for the use of super.

::

class A(object):
def f(self):
return 'A'

class B(A):
def f(self):
super(B, self).f() # Here, A would be out Next class in the
   # MRO, of course.

A super object is simply an instance of the super type, which is associated
with a class and possibly with an instance of that class. Finally, new super
refers to the new super type, which will replace the original.

Replacing the old usage of super, calls to the next class in the MRO (method
resolution order) will be made without an explicit super object creation,
by simply accessing an attribute on the super type directly, which will
automatically apply the class and instance to perform the proper lookup. The
following example demonstrates the use of this.

::

class A(object):
def f(self):
return 'A'

class B(A):
def f(self):
return 'B' + super.f()

class C(A):
def f(self):
return 'C' + super.f()

class D(B, C):
def f(self):
return 'D' + super.f()

assert D().f() == 'DBCA'

The proposal adds a dynamic attribute lookup to the super type, which will
automatically determine the proper class and instance parameters. Each super
attribute lookup identifies these parameters and performs the super lookup on
the instance, as the current super implementation does with the explicit
invokation of a super object upon a class and instance.

The enhancements to the super type will define a new __getattr__ classmethod
of the super type, which must look backwards to the previous frame and locate
the instance object. This can 

Re: [Python-Dev] [Python-3000] Pre-pre PEP for 'super' keyword

2007-04-29 Thread Tristan Seligmann
* Guido van Rossum [EMAIL PROTECTED] [2007-04-29 16:30:18 -0700]:

 On 4/29/07, Jim Jewett [EMAIL PROTECTED] wrote:
  So it is a keyword in the sense that None is a keyword; not in the
  stronger sense that if is a keyword?
 
 Um, how do you see those two differ? Is 'if' a keyword in the same
 sense as 'or', or in a different sense?

In my mind, 'if' and 'or' are syntax, whereas things like 'None' or
'True' are values; even if None becomes an actual keyword, rather than
a builtin.
-- 
mithrandi, i Ainil en-Balandor, a faer Ambar


signature.asc
Description: Digital signature
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-3000] Pre-pre PEP for 'super' keyword

2007-04-29 Thread Guido van Rossum
On 4/29/07, Tristan Seligmann [EMAIL PROTECTED] wrote:
 * Guido van Rossum [EMAIL PROTECTED] [2007-04-29 16:30:18 -0700]:

  On 4/29/07, Jim Jewett [EMAIL PROTECTED] wrote:
   So it is a keyword in the sense that None is a keyword; not in the
   stronger sense that if is a keyword?
 
  Um, how do you see those two differ? Is 'if' a keyword in the same
  sense as 'or', or in a different sense?

 In my mind, 'if' and 'or' are syntax, whereas things like 'None' or
 'True' are values; even if None becomes an actual keyword, rather than
 a builtin.

I'm sorry, but that is such an incredibly subjective difference that I
can't do anything with it. String literals and numeric literals are
syntax too, even though they are values. A keyword, or reserved word,
is simply something that looks like an identifier but is converted
into a different token (by the lexer or by something sitting between
the lexer and the parse) before the parser sees it.

Also note that null is a keyword in Java.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-3000] Pre-pre PEP for 'super' keyword

2007-04-29 Thread Delaney, Timothy (Tim)
Jim Jewett wrote:

 On 4/29/07, Tim Delaney [EMAIL PROTECTED] wrote:
 I've been intending to write up a PEP for fixing super, but I
 haven't had time to get to it.
 
 Calvin Spealman has the most recent draft. I hope he will incorporate
 this into his draft.

Sorry about this - wasn't receiving python-dev at home, so didn't
realise Calvin had released the PEP.

I think the current PEP draft is way too complicated - I don't think
there's any need for descriptors, etc. I think we can make things work
in the following way:

1. When a method is defined, the class is bound to it via an attribute
(which in my version is called func_class).

2. Every non-static method has an implicit cell variable called 'super'.
This would preferably not be able to be rebound. I also think it would
be beneficial if the first parameter to the method couldn't be rebound
(point 7 in my original email in this thread).

3. When a method is entered, the 'super' cell variable is populated by a
call equivalent to:

super = __builtin__.super(func_class, first_parameter)

This would result in 'super' being a constant object, within the scope
of the currently-executing method. 'keyword' was perhaps too strong - I
was thinking this would only need to be done if 'super' were actually
used, which would be easier to determine if 'super' actually were a
keyword. This could still be done by not emitting the above call unless
the 'super' cell variable were ever actually used.

I've done bytecode-hacky stuff to do the equivalent of the above (as
much as I've been able to), but a real implementation would just emit
the correct bytecode (or java bytecode, or whatever) in the compiled
code object.

The issue of super() vs. super.__call__() ambiguity - I'll need to look
at that when I get home.

I'm a strong -1 against super() automatically passing the parameters
that were passed to the currently-executing method.

Tim Delaney
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-3000] Pre-pre PEP for 'super' keyword

2007-04-29 Thread Tristan Seligmann
* Guido van Rossum [EMAIL PROTECTED] [2007-04-29 18:19:20 -0700]:

  In my mind, 'if' and 'or' are syntax, whereas things like 'None' or
  'True' are values; even if None becomes an actual keyword, rather than
  a builtin.
 
 I'm sorry, but that is such an incredibly subjective difference that I
 can't do anything with it. String literals and numeric literals are
 syntax too, even though they are values. A keyword, or reserved word,
 is simply something that looks like an identifier but is converted
 into a different token (by the lexer or by something sitting between
 the lexer and the parse) before the parser sees it.

Let me try a less subjective description. Things like None, 2.3, 'foo',
True are values or expressions; I'm not certain exactly what the term
for these is in Python's grammar, but I basically mean something that
can be on the RHS of an assignment.. However, something like 'for' or
'if' is part of some other grammatical construct, generally a statement
or operator of some kind, so I tend to think of those differently.
-- 
mithrandi, i Ainil en-Balandor, a faer Ambar


signature.asc
Description: Digital signature
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-3000] Pre-pre PEP for 'super' keyword

2007-04-29 Thread Guido van Rossum
On 4/29/07, Delaney, Timothy (Tim) [EMAIL PROTECTED] wrote:
 I think the current PEP draft is way too complicated - I don't think
 there's any need for descriptors, etc. I think we can make things work
 in the following way:

 1. When a method is defined, the class is bound to it via an attribute
 (which in my version is called func_class).

In Py3k all the func_XXX attrs are renamed __XXX__, so this would be
__class__; but that's a name reserved for something else, so it would
need to be something else.  E.g. __containing_class__.

Also, this would have to be done when the class is defined; when the
method is being defined the class doesn't exist yet.

 2. Every non-static method has an implicit cell variable called 'super'.

I think you're using 'cell' in a different sense than it is normally
used in Python's implementation. What you are looking for is called a
local variable (I deduce this from your initialization of the cell
with something computed from the first argument). A 'cell' (as I
introduced in my original back-of-the-envelop proposal; apparently you
totally missed this reference) is a special kind of object containing
a reference to another object and used to implement nonlocal variable
references (the Python 2 read-only nonlocals as well as the Python 3
writable nonlocals). The cell is initialized in the surrounding scope
and attached to the function object (as func_closure in 2.x, or
__closure__ in 3.0). When the function is called, a reference to the
cell is stored in the call frame.

If anything in your proposal resembles a cell (in the sense that I and
other Pythonistas mean it), it's the func_class attribute. In fact, in
this sense our proposals are equivalent modulo slight implementation
details; I proposed using a cell because there's an existing mechanism
to get these mapped into a local variable, and because cells are
cheaper than function attributes -- the first function attribute
requires creating a dict, which is one of the larger built-in objects.

 This would preferably not be able to be rebound. I also think it would
 be beneficial if the first parameter to the method couldn't be rebound
 (point 7 in my original email in this thread).

The latter part sounds irrelevant to me.

 3. When a method is entered, the 'super' cell variable is populated by a
 call equivalent to:

 super = __builtin__.super(func_class, first_parameter)

 This would result in 'super' being a constant object, within the scope
 of the currently-executing method. 'keyword' was perhaps too strong - I
 was thinking this would only need to be done if 'super' were actually
 used, which would be easier to determine if 'super' actually were a
 keyword. This could still be done by not emitting the above call unless
 the 'super' cell variable were ever actually used.

This sounds about right to me, with the strong preference that super
*should* be made a keyword, and the built-in of the same name renamed
to __super__, as it has a somewhat similar relationship to the super
keyword as the built-in __import__ has to the import keyword.

 I've done bytecode-hacky stuff to do the equivalent of the above (as
 much as I've been able to), but a real implementation would just emit
 the correct bytecode (or java bytecode, or whatever) in the compiled
 code object.

Shouldn't be too hard for someone who's hacked Python/compile.c before.

 The issue of super() vs. super.__call__() ambiguity - I'll need to look
 at that when I get home.

Sounds irrelevant -- if super is equivalent to
__builtin__.__super__(class, firstarg) then super never gets
called; the only thing ever done to it (in the normal course of
things) is to request an attribute of it.

 I'm a strong -1 against super() automatically passing the parameters
 that were passed to the currently-executing method.

Same here.

There seems to be the remaining controversy that there are three forms
of super calls currently in use:

super(ThisClass, self).method(...)  # in a regular method
super(ThisClass, cls).method(...)  # in a class method
super(ThisClass).method(...)  # ???

The first two are handled by your use the first argument approach.

The third exists so that you can create an unbound super instance
which is useful for the oft-misunderstood autosuper example in my
descrintro essay:
http://www.python.org/download/releases/2.2.3/descrintro/#metaclass_examples
.

But since the latter is the hack that we're trying to replace with a
proper implementation here, I suspect we can get away with only
supporting the first two forms (and the third form is still supported
using __builtin__.__super__).

IOW I think you're on to something. Keep up the good word.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-3000] Pre-pre PEP for 'super' keyword

2007-04-29 Thread Delaney, Timothy (Tim)
Guido van Rossum wrote:

 1. When a method is defined, the class is bound to it via an
attribute
 (which in my version is called func_class).

 In Py3k all the func_XXX attrs are renamed __XXX__, so this would be
 __class__; but that's a name reserved for something else, so it would
 need to be something else.  E.g. __containing_class__.

Yep - I've just used a placeholder name.

 Also, this would have to be done when the class is defined; when the
 method is being defined the class doesn't exist yet.

Good point. Change that to at the first opportunity ;)

 2. Every non-static method has an implicit cell variable called
 'super'. 
 
 I think you're using 'cell' in a different sense than it is normally
 used in Python's implementation. What you are looking for is called a
 local variable (I deduce this from your initialization of the cell
 with something computed from the first argument).

Actually, I think I'm using the terminology correctly - I'm talking
about an entry in co_cellvars. Given the following class:

class A(object):
def f(self):
super = super_factory()

def inner():
return 'A' + super.f()

print inner()

the use of 'super' in both A.f and A.f.inner will produce an entry in
A.f.func_code.co_cellvars and A.f.inner.func_code.co_freevars. What I'm
proposing is that the `super = super_factory()` line be implicit in this
case, resulting in the following code behaving identically:

class A(object):
def f(self):
def inner():
return 'A' + super.f()

print inner()

 The issue of super() vs. super.__call__() ambiguity - I'll need to
 look at that when I get home.
 
 Sounds irrelevant -- if super is equivalent to
 __builtin__.__super__(class, firstarg) then super never gets
 called; the only thing ever done to it (in the normal course of
 things) is to request an attribute of it.

Sorry - this is related to my proposal that the following two bits of
code behave the same:

class A(object):
def f(self, *p, **kw):
super.f(*p, **kw)

class A(object):
def f(self, *p, **kw):
super(*p, **kw)

But as has been pointed out, this creates an ambiguity with:

class A(object):
def f(self, *p, **kw):
super.__call__(*p, **kw)

so I want to see if I can resolve it.

 super(ThisClass).method(...)  # ???
 
 The third exists so that you can create an unbound super instance
 which is useful for the oft-misunderstood autosuper example in my
 descrintro essay:

http://www.python.org/download/releases/2.2.3/descrintro/#metaclass_exam
ples
 .
 
 But since the latter is the hack that we're trying to replace with a
 proper implementation here, I suspect we can get away with only
 supporting the first two forms (and the third form is still supported
 using __builtin__.__super__).

Yep - that's my thought as well. I think it would be very rare to need
super(ThisClass), although it makes some sense that that would be what
super means in a static method ...

Tim Delaney
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com