Class Variable Access and Assignment

P

Paul Rubin

I'm surprised that it never occurred to you that people might
want to do something like x = 1; x += 1 in Python,

But I wouldn't expect that to mean that ints implement __iadd__. I'd expect
the x+=1 to just use __add__. I haven't checked the spec though.
I can respect the position of somebody who says that only methods
should be inherited -- somebody, I think it was you, suggested that there
is at least one existing OO language that doesn't allow inheritance for
attributes, but never responded to my asking what language it was.

I was thinking of Flavors. You use a special function (send) to do method
calls. But people generally felt that was kludgy and CLOS eliminated it.
I'm not sure what happens in Smalltalk.
instance.attribute sometimes reading from the class attribute is a feature
of inheritance; instance.attribute always writing to the instance is a
feature of OOP; instance.attribute sometimes writing to the instance and
sometimes writing to the class would be, in my opinion, not just a wart
but a full-blown misfeature.

But that is what you're advocating: x.y+=1 writes to the instance or
the class depending on whether x.y is mutable or not. Say you have an
immutable class with a mutable subclass or vice versa. You'd like to
be able to replace a class instance with a subclass instance and not
have the behavior change (Liskov substitution principle), etc.
 
S

Steve Holden

Steven D'Aprano wrote:
[...]
But I can't understand the position of folks who want inheritance but
don't want the behaviour that Python currently exhibits.
instance.attribute sometimes reading from the class attribute is a feature
of inheritance; instance.attribute always writing to the instance is a
feature of OOP; instance.attribute sometimes writing to the instance and
sometimes writing to the class would be, in my opinion, not just a wart
but a full-blown misfeature.

I ask and I ask and I ask for some use of this proposed behaviour, and
nobody is either willing or able to tell me where how or why it would be
useful. What should I conclude from this?

You should conclude that some readers of this group are happier
designing languages with theoretical purity completely disconnected from
users' needs. But of course we pragmatists know that practicality beats
purity :)

regards
Steve
 
S

Steven D'Aprano

But that is what you're advocating: x.y+=1 writes to the instance or
the class depending on whether x.y is mutable or not.

Scenario 1:

Pre-conditions: class.a exists; instance.a exists.
Post-conditions: class.a unchanged; instance.a modified.

I give that a big thumbs up, expected and proper behaviour.

Scenario 2:

Pre-conditions: class.a exists and is immutable; instance.a does not
exist.
Post-conditions: class.a unchanged; instance.a exists.

Again, expected and proper behaviour.

(Note: this is the scenario that Antoon's proposed behaviour would change
to class.a modified; instance.a does not exist.)

Scenario 3:

Pre-conditions: class.a exists and is mutable; instance.a exists.
Post-conditions: class.a unchanged; instance.a is modified.

Again, expected and proper behaviour.

Scenario 4:

Pre-conditions: class.a exists and is mutable; instance.a does
not exist.
Post-conditions: class.a modified; instance.a does not exist.

Well, that is a wart. It is the same wart, and for the same reasons, as
the behaviour of:

def function(value=[]):
value.append(None)

I can live with that. It is a familiar wart, and keeps inheritance of
attributes working the right way. And who knows? If your attributes are
mutable, AND you want Antoon's behaviour, then you get it for free just by
using b.a += 1 instead of b.a = b.a + 1.

Say you have an
immutable class with a mutable subclass or vice versa. You'd like to
be able to replace a class instance with a subclass instance and not
have the behavior change (Liskov substitution principle), etc.

That's easy. You just have to make sure that the subclass implements
__iadd__ the same way that the immutable parent class does.

You can't expect a class that performs += in place to act the
same as a class that doesn't perform += in place. Excessive data
abstraction, remember?

L = list("Liskov substitution principle")
L.sort() # sorts in place
print L # prints the sorted list

class immutable_list(list):
# __init__ not shown, but does the right thing
def sort(self):
tmp = list(self)
tmp.sort()
return immutable_list(tmp)

