Re: What is the semantics meaning of 'object'?

2013-06-29 Thread Mark Janssen
> On 26/06/2013 9:19 AM, Mark Janssen wrote:
>>
>> Did you ever hear of the Glass Bead Game?
>
> Which was Hesse's condemnation of the
> pure-academic-understanding-unbound-by-pragmatic-use approach as mental
> masturbation,

It was not.  He was conflicted.  On the one hand he knew the
enterprise was noble, but on the other he saw it could lead to crystal
palaces that were good to nobody.
-- 
MarkJ
Tacoma, Washington
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-27 Thread alex23

On 26/06/2013 9:19 AM, Mark Janssen wrote:

Did you ever hear of the Glass Bead Game?


Which was Hesse's condemnation of the 
pure-academic-understanding-unbound-by-pragmatic-use approach as mental 
masturbation, _not_ a recommendation for how human knowledge should 
work. If you think otherwise, you might want to read the last few 
chapters again.


--
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-26 Thread Ethan Furman

On 06/26/2013 04:54 PM, Steven D'Aprano wrote:

On Wed, 26 Jun 2013 13:14:44 -0700, Ethan Furman wrote:


On 06/23/2013 11:50 AM, Steven D'Aprano wrote:



What else would you call a function that does lookups on the current
object's superclasses?


Well, I would call it super().  Trouble is, that is not all that super()
does.  Going back to Ian's example:


On 06/23/2013 10:08 AM, Ian Kelly wrote:


class Base1(object):
 def __init__(self, foo, **kwargs):
super(Base1, self).__init__(**kwargs)

class Base2(object):
 def __init__(self, bar, **kwargs):
super(Base2, self).__init__(**kwargs)

class Derived(Base1, Base2):
 def __init__(self, **kwargs):
super(Derived, self).__init__(**kwargs)


Notice how Base1 calls super(), but depending on circumstances, it could
by Base2 that super() calls.  Surely you are not suggesting that Base2
is therefore an ancestor of Base1?


No. But "the current object" is not Base1, but an instance of Derived,
and Base2 *is* an ancestor of Derived. Perhaps if I had said "self"
instead of current object, you wouldn't have made this error. If so, I
apologise for confusing you.


No apology necessary.  I understand both inheritance and super fairly well, and 
you did not confuse me.



When your inheritance chain begins from an instance of Base1, Base2
methods will never be called. It is only when the chain begins from
Derived that Base2 may be called, which is exactly as it should be.


Absolutely.  That doesn't change the fact that when writing Base1 you are still using the word 'super', and hopefully 
remembering that even though it's named 'super' it may in fact call an object that is sideways from where you're at now 
and have absolutely no relation to Base1's ancestors.




It's too late to change the name now, but pretending there is no good
and valid reason for confusion doesn't help.


The confusion is not with the name, or what super does, but with
inheritance itself.


Good names are important because a good name can help alleviate confusion.  A bad name can exacerbate it.  Given the 
terminology of superclasses and subclasses, naming a function 'super' that can in fact call another class that is in no 
way the superclass of the class in which it is written, can easily cause confusion.


--
~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-26 Thread Ian Kelly
On Wed, Jun 26, 2013 at 5:54 PM, Steven D'Aprano
 wrote:
> No. But "the current object" is not Base1, but an instance of Derived,
> and Base2 *is* an ancestor of Derived. Perhaps if I had said "self"
> instead of current object, you wouldn't have made this error. If so, I
> apologise for confusing you.

If I am reading a class definition and see the code
super().__init__(), and I am not familiar with super() and do not
bother to go look it up in the docs because it looks "obvious" (or
perhaps I have read a tutorial that simply mentions that super() is
used to call methods from a superclass and elides over the details) --
my assumption is not going to be that super() is looking into
superclasses relative to the class of self, but more simply that
super() is looking into superclasses relative to the class that I'm
currently reading.

Why?  Because that's the way that "super" works in every other
language I know of that has it.

Java: super looks depth-first from the contextual class (no multiple
inheritance allowed)
Ruby: super looks depth-first from the contextual class (no multiple
inheritance allowed)
Objective-C: super looks depth-first from the contextual class (no
multiple inheritance allowed)
Perl 5: by default, super looks depth-first from the contextual class
(multiple inheritance IS allowed; the C3 linearization (MRO) CAN be
used, but it must first be explicitly enabled with a pragma directive)

Now if you're coming from Java, Ruby, or Objective-C and reading a
Python super() statement, then hopefully you will stop and think,
"Hey, wait a minute.  [Other language] doesn't have multiple
inheritance and Python does, so how does super() work here?"  More
likely though you're not even thinking about multiple inheritance when
you read that statement, and you just assume that it works exactly
like the super keyword that you're used to, and you move on.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-26 Thread Steven D'Aprano
On Wed, 26 Jun 2013 13:14:44 -0700, Ethan Furman wrote:

> On 06/23/2013 11:50 AM, Steven D'Aprano wrote:

>> What else would you call a function that does lookups on the current
>> object's superclasses?
> 
> Well, I would call it super().  Trouble is, that is not all that super()
> does.  Going back to Ian's example:
> 
>> On 06/23/2013 10:08 AM, Ian Kelly wrote:
>>>
>>> class Base1(object):
>>> def __init__(self, foo, **kwargs):
>>>super(Base1, self).__init__(**kwargs)
>>>
>>> class Base2(object):
>>> def __init__(self, bar, **kwargs):
>>>super(Base2, self).__init__(**kwargs)
>>>
>>> class Derived(Base1, Base2):
>>> def __init__(self, **kwargs):
>>>super(Derived, self).__init__(**kwargs)
> 
> Notice how Base1 calls super(), but depending on circumstances, it could
> by Base2 that super() calls.  Surely you are not suggesting that Base2
> is therefore an ancestor of Base1?

No. But "the current object" is not Base1, but an instance of Derived, 
and Base2 *is* an ancestor of Derived. Perhaps if I had said "self" 
instead of current object, you wouldn't have made this error. If so, I 
apologise for confusing you.

When your inheritance chain begins from an instance of Base1, Base2 
methods will never be called. It is only when the chain begins from 
Derived that Base2 may be called, which is exactly as it should be.


> It's too late to change the name now, but pretending there is no good
> and valid reason for confusion doesn't help.

The confusion is not with the name, or what super does, but with 
inheritance itself.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-26 Thread Ethan Furman

On 06/23/2013 11:50 AM, Steven D'Aprano wrote:

On Sun, 23 Jun 2013 12:04:35 -0600, Ian Kelly wrote:


On Sun, Jun 23, 2013 at 11:36 AM, Steven D'Aprano
 wrote:

On Sun, 23 Jun 2013 11:18:41 -0600, Ian Kelly wrote:


Incidentally, although super() is useful, it's not perfect, and this
is one of my grievances with it: that a user can, based upon the name,
draw an inaccurate assumption about what it does without reading or
fully understanding the documentation on it, which might then result
in misusing it.


Wait a second... are you saying that the Python developers created an
advanced language feature relating to multiple inheritance, one of the
most complex OOP concepts around, so difficult that most other
languages simply prohibit it completely, and it wasn't instantly and
correctly intuited by every single programmer based only on the name?
Oh my stars, somebody call Ranting Rick, he needs to write a PyWart
post to expose this scandal!!!


Mostly I'm saying that super() is badly named.



What else would you call a function that does lookups on the current
object's superclasses?


Well, I would call it super().  Trouble is, that is not all that super() does.  
Going back to Ian's example:


On 06/23/2013 10:08 AM, Ian Kelly wrote:


class Base1(object):
def __init__(self, foo, **kwargs):
   super(Base1, self).__init__(**kwargs)

class Base2(object):
def __init__(self, bar, **kwargs):
   super(Base2, self).__init__(**kwargs)

class Derived(Base1, Base2):
def __init__(self, **kwargs):
   super(Derived, self).__init__(**kwargs)


Notice how Base1 calls super(), but depending on circumstances, it could by Base2 that super() calls.  Surely you are 
not suggesting that Base2 is therefore an ancestor of Base1?


It's too late to change the name now, but pretending there is no good and valid 
reason for confusion doesn't help.

--
~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-26 Thread Ethan Furman

On 06/23/2013 12:05 PM, Ian Kelly wrote:

On Sun, Jun 23, 2013 at 12:46 PM, Steven D'Aprano
 wrote:

All is not lost, there are ways to make your classes cooperative. The
trick is to have your classes' __init__ methods ignore keyword arguments
they don't know what to do with. object used to do the same thing, but it
no longer does, so you need to add an extra class just before object to
swallow any args before they read object.


class Blocker(object):
 def __init__(self, **kwargs):
 # Block kwargs from reaching object
 super(Blocker, self).__init__()


I don't like the idea of doing this with a cooperative __init__
method.  If any keyword arguments were passed that weren't consumed,
that is probably a bug, and this just swallows the exception instead
of reporting it.


+1

Z

Of course, if you're doing cooperative inheritance with some other
method that doesn't exist on object, then this technique is necessary
to prevent the topmost class from trying to call that method on object
and erroring out.


But in that case the Blocker wouldn't call super since it is acting as the base 
class.

--
~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-26 Thread Chris Angelico
On Thu, Jun 27, 2013 at 1:16 AM, Rotwang  wrote:
> On 25/06/2013 23:57, Chris Angelico wrote:
>>
>> On Wed, Jun 26, 2013 at 8:38 AM, Mark Janssen 
>> wrote:
>>>
>>> Combining integers with sets I can make
>>> a Rational class and have infinite-precision arithmetic, for example.
>>
>>
>> Combining two integers lets you make a Rational. Python integers are
>>
>> already infinite-precision. Or are you actually talking of using
>> "machine words" and sets as your fundamental? Also, you need an
>>
>> ordered set - is the set {5,3} greater or less than the set {2} when
>> you interpret them as rationals? One must assume, I suppose, that any
>>
>> one-element set represents the integer 1, because any number divided
>> by itself is 1. Is the first operand 3/5 or 5/3?
>
>
> You could use Kuratowski ordered pairs:
>
> http://en.wikipedia.org/wiki/Ordered_pair#Kuratowski_definition
>
> Not that doing so would be sensible, of course. I don't know much about
> low-level data structures but it seems obvious that it's much easier to
> implement an ordered container type than an unordered set on a computer.

