Why we will use obj$func() often

Mike C. Fletcher mcfletch at rogers.com
Fri Apr 23 01:22:44 EDT 2004


Mark Hahn wrote:

>Mike C. Fletcher wrote:
>
>  
>
>>This isn't really a very clear description of what's going on in
>>Python.  It won't matter to the Prothon users, but don't want any
>>Python users to get confused...
>>    
>>
>
>My inability to understand this stuff is what drove me to do Prothon <grin>.
>All the hidden wrapped this and wrapped that confused me to no end.
>  
>
Fascinating.  Most users never even notice this stuff, let alone getting 
so worked up about it that they start a whole separate language ;) .  
After all, they don't generally even know that metaclasses *exist* and 
just know that it all works exactly as they would expect.  You for 
instance, were describing how the interpreter just knows that a class 
can't be the target of an unbound class method.  Sure, *maybe* it's all 
a hideously complex mess that has people running screaming from Python 
in horror, but from where I sit it is an extremely elegant system that 
most people use without any impedance mismatch at all.

>>    By the way, the modern Python idiom is:
>>
>>        super( klass2, self ).func( )
>>
>>    
>>
>
>You're kidding.  That seems like a big leap backwards in friendliness.  Kind
>of a syntax castor oil.
>  
>
Explicit is better than implicit.  You are attempting to call the 
superclass' method; using:

    klass.func( self )

is actually a far less maintainable and composable idiom.  Here you are 
saying "call this *particular* superclass' method", introducing a 
dependency on the class' current superclass inside the method call.  The 
super() version does introduce a dependency on the *current* class 
inside the call, but that's generally far less likely to mess up as code 
gets revised.

super(), in other words, is a practical solution to avoiding the 
explicit dependencies that crop up when you directly reference a 
super-class.  It solves problems *for large-systems developers* who need 
robust, cooperative, composable functionality (e.g. via mix-in 
classes).  klass.func() might seem prettier and shorter in small 
systems, but it's something that Python's user community has outgrown 
over the years (if you can troll so can I ;) ).

>That's explains why Joe Mason did his proposal for Prothon delegation using
>that same idiom for Prothon.  I thought he was somewhat crazy wanting us to
>type all that each time.
>  
>
It's not the most elegant spelling of the idiom, that's true, but it was 
added without introducing any new magic.  When creating a new language 
you can decide to add new magic to the system solely as a question of 
"what is right".  When evolving a highly successful system, introducing 
new magic is a serious concern:

    super.func()

with super as a key-word would be fine in Prothon, as there's no code 
that depends on using the name super.

    super().func()

would work just as well, with the interpreter figuring out which class 
super() is being called from within but what happens when it's defined 
outside a class and injected later? After all, it's the class where it's 
*defined* that matters, not the one where it's being used.  So Guido 
went for the minimum of magic.  There's no special restriction on a 
function that uses super that the function must be defined in a class, 
there's no rules to figure out whether it affects inner or outer 
classes, there's, in short, no magic required to learn the idiom, it's a 
simple class instantiation like just about everything else.

    Special cases aren't special enough to break the rules.
    Although practicality beats purity.

super is used primarily by large-systems developers (meta-programmers), 
so having the functionality require the introduction of special magic 
and rules for regular users (every time they see an instance of "magic" 
they need to learn what it does) seems unnecessarily "special".  
Implementing super as a simple class means that, should someone be 
interested, they can simply look up the implementation and go "ah, I see 
what it does", but until then they can understand it as a simple call 
that returns a wrapper which gives the superclass of the passed class in 
the passed instance' mro... i.e. it's a black box that follows all the 
regular rules of functions/callables in Python.

Language design is about balancing the minimal set of ideas needed to 
give full generality and power with the need for expressivity and 
practicality.  So far Guido's decisions have been, IMO, a fairly good 
balance.  There are warts, but every language will have warts.  Python 
is a *small* language where, particularly in the later incarnations the 
special cases are going away and the same basic mechanisms are getting 
used in more and more places (e.g. with descriptors).  The reduction of 
special cases is an important design tool.

>What problem caused Python to want to switch to such a general operation?
>What is the usage case that is so important that it is making eveyone wear
>out their keyboards typing that monstrosity?
>  
>
Remember, this is the Python list, we tend to find hugely rhetorical 
arguments somewhat off-putting ;) .  On the other hand, we've 
extinguished more potential flamewars than I can count over the years, 
so it's not like the universe is going to collapse because of a few 
overblown statements :) .  If it did I would have doomed us all ages ago 
:) .

>Oh well, I guess it gives me one more argument to pitch for Prothon...
>  
>
Sure, the magic you sprinkle through your system is part of its flavour 
and character, that character is how languages sell themselves.  Though 
honestly, if someone seriously came up to me and said:

    "Switch to Frobnaz, it has explicit syntax for referencing a
    superclass rather than that archaic explicit invocation stuff in Python"

I'd probably dismiss them out of hand as being so totally out of touch 
with reality as to be not worth the effort of listening (well, not 
really, I *try* not to dismiss people out of hand no matter how crazy 
they are).  Addressing a few of Python's warts is *not* going to make 
the world beat a path to your door.  If you are going to get people to 
make a clean leap to your language (i.e. it's not source-code compatible 
with their current language, and doesn't have some compelling 
feature/niche) you need to design something that's about two times 
better, and you don't design something twice as good by copying and 
tweaking.  You do it by making intelligent design decisions that create 
a coherent language that fits well with people's expectations, that fits 
in their mind without a lot of magic and arbitrary rules to remember 
(PERL, of course being the exception that proves the rule, where the 
attempt is to simply guess everything the user might want to do and 
create an explicit syntax for that ;) ).

Your language *will* have it's own warts, that's a simple reality, 
pointing out that you don't have the same warts *in the same places* as 
another language is not a compelling argument for switching.  For 
instance, I would almost certainly consider the fishHeight$Somewhere() 
syntax to be a wart ;) , so being told that I can save 20 characters or 
so in typing super (which I've only done maybe one or two hundred times 
since it was introduced) by introducing something that my end-developers 
are going to have to be trained on doesn't really make me wet my pants 
in anticipation and joy :) .  After all, I've probably typed almost that 
much in this email alone.

Oops, dang keyboard wore out again ;) ,
Mike

_______________________________________
  Mike C. Fletcher
  Designer, VR Plumber, Coder
  http://members.rogers.com/mcfletch/






More information about the Python-list mailing list