L = immutable_list("Liskov substitution principle")
L.sort() # throws the sorted list away
print L # prints the unsorted list

The only way the Liskov substitution principle works is if everything
works the same way, which means that all subclasses, all *possible*
subclasses, must have no more functionality than the subclass that does
the absolute least. Since the least is nothing, well, you work it out.
 
B

Bengt Richter

Scenario 1:

Pre-conditions: class.a exists; instance.a exists.
Post-conditions: class.a unchanged; instance.a modified.

I give that a big thumbs up, expected and proper behaviour.

Scenario 2:

Pre-conditions: class.a exists and is immutable; instance.a does not
exist.
Post-conditions: class.a unchanged; instance.a exists.

Again, expected and proper behaviour.

(Note: this is the scenario that Antoon's proposed behaviour would change
to class.a modified; instance.a does not exist.)

Scenario 3:

Pre-conditions: class.a exists and is mutable; instance.a exists.
Post-conditions: class.a unchanged; instance.a is modified.

Again, expected and proper behaviour.

Scenario 4:

Pre-conditions: class.a exists and is mutable; instance.a does
not exist.
Post-conditions: class.a modified; instance.a does not exist.
Are you saying the above is what happens or what should happen or not happen?
It's not what happens. Post-conditions are that class.a is modified AND
instance.a gets a _separate_ reference to the same result. Note:

Python 2.4b1 (#56, Nov 3 2004, 01:47:27)
[GCC 3.2.3 (mingw special 20030504-1)] on win32
Type "help", "copyright", "credits" or "license" for more information. ... a = []
...
>>> b=A()
>>> id(A.__dict__['a']) 49230700
>>> b.a += [123]
>>> id(A.__dict__['a']) 49230700
>>> id(b.__dict__['a']) 49230700
>>> (b.__dict__['a']) [123]
>>> (A.__dict__['a'])
[123]

Let's eliminate the inheritable class variable A.a:
>>> del A.a
>>> b.a [123]
>>> id(b.__dict__['a']) 49230700
>>> vars(b)
{'a': [123]}

Make sure we did eliminate A.a ['__dict__', '__module__', '__weakref__', '__doc__']

Is that the "wart" you were thinking of, or are you actually happier? ;-)
Well, that is a wart. It is the same wart, and for the same reasons, as
the behaviour of:

def function(value=[]):
value.append(None)
IMO that's not a wart at all, that's a direct design decision, and it's
different from the dual referencing that happens in Scenario 4.
I can live with that. It is a familiar wart, and keeps inheritance of
attributes working the right way. And who knows? If your attributes are
mutable, AND you want Antoon's behaviour, then you get it for free just by
using b.a += 1 instead of b.a = b.a + 1.
Not quite, because there is no way to avoid the binding of the __iadd__
return value to b.a by effective setattr (unless you make type(b).a
a descriptor that intercepts the attempt -- see another post for example).

Regards,
Bengt Richter
 
S

Steven D'Aprano

Are you saying the above is what happens or what should happen or not happen?

Er, it's what I thought was happening without actually checking it...
It's not what happens. Post-conditions are that class.a is modified AND
instance.a gets a _separate_ reference to the same result. Note:

[snip demonstration]
Is that the "wart" you were thinking of, or are you actually happier?
;-)

In other words, the post-condition for all four scenarios includes that
the instance attribute now exists. I'm actually happier. My brain was full
of people talking about __iadd__ modifying mutables in place and I wasn't
thinking straight.

Well, that is a wart. It is the same wart, and for the same reasons, as
the behaviour of:

def function(value=[]):
value.append(None)
IMO that's not a wart at all, that's a direct design decision, and it's
different from the dual referencing that happens in Scenario 4.

Okay, perhaps wart is not quite the right word... but it is certainly
unexpected if you haven't come across it before, or thought *deeply* about
what is going on. A gotcha perhaps.
 
C

Christopher Subich