Yeah, I don't think Mark is much concerned about implementing things
on actual computers, somehow :)

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-26 Thread Rotwang

On 25/06/2013 23:57, Chris Angelico wrote:

On Wed, Jun 26, 2013 at 8:38 AM, Mark Janssen  wrote:

Combining integers with sets I can make
a Rational class and have infinite-precision arithmetic, for example.


Combining two integers lets you make a Rational. Python integers are
already infinite-precision. Or are you actually talking of using
"machine words" and sets as your fundamental? Also, you need an
ordered set - is the set {5,3} greater or less than the set {2} when
you interpret them as rationals? One must assume, I suppose, that any
one-element set represents the integer 1, because any number divided
by itself is 1. Is the first operand 3/5 or 5/3?


You could use Kuratowski ordered pairs:

http://en.wikipedia.org/wiki/Ordered_pair#Kuratowski_definition

Not that doing so would be sensible, of course. I don't know much about 
low-level data structures but it seems obvious that it's much easier to 
implement an ordered container type than an unordered set on a computer.

--
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-26 Thread Antoon Pardon
Op 26-06-13 00:27, Mark Janssen schreef:
>> The main problem is getting to the top/end of the call chain. Classic
>> example is with __init__, but the same problem can also happen with
>> other calls. Just a crazy theory, but would it be possible to
>> construct a black-holing object that, for any given method name,
>> returns a dummy function that ignores its args? (Other forms of
>> attribute lookup aren't going to be a problem, I think, so this can be
>> just methods/functions.) Then you just subclass from that all the
>> time, instead of from object itself, and you should be able to safely
>> call super's methods with whatever kwargs you haven't yourself
>> processed. Would that work?
>>
>> Caveat: I have not done much with MI in Python, so my idea may be
>> complete balderdash.
> Here's how it *should* be made:  the most superest, most badassed
> object should take care of its children.  New instances should
> automatically call up the super chain (and not leave it up to the
> subclasses), so that the parent classes can take care of the chil'en.
>  When something goes wrong the parent class has to look in and see
> what's wrong.
Could you explain why you think it should work this way? Maybe illustrate
how this is supposed to work.

Let take a very simple example. We have a class that works with a stream
(anything with a write method).

class Streamer:
def __init__(self, strm):
...

Now we find that we very often use this class with a file, so we would
like to make a subclass that takes a filename as parameter. This we would 
write somehow like the following

class Filer(Streamer):
def __init__(self, fn):
fl = open(fn, "a+")
super.__init__(fl)
...


Can you explain how this example should be written en work as you view things?

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-26 Thread Chris Angelico
On Wed, Jun 26, 2013 at 9:19 AM, Mark Janssen  wrote:
> Did you ever hear of the Glass Bead Game?

Yeah, it's Magic: The Gathering and its counters.

http://www.wizards.com/magic/magazine/Article.aspx?x=mtgcom/daily/mr195

:)

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-26 Thread Ian Kelly
On Tue, Jun 25, 2013 at 7:07 PM, Mark Janssen  wrote:
>> When you inherit a "set" to make a Rational, you're making the
>> statement (to the interpreter, if nothing else) that a Rational is-a
>> set.
>
> No you don't *inherit* a set to make a Rational, although you gain a
> set to make it.

Okay, then.  Since you started this discussion from the topic of
multiple inheritance I was under the impression that you were talking
about using inheritance to construct Rationals from integers and sets.
 Evidently that is not so, and you've been talking about composition
all along, in which case I have no idea how any of this relates to
your original suggestion of putting superclasses "in charge" of their
subclasses.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-26 Thread Steven D'Aprano
On Tue, 25 Jun 2013 16:19:08 -0700, Mark Janssen wrote:

> Well you've been spoiled by all the work that came before you.  The
> issue now is not to go "back to the machine" so much as to tear down and
> build up again from raw materials, objects of more and more complexity
> where very complex "meta-objects" upon meta-objects can be built until
> the "whole of human knowledge can be contained".

It must be a wonderful view from way, way up there, but how do you 
breathe?

http://www.joelonsoftware.com/items/2008/05/01.html


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-26 Thread Chris Angelico
On Wed, Jun 26, 2013 at 11:07 AM, Mark Janssen
 wrote:
 Combining two integers lets you make a Rational.
>>>
>>> Ah, but what is going to group them together?  You see you've already
>>> gotten seduced.  Python already uses a set to group them together --
>>> it's called a Dict and it's in every Class object.
>>
>> When you inherit a "set" to make a Rational, you're making the
>> statement (to the interpreter, if nothing else) that a Rational is-a
>> set.
>
> No you don't *inherit* a set to make a Rational, although you gain a
> set to make it.  It's a subtle thing, because at the center of it
> articulates the very difference between a piece of data and a
> container to hold that data.  Or is the container the data?
>
> C++ already solves this di-lemma.  It made "class" which is exactly
> like a "struct", but hides all it's data members.  That critical
> distinction makes all the difference.  I don't know how many people on
> the list really appreciate it.

I certainly don't. In fact, I hardly use "class" in C++ these days - I
just use "struct" and let the members be public. How is that
significant?

The thing you're completely missing, though, is that NONE of what
you're saying has anything to do with inheritance or super(). It's all
composition.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Mark Janssen
>>> Combining two integers lets you make a Rational.
>>
>> Ah, but what is going to group them together?  You see you've already
>> gotten seduced.  Python already uses a set to group them together --
>> it's called a Dict and it's in every Class object.
>
> When you inherit a "set" to make a Rational, you're making the
> statement (to the interpreter, if nothing else) that a Rational is-a
> set.

No you don't *inherit* a set to make a Rational, although you gain a
set to make it.  It's a subtle thing, because at the center of it
articulates the very difference between a piece of data and a
container to hold that data.  Or is the container the data?

C++ already solves this di-lemma.  It made "class" which is exactly
like a "struct", but hides all it's data members.  That critical
distinction makes all the difference.  I don't know how many people on
the list really appreciate it.

-- 
MarkJ
Tacoma, Washington
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Ian Kelly
On Tue, Jun 25, 2013 at 5:19 PM, Mark Janssen  wrote:
>>> Combining integers with sets I can make
>>> a Rational class and have infinite-precision arithmetic, for example.
>>
>> Combining two integers lets you make a Rational.
>
> Ah, but what is going to group them together?  You see you've already
> gotten seduced.  Python already uses a set to group them together --
> it's called a Dict and it's in every Class object.

When you inherit a "set" to make a Rational, you're making the
statement (to the interpreter, if nothing else) that a Rational is-a
set.

When a Python class uses an instance dict to store the numerator and
denominator of a Fraction, it's not *inheriting* Fraction from dict,
which is good because a Fraction is not a dict.  It's merely *using* a
dict.  It comes back once again to the distinction between inheritance
and composition.

>>  Also, you need an
>> ordered set - is the set {5,3} greater or less than the set {2} when
>> you interpret them as rationals?
>
> The ordering (and hence the interpretation) is done WITHIN the Class
> (i.e. the SET as I say above).

So "set" is just your name for a class?  I understood earlier that
with integers and sets you were trying to derive your type system from
number theory.  Now it sounds like you want sets to be containers of
attributes.  Which is it?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Mark Janssen
>> Here's how it *should* be made:  the most superest, most badassed
>> object should take care of its children.  New instances should
>> automatically call up the super chain (and not leave it up to the
>> subclasses), so that the parent classes can take care of the chil'en.
>>  When something goes wrong the parent class has to look in and see
>> what's wrong.
>
> So what you're saying is that the first class defined does everything,
> and subclasses _restrict_ what can be done? I disagree strongly:

That's right.  Just as the *machine* restricts what can be done.  It's
an upturning of the purity model and going back to practicality.

> 1) That breaks the Liskov Substitution Principle. A subclass of list
> ought to fulfill the contracts of a basic list.

We don't need LSP.  I write about this on the WIkiWikiWeb where there
were many arguments documented and many hairs frazzled.  LSP was
derived from AlanKay's abstract idea of "Everything is an object".
But no -- there is a *physics* for information, and it ends at the
machine types.

> 2) It implies that someone can invent an all-encompassing superclass
> before any subclassing is done.

No, we start with basic types and work upwards.  The
"all-encompassing" superclass it an all-encompassing data object:  in
mathematics, it's called a SET -- and mathematics has already done the
work to prove that it's the most generic and all-encompassing, a field
of SET THEORY.

> This kinda violates the laws of
> information. Programmers, being creative entities, will be adding to
> the pool of knowledge. Trying to shoehorn everything into one object
> won't work.

No, we don't need programmers adding to the "pool of knowledge" -- the
internet does that.  We need programmers making data objects that can
present data in new and more interesting ways -- starting from basic
principles.

-- 
MarkJ
Tacoma, Washington
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Mark Janssen
>> Combining integers with sets I can make
>> a Rational class and have infinite-precision arithmetic, for example.
>
> Combining two integers lets you make a Rational.

Ah, but what is going to group them together?  You see you've already
gotten seduced.  Python already uses a set to group them together --
it's called a Dict and it's in every Class object.

> Python integers are
> already infinite-precision. Or are you actually talking of using
> "machine words" and sets as your fundamental?

Probably.  It depends on where we need the flexibility of the
abstraction and where the code is written.

>  Also, you need an
> ordered set - is the set {5,3} greater or less than the set {2} when
> you interpret them as rationals?

The ordering (and hence the interpretation) is done WITHIN the Class
(i.e. the SET as I say above).

> One must assume, I suppose, that any
> one-element set represents the integer 1, because any number divided
> by itself is 1.

Ah, very good, observation.  But that must remain an improper question.  ;^)

>> That's a lot of power derived simply from using generic data
>> structures, not some panzy generic meta-Object that doesn't do
>> anything but tie people to an implicit type-theology.
>
> Sure. And if you want assembly language, you know where to find it.

Well you've been spoiled by all the work that came before you.  The
issue now is not to go "back to the machine" so much as to tear down
and build up again from raw materials, objects of more and more
complexity where very complex "meta-objects" upon meta-objects can be
built until the "whole of human knowledge can be contained".