Bengt said:
But if it is an esoteric descriptor (or even a simple property, which is
a descriptor), the behaviour will depend on the descriptor, and an instance
variable can be created or not, as desired, along with any side effect you like.

Right, and that's also language-specification. Voodoo, yes, but
language specification nonetheless. :)
 
B

Bengt Richter

Right, and that's also language-specification. Voodoo, yes, but
language specification nonetheless. :)

I guess http://docs.python.org/ref/augassign.html is the spec.
I notice its example at the end uses an old-style class, so maybe
it's understandable that when it talks about getattr/setattr, it doesn't
mention the possible role of descriptors, nor narrow the meaning of
"evaluate once" for a.x to exclude type(a).x in the setattr phase of execution.

I.e., if x is a descriptor, "evaluate" apparently means only

type(a).x.__get__(a, type(a))

since that is semantically getting the value behind x, and so both of the ".x"s in

type(a).x.__set__(a, type(a).x.__get__(a, type(a)).__add__(1)) # (or __iadd__ if defined, I think ;-)

don't count as "evaluation" of the "target" x, even though it means that a.x got evaluated twice
(via getattr and setattr, to get the same descriptor object (which was used two different ways)).

I think the normal, non-descriptor case still results in (optimized) probes for type(a).x.__get__
and type(a).x.__set__ before using a.__dict__['x'].

ISTM also that it's not clear that defining __iadd__ does _not_ prevent the setattr phase from going ahead.
I.e., a successful __iadd__ in-place mutation does not happen "instead" of the setattr.

Regards,
Bengt Richter
 
A

Antoon Pardon

Op 2005-11-04 said:
Antoon said:
Except when your default is a list

class foo:
x = [] # default

a = foo()
a.x += [3]

b = foo()
b.x

This results in [3]. So in this case using a class variable x to
provide a default empty list doesn't work out in combination
with augmented operators.

This has nothing to do with namespacing at all,

Yes it has.
it's the Python
idiosyncracy about operations on mutable types. In this case, +=
mutates an object, while + returns a new one -- as by definition, for
mutables.

It is the combination of the two.

If python had chosen for an approach like function namespaces, the
problem wouldn't have occured either. What would have happened then
is that the compilor would have noticed the a.x on the right hand
side and based on that fact would then have deciced that all a.x
references should be instance reference (at least in that function
block). The a.x += ... would then result in an AttributeError being raised.

You may prefer the current behaviour over this, but that is not the
point. The point is that resolution of name spaces does play its
role in this problem.


It also has little to do with mutable vs immutable types.
Someone could implement an immutable type, but take advantage
of some implemtation details to change the value inplace
in the __iadd__ method. Such an immutable type would show
the same problems.
 
A

Antoon Pardon

Op 2005-11-04 said:
Compare:

b.a += 2

Before the assignment, instance b does not have an attribute "a", so class
attribute "a" is accessed. You seem to be objecting to this inheritance.

I object to the inheritance in a scope where b.a also refers to the
instance.

If there is no problem that a reference can refer to different objects
in the same scope, then the following should work too.

a = 0
def f():
a += 2

One can reason just the same that before the assignment f doesn't have
a local variable yet, so the global should be accessed. People who
don't agree don't want functions to have access to outer scope
variables.
Do you object to import searching multiple directories?

Why do you object to attribute resolution searching multiple namespaces?

I don't.
Look a little more closely. In all three pieces of code, you have a
conflict between the class attribute 'ls' and an instance attribute 'ls'.

No you look a little more clearly.
In the first scenario, that conflict is resolved by insisting that
instances explicitly define an attribute, in other words, by making
instance attribute ONLY search the instance namespace and not the class
namespace.

No it isn't. You seem unable to make a difference between a resolution
in general, and a resolution in a scope where an assignment has been
made.
 
A

Antoon Pardon

Op 2005-11-04 said:
Antoon said:
Well I wonder. Would the following code be considered a name binding
operation:

b.a = 5

Try it, it's not.