Did you ever hear of the Glass Bead Game?
-- 
MarkJ
Tacoma, Washington
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Ian Kelly
On Tue, Jun 25, 2013 at 5:07 PM, Ian Kelly  wrote:
> On Tue, Jun 25, 2013 at 4:38 PM, Mark Janssen  
> wrote:
>> The issue of classes cooperating isn't as big as it seems, because
>> since you're working now from a useful, agreed-upon common base (the
>> non-negotiable, but also non-arbitrary) machine types, you're now all
>> (the python and ideally the *object* community) speaking the same
>> language.   Who's going to argue about integers (as the atomic type)
>> and sets (as the most basic grouping type) being THE common set of
>> bases for everything else?  I mean, it doesn't get anymore ideal and
>> pure than integers and sets.  Combining integers with sets I can make
>> a Rational class and have infinite-precision arithmetic, for example.
>
> I don't see how this solves anything.  At some point you have to be
> able to add methods and attributes to your objects.  For example, your
> Rational class is going to need some sort of "reduce" method to reduce
> a Rational instance to lowest terms.  That's not a method that belongs
> on an integer or set type.  If you can't add functionality, then all
> you will ever have are integers and sets, and if you can add
> functionality, then what difference does it make what your fundamental
> base class is?

Oh, and just in case you're not aware, Python already has a Fraction
class that supports unlimited-precision arithmetic.  It doesn't need
to inherit from tuple to accomplish this, and in fact that would be a
bad way to approach it, since a fraction is *not* a tuple.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Ian Kelly
On Tue, Jun 25, 2013 at 4:38 PM, Mark Janssen  wrote:
> Sorry my last message got sent prematurely.  Retrying...
>
>> So instead of super(), you would have sub()?  It's an interesting
>> concept, but I don't think it changes anything.  You still have to
>> design your classes cooperatively if you expect to use them with
>> multiple inheritance.
>
> Yes, and let new instances of the child classes automatically ensure
> the contracts of the parent classes -- managed within the Python
> interpreter, not the developer.

It sounds like you want to be using Eiffel, not Python.

> As for sub(), I suppose it could be called delegate().

You can call it that, but you'll just be muddying the waters since
there's already a perfectly good pattern by that name, which involves
having multiple distinct objects and has nothing to do with
inheritance.

> The issue of classes cooperating isn't as big as it seems, because
> since you're working now from a useful, agreed-upon common base (the
> non-negotiable, but also non-arbitrary) machine types, you're now all
> (the python and ideally the *object* community) speaking the same
> language.   Who's going to argue about integers (as the atomic type)
> and sets (as the most basic grouping type) being THE common set of
> bases for everything else?  I mean, it doesn't get anymore ideal and
> pure than integers and sets.  Combining integers with sets I can make
> a Rational class and have infinite-precision arithmetic, for example.

I don't see how this solves anything.  At some point you have to be
able to add methods and attributes to your objects.  For example, your
Rational class is going to need some sort of "reduce" method to reduce
a Rational instance to lowest terms.  That's not a method that belongs
on an integer or set type.  If you can't add functionality, then all
you will ever have are integers and sets, and if you can add
functionality, then what difference does it make what your fundamental
base class is?

>From a programming perspective, I think it is proper that "object" is
the most fundamental base class, because all it has is identity.
Integers and sets add other functionality on top of that.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Chris Angelico
On Wed, Jun 26, 2013 at 9:00 AM, Mark Janssen  wrote:
>> 1) That breaks the Liskov Substitution Principle. A subclass of list
>> ought to fulfill the contracts of a basic list.
>
> We don't need LSP.  I write about this on the WIkiWikiWeb where there
> were many arguments documented and many hairs frazzled.  LSP was
> derived from AlanKay's abstract idea of "Everything is an object".
> But no -- there is a *physics* for information, and it ends at the
> machine types.

Then you're talking about composition, not inheritance. We already
have that - just declare a new type that consists only of other,
simpler, types. That's the way class definitions work. (Okay, in
Python it's a little different because everything's dynamic, but still
there's a general concept that you're building the complex from the
simple - a Point from a number of integers, a Shape2D from a number of
points, etc.)

>> This kinda violates the laws of
>> information. Programmers, being creative entities, will be adding to
>> the pool of knowledge. Trying to shoehorn everything into one object
>> won't work.
>
> No, we don't need programmers adding to the "pool of knowledge" -- the
> internet does that.  We need programmers making data objects that can
> present data in new and more interesting ways -- starting from basic
> principles.

The internet creates knowledge all on its own? Wow. The Singularity
has been reached!

No. Programmers add to code. That's what we get paid for. All those
commits going onto source control aren't the creation of the internet.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Chris Angelico
On Wed, Jun 26, 2013 at 8:38 AM, Mark Janssen  wrote:
> Combining integers with sets I can make
> a Rational class and have infinite-precision arithmetic, for example.

Combining two integers lets you make a Rational. Python integers are
already infinite-precision. Or are you actually talking of using
"machine words" and sets as your fundamental? Also, you need an
ordered set - is the set {5,3} greater or less than the set {2} when
you interpret them as rationals? One must assume, I suppose, that any
one-element set represents the integer 1, because any number divided
by itself is 1. Is the first operand 3/5 or 5/3?

> That's a lot of power derived simply from using generic data
> structures, not some panzy generic meta-Object that doesn't do
> anything but tie people to an implicit type-theology.

Sure. And if you want assembly language, you know where to find it.
Personally, I don't want to have to code the fundamentals of data
structures in Python - that's C's job. The details of hashing
algorithms, fill factors, collision handling, and so on, are the
concern of the dict implementation, and unless there's a good reason
to dig into it (like when I'm explaining to my boss about a
hash-collision attack and why it means we have to upgrade to a newer
interpreter version), I don't care about the minutiae.

What you're doing is actually in the same theological / theoretical
level as what you're complaining of. It's equivalent to pointing out
that every single data structure you use, and every piece of
information in this world, can be represented with an aggregation of
the digits 1 and 0 - that's an awesomely powerful, clean, and
all-encompassing abstraction, but in day-to-day life, we really don't
need to think about it.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Chris Angelico
On Wed, Jun 26, 2013 at 8:27 AM, Mark Janssen  wrote:
> Here's how it *should* be made:  the most superest, most badassed
> object should take care of its children.  New instances should
> automatically call up the super chain (and not leave it up to the
> subclasses), so that the parent classes can take care of the chil'en.
>  When something goes wrong the parent class has to look in and see
> what's wrong.

So what you're saying is that the first class defined does everything,
and subclasses _restrict_ what can be done? I disagree strongly:

1) That breaks the Liskov Substitution Principle. A subclass of list
ought to fulfill the contracts of a basic list.

2) It implies that someone can invent an all-encompassing superclass
before any subclassing is done. This kinda violates the laws of
information. Programmers, being creative entities, will be adding to
the pool of knowledge. Trying to shoehorn everything into one object
won't work.

It may be that you're not saying that, but you mean that the
superclass decides which subclass's method to call. If that's what you
meant, then I really don't know how it would be any different from the
object itself making that decision, which is how things currently are.
Or are both these interpretations wrong?

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Chris Angelico
On Wed, Jun 26, 2013 at 8:25 AM, Ian Kelly  wrote:
> On Tue, Jun 25, 2013 at 4:17 PM, Chris Angelico  wrote:
>> The main problem is getting to the top/end of the call chain. Classic
>> example is with __init__, but the same problem can also happen with
>> other calls. Just a crazy theory, but would it be possible to
>> construct a black-holing object that, for any given method name,
>> returns a dummy function that ignores its args? (Other forms of
>> attribute lookup aren't going to be a problem, I think, so this can be
>> just methods/functions.) Then you just subclass from that all the
>> time, instead of from object itself, and you should be able to safely
>> call super's methods with whatever kwargs you haven't yourself
>> processed. Would that work?
>
> class BlackHole(object):
> def __getattr__(self, attr):
> return lambda *args, **kwargs: None
>
> There's no way to restrict it to just methods, because there's no
> fundamental difference in Python between methods and other attributes,
> and at the point that you're looking it up you have no way of knowing
> whether the result is about to be called or not.

Right, but what I mean is that you don't need any sort of
special-casing to pick an object type to return. Just return a
function, because that's going to be safe.

> And even if there were, this would be an excellent way to hide bugs.

Ehh, true. Don't know a way around that one. Meh.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Mark Janssen
Sorry my last message got sent prematurely.  Retrying...

> So instead of super(), you would have sub()?  It's an interesting
> concept, but I don't think it changes anything.  You still have to
> design your classes cooperatively if you expect to use them with
> multiple inheritance.

Yes, and let new instances of the child classes automatically ensure
the contracts of the parent classes -- managed within the Python
interpreter, not the developer.

As for sub(), I suppose it could be called delegate().

The issue of classes cooperating isn't as big as it seems, because
since you're working now from a useful, agreed-upon common base (the
non-negotiable, but also non-arbitrary) machine types, you're now all
(the python and ideally the *object* community) speaking the same
language.   Who's going to argue about integers (as the atomic type)
and sets (as the most basic grouping type) being THE common set of
bases for everything else?  I mean, it doesn't get anymore ideal and
pure than integers and sets.  Combining integers with sets I can make
a Rational class and have infinite-precision arithmetic, for example.

That's a lot of power derived simply from using generic data
structures, not some panzy generic meta-Object that doesn't do
anything but tie people to an implicit type-theology.

-- 
MarkJ
Tacoma, Washington
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Mark Janssen
> The main problem is getting to the top/end of the call chain. Classic
> example is with __init__, but the same problem can also happen with
> other calls. Just a crazy theory, but would it be possible to
> construct a black-holing object that, for any given method name,
> returns a dummy function that ignores its args? (Other forms of
> attribute lookup aren't going to be a problem, I think, so this can be
> just methods/functions.) Then you just subclass from that all the
> time, instead of from object itself, and you should be able to safely
> call super's methods with whatever kwargs you haven't yourself
> processed. Would that work?
>
> Caveat: I have not done much with MI in Python, so my idea may be
> complete balderdash.

Here's how it *should* be made:  the most superest, most badassed
object should take care of its children.  New instances should
automatically call up the super chain (and not leave it up to the
subclasses), so that the parent classes can take care of the chil'en.
 When something goes wrong the parent class has to look in and see
what's wrong.

In other words, this habit of specializing a Class to make up for the
weaknesses of its parent are THE WRONG WAY.   Instead, let the
specialization start at the machine types (where it doesn't get more
specialized), and work UPWARDS.

Let the standard library make the grouping (or collection types) to
point to the standard way of data structuring, and then everything
else becomes little mini-apps making a DataEcosystem.

--mark
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Mark Janssen
> So instead of super(), you would have sub()?  It's an interesting
> concept, but I don't think it changes anything.  You still have to
> design your classes cooperatively if you expect to use them with
> multiple inheritance.

Yes, and let new instances of the child classes automatically ensure
the contracts of the parent classes.  I suppose it could be called
delegation
-- 
MarkJ
Tacoma, Washington
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Ian Kelly
On Tue, Jun 25, 2013 at 4:17 PM, Chris Angelico  wrote:
> The main problem is getting to the top/end of the call chain. Classic
> example is with __init__, but the same problem can also happen with
> other calls. Just a crazy theory, but would it be possible to
> construct a black-holing object that, for any given method name,
> returns a dummy function that ignores its args? (Other forms of
> attribute lookup aren't going to be a problem, I think, so this can be
> just methods/functions.) Then you just subclass from that all the
> time, instead of from object itself, and you should be able to safely
> call super's methods with whatever kwargs you haven't yourself
> processed. Would that work?

class BlackHole(object):
def __getattr__(self, attr):
return lambda *args, **kwargs: None

There's no way to restrict it to just methods, because there's no
fundamental difference in Python between methods and other attributes,
and at the point that you're looking it up you have no way of knowing
whether the result is about to be called or not.

And even if there were, this would be an excellent way to hide bugs.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Ian Kelly
On Tue, Jun 25, 2013 at 3:58 PM, Mark Janssen  wrote:
> Ah, and here we see the weakness in the object architecture that has
> evolved in the past decade (not just in Python, note).  It hasn't
> really ironed out what end is what.   Here's a proposal:  the highest,
> most "parental", most general object should be in charge, not
> subclasses calling specific parent's init methods
> (Parent.__init__(myparams)), etc. -- ***THIS IS WHERE WE WENT
> WRONG***.
>
> After the "type/class unification", python tried to make the most
> generic, most useless class be the parent of *all of them*, but
> there's been no use whatsoever in that.  It was a good idea in the
> beginning, so pure as it was, but it has not panned out in practice.
> Sorry...

So instead of super(), you would have sub()?  It's an interesting
concept, but I don't think it changes anything.  You still have to
design your classes cooperatively if you expect to use them with
multiple inheritance.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Chris Angelico
On Wed, Jun 26, 2013 at 3:44 AM, Ian Kelly  wrote:
> On Sun, Jun 23, 2013 at 1:33 PM, Antoon Pardon
>  wrote:
>> Op 23-06-13 18:35, Steven D'Aprano schreef:
>>> Please don't. This is false economy. The time you save will be trivial,
>>> the overhead of inheritance is not going to be the bottleneck in your
>>> code, and by ignoring super, you only accomplish one thing:
>>>
>>> - if you use your class in multiple inheritance, it will be buggy.
>>
>>
>> Which is why I don't understand that the python standard library still
>> contains that kind of code. At least it did in 3.2 and I saw nothing
>> in the 3.3 release notes that would make me suspect this has changed.
>
> This bothers me as well.  If you look at Raymond Hettinger's "super()
> considered super" article, he includes the (correct) advice that
> super() needs to be used at every level of the call chain.  At the end
> of the article, he offers this example to show how "easy" multiple
> inheritance can be:
>
> from collections import Counter, OrderedDict
>
> class OrderedCounter(Counter, OrderedDict):
>  'Counter that remembers the order elements are first seen'
>  def __repr__(self):
>  return '%s(%r)' % (self.__class__.__name__,
> OrderedDict(self))
>  def __reduce__(self):
>  return self.__class__, (OrderedDict(self),)
>
> oc = OrderedCounter('abracadabra')
>
> Which is pretty cool in its simplicity, but here's the rub (which I
> have previously noted on this list): OrderedDict doesn't use super.
> Counter does, but not cooperatively; it just calls super().__init__()
> with no arguments.  So the fact that this example works at all is
> basically luck.

The main problem is getting to the top/end of the call chain. Classic
example is with __init__, but the same problem can also happen with
other calls. Just a crazy theory, but would it be possible to
construct a black-holing object that, for any given method name,
returns a dummy function that ignores its args? (Other forms of
attribute lookup aren't going to be a problem, I think, so this can be
just methods/functions.) Then you just subclass from that all the
time, instead of from object itself, and you should be able to safely
call super's methods with whatever kwargs you haven't yourself
processed. Would that work?

Caveat: I have not done much with MI in Python, so my idea may be
complete balderdash.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Mark Janssen
> This bothers me as well.  If you look at Raymond Hettinger's "super()
> considered super" article, he includes the (correct) advice that
> super() needs to be used at every level of the call chain.  At the end
> of the article, he offers this example to show how "easy" multiple
> inheritance can be:
> [...]
> oc = OrderedCounter('abracadabra')
>
> Which is pretty cool in its simplicity, but here's the rub (which I
> have previously noted on this list): OrderedDict doesn't use super.
> Counter does, but not cooperatively; it just calls super().__init__()
> with no arguments.  So the fact that this example works at all is
> basically luck.

Ah, and here we see the weakness in the object architecture that has
evolved in the past decade (not just in Python, note).  It hasn't
really ironed out what end is what.   Here's a proposal:  the highest,
most "parental", most general object should be in charge, not
subclasses calling specific parent's init methods
(Parent.__init__(myparams)), etc. -- ***THIS IS WHERE WE WENT
WRONG***.

After the "type/class unification", python tried to make the most
generic, most useless class be the parent of *all of them*, but
there's been no use whatsoever in that.  It was a good idea in the
beginning, so pure as it was, but it has not panned out in practice.
Sorry...

I'm trying to start a recovery plan at the wikiwikiweb
(http://c2.com/cgi/wiki?WikiWikiWeb) and I don't want to hear any more
smarmy comments about it.  The confusion is deeper than Python.
-- 
MarkJ
Tacoma, Washington
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Ian Kelly
On Sun, Jun 23, 2013 at 1:33 PM, Antoon Pardon
 wrote:
> Op 23-06-13 18:35, Steven D'Aprano schreef:
>> Please don't. This is false economy. The time you save will be trivial,
>> the overhead of inheritance is not going to be the bottleneck in your
>> code, and by ignoring super, you only accomplish one thing:
>>
>> - if you use your class in multiple inheritance, it will be buggy.
>
>
> Which is why I don't understand that the python standard library still
> contains that kind of code. At least it did in 3.2 and I saw nothing
> in the 3.3 release notes that would make me suspect this has changed.

This bothers me as well.  If you look at Raymond Hettinger's "super()
considered super" article, he includes the (correct) advice that
super() needs to be used at every level of the call chain.  At the end
of the article, he offers this example to show how "easy" multiple
inheritance can be:

from collections import Counter, OrderedDict

class OrderedCounter(Counter, OrderedDict):
 'Counter that remembers the order elements are first seen'
 def __repr__(self):
 return '%s(%r)' % (self.__class__.__name__,
OrderedDict(self))
 def __reduce__(self):
 return self.__class__, (OrderedDict(self),)

oc = OrderedCounter('abracadabra')

Which is pretty cool in its simplicity, but here's the rub (which I
have previously noted on this list): OrderedDict doesn't use super.
Counter does, but not cooperatively; it just calls super().__init__()
with no arguments.  So the fact that this example works at all is
basically luck.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-25 Thread Antoon Pardon

Op 23-06-13 18:35, Steven D'Aprano schreef:

On Sun, 23 Jun 2013 10:15:38 -0600, Ian Kelly wrote:


If you're worried about efficiency, you can also explicitly name the
superclass in order to call the method directly, like:

 A.__init__(self, arg)


Please don't. This is false economy. The time you save will be trivial,
the overhead of inheritance is not going to be the bottleneck in your
code, and by ignoring super, you only accomplish one thing:

- if you use your class in multiple inheritance, it will be buggy.


Which is why I don't understand that the python standard library still
contains that kind of code. At least it did in 3.2 and I saw nothing
in the 3.3 release notes that would make me suspect this has changed.

--
Antoon Pardon

--
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-24 Thread Steven D'Aprano
On Mon, 24 Jun 2013 08:58:23 -0700, Mark Janssen wrote:

>>> Mostly I'm saying that super() is badly named.
>>
>> What else would you call a function that does lookups on the current
>> object's superclasses?
> 
> ^.  You make a symbol for it.  ^__init__(foo, bar)

If you want Perl, you can find it here:

http://www.perl.org/


Or even more scary:

https://en.wikipedia.org/wiki/APL_syntax_and_symbols



^ won't do the job, because it's already used for bitwise-xor. I suppose 
that *technically* it could be used as either a binary or unary operator, 
like +, -, *, **, but I don't think it could be used as both an operator 
and an identifier.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-24 Thread Ian Kelly
On Mon, Jun 24, 2013 at 9:58 AM, Mark Janssen  wrote:
>>> Mostly I'm saying that super() is badly named.
>>
>> What else would you call a function that does lookups on the current
>> object's superclasses?
>
> ^.  You make a symbol for it.  ^__init__(foo, bar)

On the one hand, eww.

On the other hand, with the changes to super in Python 3 to make it
more magical, it might as well be syntax.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-24 Thread Ian Kelly
On Mon, Jun 24, 2013 at 9:00 AM, Rotwang  wrote:
> On 24/06/2013 07:31, Steven D'Aprano wrote:
>
>> I daresay that there are good reasons why new-style classes don't do the
>> same thing, but the point is that had the Python devs had been
>> sufficiently interested in keeping the old behaviour, and willing to pay
>> whatever costs that would require, they could have done so.
>
>
> Sure, though the above behaviour was probably easier to achieve with
> old-style classes than it would have been with new-style classes because all
> instances of old-style classes have the same type. But I don't doubt that
> you're correct that they could have done it if they wanted.

It seems to me that the important difference with new-style classes is
that they suddenly have metaclasses and are themselves just ordinary
objects, and so it is important that they consistently resolve calls
in the same way that all other objects do.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-24 Thread Mark Janssen
>> Mostly I'm saying that super() is badly named.
>
> What else would you call a function that does lookups on the current
> object's superclasses?