Python 2.2.3 (#1, Nov 12 2004, 13:02:04)
[GCC 3.2.3 20030502 (Red Hat Linux 3.2.3-42)] on linux2
Type "help", "copyright", "credits" or "license" for more information.Traceback (most recent call last):
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'object' object has no attribute 'a'

Once it's attached to an object, it's an attribute, not a base name.

So? It is still a name and it gets bound to an object. Sure the name
is bound within a specific namespace but that is IMO a detail.
unified for Py3k, but in cases like this the distinction is important.

But part of this dicussion is about the sanity of making these kind
of distinctions. Since they apparantly plan to get rid of them in
Py3k, I guess I'm not the only one questioning that.
 
A

Antoon Pardon

Op 2005-11-04 said:
It's just a little further down. I'll post the quote once more (but
this is the last time ;^):

I appreciate you quoting the documentation. But I would appreciate
a URL even more. It isn't necessary now any more but it would have
been usefull the first time you quoted this material.
"""For targets which are attribute references, the initial value is
retrieved with a getattr() and the result is assigned with a setattr().
Notice that the two methods do not necessarily refer to the same
variable. When getattr() refers to a class variable, setattr() still
writes to an instance variable. For example:

class A:
x = 3 # class variable
a = A()
a.x += 1 # writes a.x as 4 leaving A.x as 3"""

I'd say it's documented...

Well then I guess they have documented awkward behaviour.
I fear that this has to do with the way reality works. Perhaps
it's due to Gödel's incompleteness theorems... :)

Sure, Python has evolved and grown for about 15 years, and
backward compatibility has always been an issue, but the
management and development of Python is dynamic and fairly
open-minded. If there had been an obvious way to change this
in a way that solved more problems than it caused, I suspect
that change would have happened already.

Fine I can live with that.
 
A

Antoon Pardon

Op 2005-11-04 said:
Antoon said:
Well maybe because as far as I understand the same kind of logic
can be applied to something like

lst[f()] += foo

In order to decide that this should be equivallent to

lst[f()] = lst[f()] + foo.

But that isn't the case.

Because, surprisingly enough, Python tends to evaluate expressions only
once each time they're invoked.

Well but once can consider b.a as an expression too. An expression
that gets evaluated twice in case of

b.a += 2
In this case, [] is being used to get an item and set an item --
therefore, it /has/ to be invoked twice -- once for __getitem__, and
once for __setitem__.

But we are here questioning language design. One could question a design
where it is necessary to invoke the [] operator twice, even when it
is only mentioned once in the code.
Likewises, lst appears once, and it is used once -- the name gets looked
up once (which leads to a += 1 problems if a is in an outer scope).

f() also appears once -- so to evaluate it more than one time is odd,
at best.

No more or less than "[]" or "." is to be invoked twice.
 
A

Antoon Pardon

Op 2005-11-04 said:
Follow the logical implications of this proposed behaviour.

class Game:
current_level = 1
# by default, games start at level one

def advance(self):
self.current_level += 1


py> antoon_game = Game()
py> steve_game = Game()
py> steve_game.advance()
py> steve_game.advance()
py> print steve_game.level
3
py> print antoon_game.level

What will it print?

Hint: your scheme means that class attributes mask instance attributes.

So? This proposal was not meant to replace the current behaviour.
It was meant to contradict your assertion that some particular
behaviour implied mutable numbers.

My proposal was an example that showed the particular behaviour and
didn't require mutable numbers, so it showed your assertion false.
 
A

Antoon Pardon

Op 2005-11-04 said:
Because names in function namespaces don't have inheritance.

Your quibling about words. This certainly works.

x = 1
def f():
a = x + 1

So you could say that function namespaces do inherit from
outer scopes.

Whether you want to name it inheritance or not, is not the
issue.
 
A

Antoon Pardon