^.  You make a symbol for it.  ^__init__(foo, bar)

-- 
MarkJ
Tacoma, Washington
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-24 Thread Rotwang

On 24/06/2013 07:31, Steven D'Aprano wrote:

On Mon, 24 Jun 2013 02:53:06 +0100, Rotwang wrote:


On 23/06/2013 18:29, Steven D'Aprano wrote:

On Sat, 22 Jun 2013 23:40:53 -0600, Ian Kelly wrote:

[...]

Can you elaborate or provide a link?  I'm curious to know what other
reason there could be for magic methods to behave differently from
normal methods in this regard.


It's an efficiency optimization. I don't quite get the details, but
when you run something like "a + b", Python doesn't search for __add__
using the normal method lookup procedure. That allows it to skip
checking the instance __dict__, as well as __getattribute__ and
__getattr__.


It's not just an efficiency optimisation, it's actually necessary in
cases where a dunder method gets called on a type. Consider what happens
when one calls repr(int), for example - if this tried to call
int.__repr__() by the normal lookup method, it would call the unbound
__repr__ method of int with no self argument:



I don't know about *necessary*, after all, classic classes manage just
fine in Python 2.x:

py> class OldStyle:
... def __repr__(self):
... return "Spam"
...
py> repr(OldStyle())
'Spam'
py> repr(OldStyle)
''


Point taken. It's also possible to override the __repr__ method of an 
old-style instance and have the change recognised by repr, so repr(x) 
isn't simply calling type(x).__repr__(x) in general.




I daresay that there are good reasons why new-style classes don't do the
same thing, but the point is that had the Python devs had been
sufficiently interested in keeping the old behaviour, and willing to pay
whatever costs that would require, they could have done so.


Sure, though the above behaviour was probably easier to achieve with 
old-style classes than it would have been with new-style classes because 
all instances of old-style classes have the same type. But I don't doubt 
that you're correct that they could have done it if they wanted.

--
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-24 Thread Roy Smith
In article <51c7fe14$0$29973$c3e8da3$54964...@news.astraweb.com>,
 Steven D'Aprano  wrote:

> Mixins are such a limited version of MI that it's often not even counted 
> as MI, and even when it is, being familiar with mixins is hardly 
> sufficient to count yourself as familiar with MI.

OK, fair enough.

> >> - then you might assume that super means "return the superclass of this
> >> class" (or possibly instance).
> > 
> > That's exactly what I assumed.  And, since you correctly surmised that
> > that's what I would assume, I would suggest that it was pretty obvious
> > to you too.  Of course, given that assumption, it was not at all clear
> > what it would do in a class with multiple ancestors.
> 
> That's exactly why it *isn't* obvious. Too many assumptions need to be 
> made, and questions left unanswered, for the conclusion to be obvious.

I think we're using different definitions of "obvious".  I'm using it to 
mean, "What you would conclude from a first look at a problem".  The 
fact that it is proven to be wrong upon closer examination doesn't 
change the fact that it's obvious.

> That's like saying that it's "obvious" that the sun goes around the 
> earth, because that's what it looks like. What would it look like if 
> it was the other way around?

Well, it is obvious.  It's just wrong, based on our current 
understanding.  Humans have been theorizing about how the heavenly 
bodies work for thousands of years.  It's only in the past 400 that 
they're figured out how the solar system works.

So, to bring this back to Python, the goal of designing 
easy-to-understand things is that the obvious explanation also happens 
to be the correct one.  Giving super() the name that it has failed at 
this.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-24 Thread Steven D'Aprano
On Sun, 23 Jun 2013 21:38:33 -0400, Roy Smith wrote:

> In article <51c7a087$0$2$c3e8da3$54964...@news.astraweb.com>,
>  Steven D'Aprano  wrote:
> 
>> On Sun, 23 Jun 2013 15:24:14 -0400, Roy Smith wrote:
>> 
>> > In article <51c74373$0$2$c3e8da3$54964...@news.astraweb.com>,
>> >  Steven D'Aprano  wrote:
>>  
>> >> What else would you call a function that does lookups on the current
>> >> object's superclasses?
>> > 
>> > Well, mro_lookup() would have been a better choice.  Super() has an
>> > obvious meaning, which just happens to be wrong.
>> 
>> This "obvious but wrong" meaning isn't the least bit obvious to me.
>> Care to give me a hint? The only thing I can think of is:
>> 
>> - if you are familiar with single inheritance;
> 
> True.
> 
>> - but unfamiliar with multiple inheritance;
> 
> False.  Although, I'm pretty sure that all the times I've used MI (in
> both Python and C++), it was of the mix-in variety.

Mixins are such a limited version of MI that it's often not even counted 
as MI, and even when it is, being familiar with mixins is hardly 
sufficient to count yourself as familiar with MI. That's kind of like me 
saying I'm familiar with life in Italy on the strength of a three-week 
holiday back in 1982 :-)

If you still think of "the" superclass, then you haven't done enough MI 
to learn better :-)

 
>> - then you might assume that super means "return the superclass of this
>> class" (or possibly instance).
> 
> That's exactly what I assumed.  And, since you correctly surmised that
> that's what I would assume, I would suggest that it was pretty obvious
> to you too.  Of course, given that assumption, it was not at all clear
> what it would do in a class with multiple ancestors.

That's exactly why it *isn't* obvious. Too many assumptions need to be 
made, and questions left unanswered, for the conclusion to be obvious. 
Just because some people might jump to an unjustified conclusion, doesn't 
mean that the conclusion is obvious. That's like saying that it's 
"obvious" that the sun goes around the earth, because that's what it 
looks like. What would it look like if it was the other way around?



>> I don't think that counts as "obvious". Or at least not "intuitive" :-)
> 
> Obvious is in the mind of the observer.

Well that's obvious :-)




-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Steven D'Aprano
On Mon, 24 Jun 2013 02:53:06 +0100, Rotwang wrote:

> On 23/06/2013 18:29, Steven D'Aprano wrote:
>> On Sat, 22 Jun 2013 23:40:53 -0600, Ian Kelly wrote:
>>> [...]
>>>
>>> Can you elaborate or provide a link?  I'm curious to know what other
>>> reason there could be for magic methods to behave differently from
>>> normal methods in this regard.
>>
>> It's an efficiency optimization. I don't quite get the details, but
>> when you run something like "a + b", Python doesn't search for __add__
>> using the normal method lookup procedure. That allows it to skip
>> checking the instance __dict__, as well as __getattribute__ and
>> __getattr__.
> 
> It's not just an efficiency optimisation, it's actually necessary in
> cases where a dunder method gets called on a type. Consider what happens
> when one calls repr(int), for example - if this tried to call
> int.__repr__() by the normal lookup method, it would call the unbound
> __repr__ method of int with no self argument:


I don't know about *necessary*, after all, classic classes manage just 
fine in Python 2.x:

py> class OldStyle:
... def __repr__(self):
... return "Spam"
... 
py> repr(OldStyle())
'Spam'
py> repr(OldStyle)
''


I daresay that there are good reasons why new-style classes don't do the 
same thing, but the point is that had the Python devs had been 
sufficiently interested in keeping the old behaviour, and willing to pay 
whatever costs that would require, they could have done so.

But your point is well taken. It's not just purely a speed optimization.


> This is explained here:
> 
> http://docs.python.org/3.3/reference/datamodel.html#special-lookup


Nice link, thank you.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Rotwang

On 23/06/2013 18:29, Steven D'Aprano wrote:

On Sat, 22 Jun 2013 23:40:53 -0600, Ian Kelly wrote:

[...]

Can you elaborate or provide a link?  I'm curious to know what other
reason there could be for magic methods to behave differently from
normal methods in this regard.


It's an efficiency optimization. I don't quite get the details, but when
you run something like "a + b", Python doesn't search for __add__ using
the normal method lookup procedure. That allows it to skip checking the
instance __dict__, as well as __getattribute__ and __getattr__.


It's not just an efficiency optimisation, it's actually necessary in 
cases where a dunder method gets called on a type. Consider what happens 
when one calls repr(int), for example - if this tried to call 
int.__repr__() by the normal lookup method, it would call the unbound 
__repr__ method of int with no self argument:


>>> int.__repr__()
Traceback (most recent call last):
  File "", line 1, in 
int.__repr__()
TypeError: descriptor '__repr__' of 'int' object needs an argument

By bypassing the instance-first lookup and going straight to the 
object's type's dictionary, repr(int) instead calls type.__repr__(int), 
which works:


>>> type.__repr__(int)
""

This is explained here:

http://docs.python.org/3.3/reference/datamodel.html#special-lookup
--
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Roy Smith
In article <51c7a087$0$2$c3e8da3$54964...@news.astraweb.com>,
 Steven D'Aprano  wrote:

> On Sun, 23 Jun 2013 15:24:14 -0400, Roy Smith wrote:
> 
> > In article <51c74373$0$2$c3e8da3$54964...@news.astraweb.com>,
> >  Steven D'Aprano  wrote:
>  
> >> What else would you call a function that does lookups on the current
> >> object's superclasses?
> > 
> > Well, mro_lookup() would have been a better choice.  Super() has an
> > obvious meaning, which just happens to be wrong.
> 
> This "obvious but wrong" meaning isn't the least bit obvious to me. Care 
> to give me a hint? The only thing I can think of is:
> 
> - if you are familiar with single inheritance;

True.

> - but unfamiliar with multiple inheritance;

False.  Although, I'm pretty sure that all the times I've used MI (in 
both Python and C++), it was of the mix-in variety.

> - then you might assume that super means "return the superclass of this 
> class" (or possibly instance). 

That's exactly what I assumed.  And, since you correctly surmised that 
that's what I would assume, I would suggest that it was pretty obvious 
to you too.  Of course, given that assumption, it was not at all clear 
what it would do in a class with multiple ancestors.

> I don't think that counts as "obvious". Or at least not "intuitive" :-)

Obvious is in the mind of the observer.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Steven D'Aprano
On Sun, 23 Jun 2013 15:24:14 -0400, Roy Smith wrote:

> In article <51c74373$0$2$c3e8da3$54964...@news.astraweb.com>,
>  Steven D'Aprano  wrote:
 