Op 2005-11-04 said:
Now the b.a on the right hand side refers to A.a the first time through
the loop but not the next times. I don't think it is sane that which
object is refered to depends on how many times you already went through
the loop.
[snip]
Look at that: the object which is referred to depends on how many times
you've already been through the loop. How nuts is that?

It is each time the 'x' from the same name space. In the code above the
'a' is not each time from the same namespace.

I also think you new very well what I meant.

I'm supposed to be a mindreader now? After you've spent multiple posts
ranting that, quote, "I don't think it is sane that which object is
refered to depends on how many times you already went through the loop",
I'm supposed to magically read your mind and know that you don't actually
object to what you say you object to, but to something completely
different?

No I meant object when I wrote object. But it is not about the object,
it is about the "being refered to". And how do you refer to objects,
by names in namespace or variables.
 
A

Antoon Pardon

Op 2005-11-06 said:
Steven D'Aprano wrote:
[...]
But I can't understand the position of folks who want inheritance but
don't want the behaviour that Python currently exhibits.
instance.attribute sometimes reading from the class attribute is a feature
of inheritance; instance.attribute always writing to the instance is a
feature of OOP; instance.attribute sometimes writing to the instance and
sometimes writing to the class would be, in my opinion, not just a wart
but a full-blown misfeature.

I ask and I ask and I ask for some use of this proposed behaviour, and
nobody is either willing or able to tell me where how or why it would be
useful. What should I conclude from this?

You should conclude that some readers of this group are happier
designing languages with theoretical purity completely disconnected from
users' needs. But of course we pragmatists know that practicality beats
purity :)

But explicit is better than implicit.
 
A

Antoon Pardon

Op 2005-11-05 said:
Is that a round-about way of saying that you really have no idea of
whether, how or when your proposed behaviour would be useful?

I am not proposing specific behaviour. Because if I do, you will
just try to argue how much worst my proposed behaviour is.

Whether or not I can come up with a better proposal is irrelevant
to how sane the current behaviour is.
Personally, I think that when you are proposing a major change to a
language that would break the way inheritance works, there should be more
benefits to the new way than the old way.

How many times do I have to repeat myself. I'm not proposing a change
to the language.
Antoon, I've been pedanted at by experts, and you ain't one. The behaviour
which you repeatedly described as not sane implements the model for
inheritance. The fact that you never explicitly said "the standard OO
model of inheritance" cuts no ice with me, not when you've written
multiple posts saying that the behaviour of that standard inheritance
model is not sane.

I haven't written that once. You may think that you can imply it from
what I wrote, but then that is your inferance and not my words.
"Unsane" now?

Heaven forbid that I should criticise people for inventing new words, but
how precisely is unsane different from insane? In standard English,
something which is not sane is insane.

Well maybe English works differently from dutch, but I thought there
were a whole lot of gradation between sane and insane. And not being
sane IMO just means not being at one end of the extreme while being
insane meant to be at the other end of the extreme.

So when something doesn't make complete sense, instead of it making
no sense at all, I would think that wording it as unsane instead of
insane resembles best what I intended to mean.
If you're just trolling, you've done a great job of it because you fooled
me well and good. But if you are serious in your criticism about the
behaviour, then stop mucking about and tell us what the behaviour should
be. Otherwise your criticism isn't going to have any practical effect on
the language at all.

I wasn't trolling. I just threw in an off hand remark. That you got so
heated up about that remark is not my responsibility. I'm not trolling
because I'm willing to defend my remark and I don't intend to get
people to get heated up about it. I just don't hold back because
people may get heated up about it.
If you are serious about wanting the behaviour changed, and not just
whining, then somebody has to come up with an alternative behaviour that
is better.

If I would be whining I would want the behaviour changed. I would just
keep complaining about it until someone else would have changed it.

Sure I would prefer it changed, but it is not that I *want* it to
change. I'll happily continue with python if it doesn't change.

Maybe when someone mentions something negative about python,
you shouldn't translate that into someone demanding a change
in python.
If not you, then who? Most of the folks who have commented on
this thread seem to like the existing behaviour.