>> What else would you call a function that does lookups on the current
>> object's superclasses?
> 
> Well, mro_lookup() would have been a better choice.  Super() has an
> obvious meaning, which just happens to be wrong.

This "obvious but wrong" meaning isn't the least bit obvious to me. Care 
to give me a hint? The only thing I can think of is:

- if you are familiar with single inheritance;

- but unfamiliar with multiple inheritance;

- and you make the incorrect assumption that there can be only one 
superclass of a given class;

- then you might assume that super means "return the superclass of this 
class" (or possibly instance). 

I don't think that counts as "obvious". Or at least not "intuitive" :-)


In any case, I don't think that the name mro_lookup is appropriate. It's 
misleading because it suggests that you pass something to be looked up, 
like a class, or perhaps an attribute name:

mro_lookup(starting_class, target_class)

mro_lookup(starting_class, 'method_name')



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Steven D'Aprano
On Sun, 23 Jun 2013 13:09:21 -0600, Ian Kelly wrote:

> On Sun, Jun 23, 2013 at 12:50 PM, Steven D'Aprano
>  wrote:
>> What else would you call a function that does lookups on the current
>> object's superclasses?
> 
> Well, as James Knight points out in the "Super Considered Harmful"
> article, the equivalent in Dylan is called "next-method", which isn't a
> valid identifier in Python but seems like a reasonable starting point.


I don't believe it is. Dylan's next-method is an implicit, automatically 
generated method parameter (a little like Python's "self") which holds 
the current value of the next method in the inheritance chain. Unlike 
super, it's only defined inside methods, because it is an implicit 
parameter to each method. It does not return a proxy object like Python's 
super, it's merely an alias to the next method in the chain (or Dylan's 
equivalent of False, when there is no such method), so you can't use it 
for arbitrary attribute lookups like you can with super.

I am not an expert on Dylan, but I'm pretty sure the above is correct. 
Here are some definitive references:

http://opendylan.org/books/drm/Method_Dispatch#HEADING-50-32

http://opendylan.org/documentation/intro-dylan/objects.html


next-method and super can be used for similar things, but they work in 
completely different ways, and next-method is quite limited compared to 
super. But suppose super had been named "next_method", as you suggest. 
Given a class C and an instance c, if I say `x = next_method(C, c)`, 
which method is x the next method of?

That's a trick question, of course. x is not a method at all, it is a 
proxy object such that when you do attribute lookup on it, it will return 
the appropriate attribute.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Rick Johnson
On Sunday, June 23, 2013 11:49:42 AM UTC-5, Roy Smith wrote:

> For what it's worth, I never bother to inherit from object
> unless I know there's something I need from new style
> classes.  Undoubtedly, this creates a disturbance in The
> Force, but such is life.

Well, in Python 3000, if you don't explicitly inherit from
"object", Python (aka: Guido's Master Control Program) is
going to implicitly do it for you; so i would suggest you be
explicit for the sake of the reader.

PS: I love how people say so confidently:

  "In Python 3, inheriting from object is optional!"

Obviously they don't understand the definition of optional.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Rick Johnson
On Sunday, June 23, 2013 11:15:38 AM UTC-5, Ian wrote:
> If you're worried about efficiency, you can also
> explicitly name the superclass in order to call the method
> directly, like:

I'm NOT worried about efficiency, i worried about
readability, and using super (when super is NOT absolutely
required) is folly.
 
> A.__init__(self, arg)

What you've done here is correct, the only flaw is that you
choose to do this for all the wrong reasons. 

...GET YOUR PRIORITIES IN ORDER!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Roy Smith
In article <51c74373$0$2$c3e8da3$54964...@news.astraweb.com>,
 Steven D'Aprano  wrote:

> On Sun, 23 Jun 2013 12:04:35 -0600, Ian Kelly wrote:
> 
> > On Sun, Jun 23, 2013 at 11:36 AM, Steven D'Aprano
> >  wrote:
> >> On Sun, 23 Jun 2013 11:18:41 -0600, Ian Kelly wrote:
> >>
> >>> Incidentally, although super() is useful, it's not perfect, and this
> >>> is one of my grievances with it: that a user can, based upon the name,
> >>> draw an inaccurate assumption about what it does without reading or
> >>> fully understanding the documentation on it, which might then result
> >>> in misusing it.
> >>
> >> Wait a second... are you saying that the Python developers created an
> >> advanced language feature relating to multiple inheritance, one of the
> >> most complex OOP concepts around, so difficult that most other
> >> languages simply prohibit it completely, and it wasn't instantly and
> >> correctly intuited by every single programmer based only on the name?
> >> Oh my stars, somebody call Ranting Rick, he needs to write a PyWart
> >> post to expose this scandal!!!
> > 
> > Mostly I'm saying that super() is badly named.
> 
> 
> What else would you call a function that does lookups on the current 
> object's superclasses?

Well, mro_lookup() would have been a better choice.  Super() has an 
obvious meaning, which just happens to be wrong.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Ian Kelly
On Sun, Jun 23, 2013 at 12:50 PM, Steven D'Aprano
 wrote:
> What else would you call a function that does lookups on the current
> object's superclasses?

Well, as James Knight points out in the "Super Considered Harmful"
article, the equivalent in Dylan is called "next-method", which isn't
a valid identifier in Python but seems like a reasonable starting
point.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Ian Kelly
On Sun, Jun 23, 2013 at 12:46 PM, Steven D'Aprano
 wrote:
> All is not lost, there are ways to make your classes cooperative. The
> trick is to have your classes' __init__ methods ignore keyword arguments
> they don't know what to do with. object used to do the same thing, but it
> no longer does, so you need to add an extra class just before object to
> swallow any args before they read object.
>
>
> class Blocker(object):
> def __init__(self, **kwargs):
> # Block kwargs from reaching object
> super(Blocker, self).__init__()

I don't like the idea of doing this with a cooperative __init__
method.  If any keyword arguments were passed that weren't consumed,
that is probably a bug, and this just swallows the exception instead
of reporting it.

Of course, if you're doing cooperative inheritance with some other
method that doesn't exist on object, then this technique is necessary
to prevent the topmost class from trying to call that method on object
and erroring out.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Steven D'Aprano
On Sun, 23 Jun 2013 12:04:35 -0600, Ian Kelly wrote:

> On Sun, Jun 23, 2013 at 11:36 AM, Steven D'Aprano
>  wrote:
>> On Sun, 23 Jun 2013 11:18:41 -0600, Ian Kelly wrote:
>>
>>> Incidentally, although super() is useful, it's not perfect, and this
>>> is one of my grievances with it: that a user can, based upon the name,
>>> draw an inaccurate assumption about what it does without reading or
>>> fully understanding the documentation on it, which might then result
>>> in misusing it.
>>
>> Wait a second... are you saying that the Python developers created an
>> advanced language feature relating to multiple inheritance, one of the
>> most complex OOP concepts around, so difficult that most other
>> languages simply prohibit it completely, and it wasn't instantly and
>> correctly intuited by every single programmer based only on the name?
>> Oh my stars, somebody call Ranting Rick, he needs to write a PyWart
>> post to expose this scandal!!!
> 
> Mostly I'm saying that super() is badly named.


What else would you call a function that does lookups on the current 
object's superclasses?



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Steven D'Aprano
On Sun, 23 Jun 2013 12:49:42 -0400, Roy Smith wrote:

> One thing I've never understood about Python 2.x's multiple inheritance
> (mostly because I almost never use it) is how you do something like
> this:
> 
> class Base1(object):
>def __init__(self, foo):
>   self.foo = foo
> 
> class Base2(object):
>def __init__(self, bar):
>   self.bar = bar
> 
> class Derived(Base1, Base2):
>def __init__(self, foo, bar):
>   # now what???
> 
> I need to call __init__() in both of my base classes.  I don't see how
> super() can do that for me.

It doesn't, and it can't, because your classes are not cooperative. The 
problem is, Derived.__init__ needs to call two super methods, but both of 
them require different arguments. If this was an ordinary method, you'd 
probably see the flaw straight away:

class Artist:
def draw(self, painting): ...

class Gambler:
def draw(self, cards): ...

class GamblingArtist(Gambler, Artist):
def draw(self, painting, cards):
...


Here you've got two completely different actions that merely share the 
same name, is it really sensible to have *one* method try to do both? And 
if so, you certainly can't expect an automated call to work out which 
argument goes to which superclass. So here's a place where cooperative 
multiple inheritance  doesn't work, and you're reduced to either manually 
calling the methods (and hoping that they don't, in turn, end up in some 
sort of diamond inheritance diagram, which would be bad), or else you 
have to redesign your classes to be more cooperative.

This is one of the reasons why many languages simply prohibit multiple 
inheritance outright, except perhaps for mixins, or at least require that 
all methods have compatible signatures.

All is not lost, there are ways to make your classes cooperative. The 
trick is to have your classes' __init__ methods ignore keyword arguments 
they don't know what to do with. object used to do the same thing, but it 
no longer does, so you need to add an extra class just before object to 
swallow any args before they read object.


class Blocker(object):
def __init__(self, **kwargs):
# Block kwargs from reaching object
super(Blocker, self).__init__()

class Base1(Blocker):
def __init__(self, foo, **kwargs):
self.foo = foo
super(Base1, self).__init__(**kwargs)

class Base2(Blocker):
def __init__(self, bar, **kwargs):
self.bar = bar
super(Base2, self).__init__(**kwargs)

class Derived(Base1, Base2):
def __init__(self, foo, bar):
super(Derived, self).__init__(foo=foo, bar=bar)


This may seem like a lot of work, but nobody said that cooperative 
multiple inheritance with different method signatures was easy!

The reality is, multiple inheritance is *hard*. Mixins and traits remove 
most of the problems, so if all you've ever used MI for is mixing in new 
behaviour, you won't get just how hard it really is. The best way to do 
MI is not to do it at all. But if you have to use it, then super is the 
only way to do it *right*. Anything else, and you're almost certainly 
either duplicating what super would do, or you've got bugs in your code.

Anyway, here are some links about super:

Super considered Super:
http://rhettinger.wordpress.com/2011/05/26/super-considered-super/

Here's a set of three posts, written quite a long time ago but still 
relevant, dissecting super in gory detail:

http://www.artima.com/weblogs/viewpost.jsp?thread=236275
http://www.artima.com/weblogs/viewpost.jsp?thread=236278
http://www.artima.com/weblogs/viewpost.jsp?thread=237121

and a more recent update:

http://www.artima.com/weblogs/viewpost.jsp?thread=281127

and a counter-argument, provocatively titled "Super considered Harmful", 
although the author backs away from this claim, since it turns out that 
the problems are not *super* but multiple inheritance itself.

https://fuhm.net/super-harmful/

Despite telling people not to use super, James Knight doesn't actually 
give them a better alternative. I believe this is because he can't -- 
super is the worst solution to multiple inheritance except for all the 
others.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Roy Smith
In article ,
 Ian Kelly  wrote:

> Yes, you're missing that super() does not simply call the base class,
> but rather the next class in the MRO for whatever the type of the
> "self" argument is.  If you write the above as:
> 
> class Base1(object):
>def __init__(self, foo, **kwargs):
>   super(Base1, self).__init__(**kwargs)
> 
> class Base2(object):
>def __init__(self, bar, **kwargs):
>   super(Base2, self).__init__(**kwargs)
> 
> class Derived(Base1, Base2):
>def __init__(self, **kwargs):
>   super(Derived, self).__init__(**kwargs)
> 
> And then you create an instance of Derived by calling
> Derived(foo='foo', bar='bar') and trace the call chain, you find that
> Derived.__init__ will call Base1.__init__(foo='foo', bar='bar'), which
> extracts its argument and then calls (surprise!)
> Base2.__init__(bar='bar'), which again extracts its argument and then
> calls object.__init__(), ending the chain.

Mind.  Blown.

I'm tempted to go all Ranting Rick about this being non-obvious, but I 
see you already covered that in another post :-)

The other thing I see here is that to make this work, the base classes 
need to accept **kwargs.  That's kind of annoying, since it means a 
class has to explicitly designed to be multiply-inheritable.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Ian Kelly
On Sun, Jun 23, 2013 at 11:36 AM, Steven D'Aprano
 wrote:
> On Sun, 23 Jun 2013 11:18:41 -0600, Ian Kelly wrote:
>
>> Incidentally, although super() is useful, it's not perfect, and this is
>> one of my grievances with it: that a user can, based upon the name, draw
>> an inaccurate assumption about what it does without reading or fully
>> understanding the documentation on it, which might then result in
>> misusing it.
>
> Wait a second... are you saying that the Python developers created an
> advanced language feature relating to multiple inheritance, one of the
> most complex OOP concepts around, so difficult that most other languages
> simply prohibit it completely, and it wasn't instantly and correctly
> intuited by every single programmer based only on the name? Oh my stars,
> somebody call Ranting Rick, he needs to write a PyWart post to expose
> this scandal!!!

Mostly I'm saying that super() is badly named.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Steven D'Aprano
On Sun, 23 Jun 2013 11:18:41 -0600, Ian Kelly wrote:

> Incidentally, although super() is useful, it's not perfect, and this is
> one of my grievances with it: that a user can, based upon the name, draw
> an inaccurate assumption about what it does without reading or fully
> understanding the documentation on it, which might then result in
> misusing it.

Wait a second... are you saying that the Python developers created an 
advanced language feature relating to multiple inheritance, one of the 
most complex OOP concepts around, so difficult that most other languages 
simply prohibit it completely, and it wasn't instantly and correctly 
intuited by every single programmer based only on the name? Oh my stars, 
somebody call Ranting Rick, he needs to write a PyWart post to expose 
this scandal!!! 

*wink*


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Steven D'Aprano
On Sat, 22 Jun 2013 23:40:53 -0600, Ian Kelly wrote:

> On Sat, Jun 22, 2013 at 11:23 PM, Steven D'Aprano
>  wrote:
>> On Sat, 22 Jun 2013 22:27:10 -0600, Ian Kelly wrote:
>>> I actually consider that an up side.  Sure it's inconvenient that you
>>> can't delegate all such methods at once just by overriding
>>> __getattribute__, but it would be more troublesome to *accidentally*
>>> implement such methods because you implemented __getattribute__.
>>
>> It's hard to see a case where that would be a bad thing.
>>
>> 1) If the proxied object doesn't include __dunder__ methods, then the
>> proxy will just end up up calling the default object dunder methods,
>> exactly as if they weren't proxied.
>>
>> 2) If the proxied object does include dunders, then you generally want
>> the proxy to call them, with perhaps one or two exceptions, which need
>> to be overridden regardless of whether they are dunders or not.
> 
> Proxying objects is not the only use of __getattribute__.

Okay, fair point.

Actually, I made a mistake... automatic delegation uses __getattr__, not 
__getattribute__.


>>> And
>>> then there are methods that really should not be delegated in the
>>> first place, like __del__.
>>
>> If you're using __del__, you're probably doing something wrong :-)
>>
>> I suppose that __del__ is a good counter-example, but (1) hardly any
>> classes use __del__, and (2) for those that do, it's *way* simpler to
>> manually override __del__ in the proxy than to manually delegate every
>> dunder method you care about. There are typically a lot of dunder
>> methods you care about.
> 
> If you manually override __del__ in the proxy, then as far as the
> garbage collector is concerned, your proxy object has a __del__ method
> (even if it does nothing), and so it will be treated differently from an
> object without a __del__ method.

Ack, I get that.

A thought comes to mind... perhaps Python ought to treat a class with 
__del__ set to None as if there was no __del__ at all? At the moment the 
garbage collector blindly calls __del__ and gets a TypeError.


>> It is not the case that dunder methods cannot be automatically proxied
>> because somebody deliberately designed Python to work that way. It's an
>> accidental side-effect of the way new-style classes resolve method
>> calls, due to decisions made for other reasons having nothing to do
>> with delegation.
> 
> Can you elaborate or provide a link?  I'm curious to know what other
> reason there could be for magic methods to behave differently from
> normal methods in this regard.

It's an efficiency optimization. I don't quite get the details, but when 
you run something like "a + b", Python doesn't search for __add__ using 
the normal method lookup procedure. That allows it to skip checking the 
instance __dict__, as well as __getattribute__ and __getattr__. End 
result is that it's quite a bit faster than ordinary lookup, but the side-
effect is that the semantics are a little different:

- you can't proxy magic methods automatically;

- __getattribute__ and __getattr__ are only called for explicit attribute 
access, not for implied calls to magic methods;

- you can't override a magic method on a per instance basis.

Note that explicit calls like "obj.__add__(thing)" take the regular 
method lookup, it's just "obj + thing" that takes the shortcut.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Ian Kelly
On Sun, Jun 23, 2013 at 11:08 AM, Ian Kelly  wrote:
> On Sun, Jun 23, 2013 at 10:49 AM, Roy Smith  wrote:
>> am I missing something here?
>
> Yes, you're missing that super() does not simply call the base class,
> but rather the next class in the MRO for whatever the type of the
> "self" argument is.  If you write the above as:

Incidentally, although super() is useful, it's not perfect, and this
is one of my grievances with it: that a user can, based upon the name,
draw an inaccurate assumption about what it does without reading or
fully understanding the documentation on it, which might then result
in misusing it.  There might still be some code I wrote out there from
when I first started using Python that looks something like:

def __init__(self):
super(Base, self).__init__()
Mixin.__init__(self)

Which is simply wrong, wrong, wrong.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Ian Kelly
On Sun, Jun 23, 2013 at 10:49 AM, Roy Smith  wrote:
> One thing I've never understood about Python 2.x's multiple inheritance
> (mostly because I almost never use it) is how you do something like this:
>
> class Base1(object):
>def __init__(self, foo):
>   self.foo = foo
>
> class Base2(object):
>def __init__(self, bar):
>   self.bar = bar
>
> class Derived(Base1, Base2):
>def __init__(self, foo, bar):
>   # now what???
>
> I need to call __init__() in both of my base classes.  I don't see how
> super() can do that for me.  I assume I would just do:
>
>def __init__(self, foo, bar):
>   Base1.__init__(self, foo)
>   Base2.__init__(self, bar)
>
> am I missing something here?

Yes, you're missing that super() does not simply call the base class,
but rather the next class in the MRO for whatever the type of the
"self" argument is.  If you write the above as:

class Base1(object):
   def __init__(self, foo, **kwargs):
  super(Base1, self).__init__(**kwargs)

class Base2(object):
   def __init__(self, bar, **kwargs):
  super(Base2, self).__init__(**kwargs)

class Derived(Base1, Base2):
   def __init__(self, **kwargs):
  super(Derived, self).__init__(**kwargs)

And then you create an instance of Derived by calling
Derived(foo='foo', bar='bar') and trace the call chain, you find that
Derived.__init__ will call Base1.__init__(foo='foo', bar='bar'), which
extracts its argument and then calls (surprise!)
Base2.__init__(bar='bar'), which again extracts its argument and then
calls object.__init__(), ending the chain.

Of course if you create an instance of Base1, then the Base1 super
call will next call object.__init__ directly, instead of
Base2.__init__.  This happens because Base2 occurs after Base1 in the
MRO for the class Derived, but Base2 does not appear at all in the MRO
for the class Base1.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Roy Smith
In article <51c723b4$0$2$c3e8da3$54964...@news.astraweb.com>,
 Steven D'Aprano  wrote:

> On Sun, 23 Jun 2013 10:15:38 -0600, Ian Kelly wrote:
> 
> > If you're worried about efficiency, you can also explicitly name the
> > superclass in order to call the method directly, like:
> > 
> > A.__init__(self, arg)
> 
> Please don't. This is false economy. The time you save will be trivial, 
> the overhead of inheritance is not going to be the bottleneck in your 
> code, and by ignoring super, you only accomplish one thing:
> 
> - if you use your class in multiple inheritance, it will be buggy.

One thing I've never understood about Python 2.x's multiple inheritance 
(mostly because I almost never use it) is how you do something like this:

class Base1(object):
   def __init__(self, foo):
  self.foo = foo

class Base2(object):
   def __init__(self, bar):
  self.bar = bar

class Derived(Base1, Base2):
   def __init__(self, foo, bar):
  # now what???