Well fine, in that case it won't even change if I do come up with
an alternative proposal. So why should I bother?
 
M

Magnus Lycka

First of all, I've still not heard any sensible suggestions
about a saner behaviour for augmented assignment or for the
way Python searches the class scope after the instance scope.

What do you suggest?

Today, x += n acts just as x = x + n if x is immutable.
Do you suggest that this should change?

Today, instance.var will look for var in the class
scope if it didn't find it in the instance scope. Do
you propose to change this?

Or, do you propose that we should have some second order
effect that makes the combination of instance.var += n
work in such a way that these features are no longer
orthogonal?

Paul said:
So add:

self.size = Paper.size

and you've removed the weirdness. What do you gain here by inheriting?

class LetterPaper(Paper):
size = Letter

class LegalPaper(Paper):
size = Legal

This is what you gain. Subclassing it extremely simple, if all
you want is that the subclass differs in data. You could also
have __init__ pick up the class variable and set an instance
variable, but why make things difficult if it's trivial now?

Considering how __init__ works in Python class hierachies,
where you need to manually call __init__ in ancestor classes
if you've overridden them, the fact that a simple self.size
picks up a class variable is particularly useful if you use
MI. For instance I could imagine a FirstPageMixin class in
this case, and a FancyFirstPageMixin that subclasses that.
There, we might want to pick up certain margin values or
other positions etc.

The spirit of Python is to make it easy to do things right,
not make it difficult to make mistakes. If you want a language
that tries to prevent you from making mistakes, use Ada.

When developing code in a dynamic language such as Python,
it's really important to have a decent set of automated tests.
If you have, you'll hopefully notice bugs like these. Making
changes in the language that forces you to write more code
will in general not reduce the total number of bugs, but
rather increase them.

I've been involved with high reliability design long enough to
know the problems involved fairly well. I mainly worked with
electronic design then, but the problem is the same: The more
safety gadgets you add, the more stuff you have that can break.
The details are a bit difference, but in principle the problem
is the same.

Ever wondered why Russian and Chinese rocket launchers have a
better reliability than the American? Simply put, they're simpler.
 
S

Steve Holden

Antoon said:
I am not proposing specific behaviour. Because if I do, you will
just try to argue how much worst my proposed behaviour is.

Whether or not I can come up with a better proposal is irrelevant
to how sane the current behaviour is.
If you can't provide a superior alternative then you have little right
to be questioning the present behavior. Honestly, you are like a child
with a whistle who keeps blowing the whistle to the annoyance of all
around it simply because it likes being able to make the noise, and
causing the annoyance.
How many times do I have to repeat myself. I'm not proposing a change
to the language.
So you have a clear impression that Python's current behavior is
unsatisfactory enough to be called "unsane" which, when challenged, you
insist simply means not at the extreme end of some imaginary sanity
scale you have constructed for the purpose if bending English to your
will. And you refuse to propose anything further towards the sane end of
the scale because people will try to argue that your proposal would be
worse than the existing behavior. Good grief, I though I was dealing
with an adult here, but I must be mistaken.Well you are repeatedly call one aspect of the Python inheritance model
insane. You appear to feel that repetition of an argument will make it
more true, which is sadly not the case.
I haven't written that once. You may think that you can imply it from
what I wrote, but then that is your inferance and not my words.
Nonsense.
But you clearly don't perceive this as being related to Python's
inheritance mechanism, presumably because you aren't prepared to accept
that an instance inherits names from its class just like a class
inherits names from its superclass.
Well maybe English works differently from dutch, but I thought there
were a whole lot of gradation between sane and insane. And not being
sane IMO just means not being at one end of the extreme while being
insane meant to be at the other end of the extreme.

So when something doesn't make complete sense, instead of it making
no sense at all, I would think that wording it as unsane instead of
insane resembles best what I intended to mean.
Ah, so Python isn't the only language you find insufficiently
expressive. I normally give some leeway to those whose first language
isn't English, but this particular bloody-mindedness has gone on long
enough. I'd call your behavior imhelpful here.