I need to call __init__() in both of my base classes.  I don't see how 
super() can do that for me.  I assume I would just do:

   def __init__(self, foo, bar):
  Base1.__init__(self, foo)
  Base2.__init__(self, bar)

am I missing something here?

For what it's worth, I never bother to inherit from object unless I know 
there's something I need from new style classes.  Undoubtedly, this 
creates a disturbance in The Force, but such is life.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Steven D'Aprano
On Sun, 23 Jun 2013 10:15:38 -0600, Ian Kelly wrote:

> If you're worried about efficiency, you can also explicitly name the
> superclass in order to call the method directly, like:
> 
> A.__init__(self, arg)

Please don't. This is false economy. The time you save will be trivial, 
the overhead of inheritance is not going to be the bottleneck in your 
code, and by ignoring super, you only accomplish one thing:

- if you use your class in multiple inheritance, it will be buggy.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Ian Kelly
On Sun, Jun 23, 2013 at 7:35 AM, Adam Jiang  wrote:
> Another question raised here is that what is the proper way to refer
> to parent class? For example,
>
> class A(object):
> def __init__(self, arg):
> print "A"
>
> class B(A):
> def __init__(self, arg):
> super(B, self).__init__(arg)
>
> Is this correct? As the result, whenever you wanted to refer to a
> method in parent class, super() functions has to be called. This seems
> inefficient.

Generally, use super() any time you want to refer to a class attribute
(such as a method) in a parent class that is overridden in the child
class. Also note that in Python 3, the call "super(B, self)" can be
condensed to just "super()".

If you're worried about efficiency, you can also explicitly name the
superclass in order to call the method directly, like:

A.__init__(self, arg)

However, super() is generally considered the right way to do this, in
order to avoid repeating the parent class name, for brevity in Python
3, and because it is needed to correctly handle some cases of multiple
inheritance.

> How to refer to a field defined in parent class?

For instance attributes or attributes that haven't been overridden,
just write "self.attribute_name".
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-23 Thread Adam Jiang
> * property only works in "new-style" classes that inherit from object;
> 
> * likewise for super;

Another question raised here is that what is the proper way to refer
to parent class? For example,

class A(object):
def __init__(self, arg):
print "A"

class B(A):
def __init__(self, arg):
super(B, self).__init__(arg)

Is this correct? As the result, whenever you wanted to refer to a
method in parent class, super() functions has to be called. This seems
inefficient.

How to refer to a field defined in parent class?

Thanks,
/Adam

>On Sun, Jun 23, 2013 at 03:20:02AM +, Steven D'Aprano wrote:
> On Sat, 22 Jun 2013 19:58:38 -0700, Adam wrote:
> 
> > class FooBar(object):
> > def __init__(self):
> > ...
> > 
> > Inheritance usually takes a class name to indicate which class is the
> > 'parent' class. However, in the previous example, from a django book,
> > the class actually takes an 'object' like parameter, doesn't it? What is
> > the semantics meaning of such kind of notation?
> 
> It's not merely notation, "object" is the name of a class. If you type it 
> (without quotes) at the interactive interpreter, you will see it is a 
> built-in class:
> 
> py> object
> 
> 
> 
> In Python 3, the use of object as base class is optional, but in Python 2 
> there is a subtle difference between classes that inherit from object and 
> those that don't. The reason for this difference is buried in the mists 
> of time, going back to Python 2.2. If you are interested, google on 
> "Python unifying types and classes":
> 
> https://duckduckgo.com/html/?q=Python+unifying+types+and+classes
> 
> 
> As a general rule, unless you actually want "old-style class" behaviour, 
> you should always inherit from object (or some other built-in type) in 
> Python 2. In Python 3, it doesn't matter.
> 
> The differences include:
> 
> * property only works in "new-style" classes that inherit from object;
> 
> * likewise for super;
> 
> * multiple inheritance with old-style classes can be buggy;
> 
> * new-style classes may be slightly faster in general;
> 
> * on the down side, automatic delegation of special double-underscore 
> methods like __getitem__ and __str__ doesn't work with new-style classes.
> 
> 
> If none of this means anything to you, be glad, and just inherit from 
> object or some other built-in type in all your classes, and all will be 
> good.
> 
> 
> 
> 
> -- 
> Steven
> -- 
> http://mail.python.org/mailman/listinfo/python-list
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-22 Thread Ian Kelly
On Sat, Jun 22, 2013 at 11:23 PM, Steven D'Aprano
 wrote:
> On Sat, 22 Jun 2013 22:27:10 -0600, Ian Kelly wrote:
>> I actually consider that an up side.  Sure it's inconvenient that you
>> can't delegate all such methods at once just by overriding
>> __getattribute__, but it would be more troublesome to *accidentally*
>> implement such methods because you implemented __getattribute__.
>
> It's hard to see a case where that would be a bad thing.
>
> 1) If the proxied object doesn't include __dunder__ methods, then the
> proxy will just end up up calling the default object dunder methods,
> exactly as if they weren't proxied.
>
> 2) If the proxied object does include dunders, then you generally want
> the proxy to call them, with perhaps one or two exceptions, which need to
> be overridden regardless of whether they are dunders or not.

Proxying objects is not the only use of __getattribute__.

>> And
>> then there are methods that really should not be delegated in the first
>> place, like __del__.
>
> If you're using __del__, you're probably doing something wrong :-)
>
> I suppose that __del__ is a good counter-example, but (1) hardly any
> classes use __del__, and (2) for those that do, it's *way* simpler to
> manually override __del__ in the proxy than to manually delegate every
> dunder method you care about. There are typically a lot of dunder methods
> you care about.

If you manually override __del__ in the proxy, then as far as the
garbage collector is concerned, your proxy object has a __del__ method
(even if it does nothing), and so it will be treated differently from
an object without a __del__ method.

> It is not the case that dunder methods cannot be automatically proxied
> because somebody deliberately designed Python to work that way. It's an
> accidental side-effect of the way new-style classes resolve method calls,
> due to decisions made for other reasons having nothing to do with
> delegation.

Can you elaborate or provide a link?  I'm curious to know what other
reason there could be for magic methods to behave differently from
normal methods in this regard.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-22 Thread Steven D'Aprano
On Sat, 22 Jun 2013 22:27:10 -0600, Ian Kelly wrote:

> On Sat, Jun 22, 2013 at 9:20 PM, Steven D'Aprano
>  wrote:
>> * on the down side, automatic delegation of special double-underscore
>> methods like __getitem__ and __str__ doesn't work with new-style
>> classes.
> 
> I actually consider that an up side.  Sure it's inconvenient that you
> can't delegate all such methods at once just by overriding
> __getattribute__, but it would be more troublesome to *accidentally*
> implement such methods because you implemented __getattribute__.  

It's hard to see a case where that would be a bad thing.

1) If the proxied object doesn't include __dunder__ methods, then the 
proxy will just end up up calling the default object dunder methods, 
exactly as if they weren't proxied.

2) If the proxied object does include dunders, then you generally want 
the proxy to call them, with perhaps one or two exceptions, which need to 
be overridden regardless of whether they are dunders or not.


> And
> then there are methods that really should not be delegated in the first
> place, like __del__.

If you're using __del__, you're probably doing something wrong :-)

I suppose that __del__ is a good counter-example, but (1) hardly any 
classes use __del__, and (2) for those that do, it's *way* simpler to 
manually override __del__ in the proxy than to manually delegate every 
dunder method you care about. There are typically a lot of dunder methods 
you care about.

It is not the case that dunder methods cannot be automatically proxied 
because somebody deliberately designed Python to work that way. It's an 
accidental side-effect of the way new-style classes resolve method calls, 
due to decisions made for other reasons having nothing to do with 
delegation. That this accident just happens to have one tiny silver 
lining doesn't change the fact that, overall, it's still a dark cloud.

In classic classes, automatic delegation was a first-class design 
pattern. With new-style classes, it's second-class, and that's a pity.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-22 Thread Ian Kelly
On Sat, Jun 22, 2013 at 9:20 PM, Steven D'Aprano
 wrote:
> * on the down side, automatic delegation of special double-underscore
> methods like __getitem__ and __str__ doesn't work with new-style classes.

I actually consider that an up side.  Sure it's inconvenient that you
can't delegate all such methods at once just by overriding
__getattribute__, but it would be more troublesome to *accidentally*
implement such methods because you implemented __getattribute__.  And
then there are methods that really should not be delegated in the
first place, like __del__.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is the semantics meaning of 'object'?

2013-06-22 Thread Steven D'Aprano
On Sat, 22 Jun 2013 19:58:38 -0700, Adam wrote:

> class FooBar(object):
> def __init__(self):
> ...
> 
> Inheritance usually takes a class name to indicate which class is the
> 'parent' class. However, in the previous example, from a django book,
> the class actually takes an 'object' like parameter, doesn't it? What is
> the semantics meaning of such kind of notation?

It's not merely notation, "object" is the name of a class. If you type it 
(without quotes) at the interactive interpreter, you will see it is a 
built-in class:

py> object



In Python 3, the use of object as base class is optional, but in Python 2 
there is a subtle difference between classes that inherit from object and 
those that don't. The reason for this difference is buried in the mists 
of time, going back to Python 2.2. If you are interested, google on 
"Python unifying types and classes":

https://duckduckgo.com/html/?q=Python+unifying+types+and+classes


As a general rule, unless you actually want "old-style class" behaviour, 
you should always inherit from object (or some other built-in type) in 
Python 2. In Python 3, it doesn't matter.

The differences include:

* property only works in "new-style" classes that inherit from object;

* likewise for super;

* multiple inheritance with old-style classes can be buggy;

* new-style classes may be slightly faster in general;

* on the down side, automatic delegation of special double-underscore 
methods like __getitem__ and __str__ doesn't work with new-style classes.


If none of this means anything to you, be glad, and just inherit from 
object or some other built-in type in all your classes, and all will be 
good.




-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


What is the semantics meaning of 'object'?

2013-06-22 Thread Adam
class FooBar(object):
def __init__(self):
...

Inheritance usually takes a class name to indicate which class is the 'parent' 
class. However, in the previous example, from a django book, the class actually 
takes an 'object' like parameter, doesn't it? What is the semantics meaning of 
such kind of notation?

Thanks,
/Adam
-- 
http://mail.python.org/mailman/listinfo/python-list