So, are we talking about 0.1% insane, 10% insane or 90% insane. For
someone who is so pedantic you are being insanely vague here. You can
hardly blame people for concluding you just like the sound of your own
voice (metaphorically speaking).
I wasn't trolling. I just threw in an off hand remark. That you got so
heated up about that remark is not my responsibility. I'm not trolling
because I'm willing to defend my remark and I don't intend to get
people to get heated up about it. I just don't hold back because
people may get heated up about it.
The defense of your original remark implies very strongly that it wasn't
offhand, and that you are indeed trolling. Hence the reduction in the
frequency of my replies. You make it more and more difficult to take you
seriously. Particularly since you have now resorted to a defense which
involves refusing to define a non-existent word in any but the vaguest
terms - you are trying to specify a position on the imaginary continuum
of sanity, but you don't say how close to which end you are trying to
specify. This puts you somewhere between "barmy" and "crackpot" on my
own personal scale.
If I would be whining I would want the behaviour changed. I would just
keep complaining about it until someone else would have changed it.
Instead you just keep complaining about it, full stop. Since we are all
now fully aware of your opinions, couldn't you just shut up, or do we
have to send you to your room without any supper? Whine, whine, whine.
Sure I would prefer it changed, but it is not that I *want* it to
change. I'll happily continue with python if it doesn't change.
That's sort of a pity. At this stage I'd recommend Ruby just to be rid
of the incessant twaddle you come up with to defend your throwaway ideas.
Maybe when someone mentions something negative about python,
you shouldn't translate that into someone demanding a change
in python.




Well fine, in that case it won't even change if I do come up with
an alternative proposal. So why should I bother?
Absolutely no reason at all. It's already transparently obvious that you
don't have a better alternative and you continue to troll simply because
it validates your particular (and increasingly peculiar) needs.

Every time I reply to you my spell checker looks at your name and shows
me a dialog with an "ignore all" button on it. I have this increasing
suspicion that it's trying to tell me something.

regards
Steve
 
A

Antoon Pardon

Op 2005-11-07 said:
If you can't provide a superior alternative then you have little right
to be questioning the present behavior.

Nonesense. Unable to produce a superior alternative doesn't make
one unable to evaluate.
So you have a clear impression that Python's current behavior is
unsatisfactory enough to be called "unsane" which,

You are generalizing my words to the point they no longer
reasonably resemble what I wrote.
The defense of your original remark implies very strongly that it wasn't
offhand, and that you are indeed trolling. Hence the reduction in the
frequency of my replies. You make it more and more difficult to take you
seriously.

Fine that goes both ways. I don't mind not being taken serious by people
I have trouble taking serious my self. No doubt that goes for you too.

So I propose we don't react to each other any longer, since there
would be very little purpose in it.
Particularly since you have now resorted to a defense which
involves refusing to define a non-existent word in any but the vaguest
terms - you are trying to specify a position on the imaginary continuum
of sanity, but you don't say how close to which end you are trying to
specify. This puts you somewhere between "barmy" and "crackpot" on my
own personal scale.
Instead you just keep complaining about it, full stop.

No I don't keep complaining about. I just defend my claim.
Since we are all
now fully aware of your opinions, couldn't you just shut up, or do we
have to send you to your room without any supper? Whine, whine, whine.

Well since you are aware of my opinion, why don't you just ignore
any new articles of mine in this thread and go on, instead of whining
about the fact that I care to defend what I wrote but won't put
more fuel on the fire by starting my idea about superior behaviour
which would only make this thread live longer without any chance
of coming to a shared conclusion.
Every time I reply to you my spell checker looks at your name and shows
me a dialog with an "ignore all" button on it. I have this increasing
suspicion that it's trying to tell me something.

Well maybe you should listen to it. It seems damn obvious neither of
us has anything interresting to say to the other.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,019
Latest member
RoxannaSta

Latest Threads

Top