Re: OT: Another try at Python's selfishness
On Thu, 9 Feb 2006 10:35:37 +0100, rumours say that Frithiof Andreas Jensen [EMAIL PROTECTED] might have written: If one was trying to detect fanatics of any creed, a certain indicator would be that they have absolutely no sense of humour - they suffer from a yet-to-be-described variant of autism I.M.O. Although I generally agree, I've seen images of fanatics laughing madly when they employ their fanatism; so they might have some sense of humour, even if a perverted one (perverted relative to your or my sense of humour, obviously :) They tend to lack self-sarcasm, though. Anyway, someone wiser than me (probably so much wiser that I subconsciously forgot their name!) said: The difference between a saint and a fanatic is that the saint fights the evil inside him/herself... -- TZOTZIOY, I speak England very best. Dear Paul, please stop spamming us. The Corinthians -- http://mail.python.org/mailman/listinfo/python-list
OT: Another try at Python's selfishness
DH [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] Frithiof Andreas Jensen wrote: [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] Having read previous discussions on python-dev I think I'm not the only Python programmer who doesn't particularly like python's self parameter: Ok, there might be five programmers and one imam. The imam does not like anything more recent than 700 A.D ... You Danes and your Muslim jokes :) ;-) A culture thing, that: They are now accepted as part of society, so we treat them equally to the people from Århus, Copenhagen, West-Jutland, Sout-Jutland, Bornholm and Mols (a tiny area 30 km from Århus). If we did not care for them, we would not poke fun at them occasionally. So far, I think the integration has really improved a lot because this affair has clearly shown that the Danish muslims are pretty much like everyone else here. The ethnic kiosks still sell Jyllands Posten, the Danish still buy groceries in ethnic shops e.t.c. Like Normal. No riots, looting and threats from hooded cowards and bullies. What we instead have learned are that the Imams - some of which have been given asylum - are blatantly lying and falsifying evidence in order to slander the country that pay their social security when the very first opportunity arises. Maybe those people should not be here in the first place. We have also learned that there is no point in getting involved in dialogue, export grants (i.e. bribes) and foreign aid money (more bribes) with dictatorships and defunct states. The effort should be directed elsewhere, where it is actually any use. Finally we can take comfort in knowing that the lunatic segment in the population is clearly less than 1500 out of 5,000,000 people - although the loonies do get 80% of the media coverage (like f.ex. the 300 autonomen that just *had* to be the only violent segment in a media-hyped confrontational demo with 30(!) neo-nazis, 200 muslims and about half the Danish police force present in riot gear - Great Plan Einstein; ). The TeeVee news should be relabeled Fools Hour - their mantra seems to be that if you want the opinion of any large group, go seek out the village idiot and ask him. The conclusion is that the *real* threat to democracy does *not* come from the lunatic segment but from connected people with nice suits and vested interests such as the Danish Industri Association that are clearly willing to take in a used Sharia as part of a trade. They worked for Hitler too and has clearly learned nothing!! PS: If one was trying to detect fanatics of any creed, a certain indicator would be that they have absolutely no sense of humour - they suffer from a yet-to-be-described variant of autism I.M.O. -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
[EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] Having read previous discussions on python-dev I think I'm not the only Python programmer who doesn't particularly like python's self parameter: Ok, there might be five programmers and one imam. The imam does not like anything more recent than 700 A.D ... What do you think? Troll! -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
But the point is, the current situation is not newbie-friendly (I can tell, I am a newbie) I will agree to that, as I consider myself still new. _But_, it's a stumbling stone only briefly. Get enough nagging error messages, and you learn and move on. I agree with the grandparent poster that it is a perfect self-documenting thing, as the use of 'self' is pretty obvious. For a language that one can learn in a short time, this is a tempest in a teacup. I'm just trying to disown my several years of Perl. I like PHP too much and have no experience with Python in a CGI environment. So, I'm a little bit confused linguistically. ;-) -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
Frithiof Andreas Jensen wrote: [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] Having read previous discussions on python-dev I think I'm not the only Python programmer who doesn't particularly like python's self parameter: Ok, there might be five programmers and one imam. The imam does not like anything more recent than 700 A.D ... You Danes and your Muslim jokes :) -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
On 2006-02-08, Ben Wilson [EMAIL PROTECTED] wrote: But the point is, the current situation is not newbie-friendly (I can tell, I am a newbie) I will agree to that, as I consider myself still new. _But_, it's a stumbling stone only briefly. Get enough nagging error messages, and you learn and move on. I agree with the grandparent poster that it is a perfect self-documenting thing, as the use of 'self' is pretty obvious. For a language that one can learn in a short time, this is a tempest in a teacup. This old C hound finds it much more sensible than C++ or Java, where the self parameter (called this) is implicit rather than explicit and you just sorta kinda hafta know it's there and the correct syntax to use to reference it. Then there's all the places where you need a Secret Decoder Ring--in Java you have to define the equivalents of stdout and stdin as they aren't provided. In c++ you can't overload the operator in your class, you have to use a friend function and you have to return an ostream--the Rule of Three for constructors, and just generally lots of small knotty issues to bite beginners. 9 times out of 10, Python Just Works the first time and things do what your mind says they should without having to learn a seventeen special cases to everything. IMO, YMMV, Not Valid in Vermont, Happy Fun Ball may accellerate to dangerous speeds. Do NOT taunt Happy Fun Ball. -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
On 04 Feb 2006 11:03:00 + [EMAIL PROTECTED] (Jens Theisen) wrote: n.estner wrote: Yes, I 100% agree to that point! But the point is, the current situation is not newbie-friendly (I can tell, I am a newbie): I declare a method with 3 parameters but when I call it I only pass 2 parameters. That's confusing. If I declare a member variable, I write: self.x = ValueForX, why can't I be equally explicit for declaring member functions? For someone new to OO in general it might as well be something good, so he realises that there actually really is a hidden parameter. After all, there is something to understand with self, and this discrapency between the number of arguments and parameters puts newbies to it. Yes. I have to say that I learned OOP at the same time as Python (I made attempts with C++ that were moderately successful, but beyond implementing new math objects, I couldn't really see the benefit OOP then. I didn't get it until I started using Python). So, the idea of the object itself is the first argument to the function made it implicitly clear to me what the heck was this whole business about methods. I found the Python approach is very enlightening. By contrast, Javascript seems positively obtuse. First, the equivalent to self is a magically-appearing variable called this. But to make matters worse, this behavior is repeated in many places -- you have to know when and where magical variables like this and prototype appear, and it's not at all obvious when reading other people's code. (I suppose a formal introduction to Javascript would explain these things -- but I note that many online how to type documents skip them, partly because OOP is not very popular with most casual Javascripters). I tend to think of Javascript as almost Python, but stupidly designed, because of stuff like this. My apologies to Javascript fans, I acknowledge that my opinion is subjective. ;-) Cheers, Terry -- Terry Hancock ([EMAIL PROTECTED]) Anansi Spaceworks http://www.AnansiSpaceworks.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
Jean-Paul Calderone [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] I'm not sure I follow. Surely you're not suggesting that this doesn't work: class X: ... def foo(self): ... print 'X.foo', self ... class A(X): ... pass ... o = A() A.foo(o) X.foo __main__.A instance at 0xb7cab64c Either things have changed or I was misinformed and neglected to verify ;-( -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
n.estner wrote: Yes, I 100% agree to that point! But the point is, the current situation is not newbie-friendly (I can tell, I am a newbie): I declare a method with 3 parameters but when I call it I only pass 2 parameters. That's confusing. If I declare a member variable, I write: self.x = ValueForX, why can't I be equally explicit for declaring member functions? For someone new to OO in general it might as well be something good, so he realises that there actually really is a hidden parameter. After all, there is something to understand with self, and this discrapency between the number of arguments and parameters puts newbies to it. Jens -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
Donn Cave wrote: Quoth [EMAIL PROTECTED]: | Still see no problem. Of course, it goes without saying that | Python 2.4 doesn't work this way, but given that it's theoretically | possible for f(a) to be resolved similarly to a.f, then I really | do not see what you're seeing here. The kwargs parameter appears | irrelevant from where I'm sitting. | | Then either you didn't understand my answers, or I didn't understand | your idea. Could you summarize how exactly f(x,y=z) should be | resolved, i.e. where it should look for f? a.f == f(a) So, if the compiler recognizes the tokens a.f, it should treat them as if it found the tokens f(a). But that wouldn't do what you want. You want it to do something different if it found the tokens f(a). I would agree that I didn't understand your answers, but they weren't really answers so much as questions, along the lines of ``well then, how would this work?'' I seem to have missed what you were driving at, but maybe if you were to just came out and explain the point? You do know what a rethorical question is? The first point is: Python has global functions, as well as methods. If f(a) should look up f inside a first, that would shadow any global or local f. That's bad, because python is dynamically typed, and you sometimes down' know what a is. Things like open(filename) or tuple(a,b,c) could behave completely unexpected, if filename had an open or a a tuple attribute. The other point is: Python supports named arguments. The algorithm to put positional and named arguments into the right parameters is rather tricky, and it _must_ know the function that's being called to work. So, you simply can't make function lookup depend on the parameters, it's a hen-egg problem. Of course the whole business is kind of a joke, since there is no way anyone in their right mind would wish to change Python's notation for such trivial reasons, but there actually are languages that resolve functions based on argument types. Overloading in C++ is somewhat like this, Haskell's typeclass mechanism, and there is a ``multiple dispatch'' model that I have no experience with but is not without its supporters. Yes, but both C++ and Haskell are statically typed, and neither supports named arguments. (We're talking about one function operating on one object, so I don't see what multiple dispatch has to do with this) -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
Quoth [EMAIL PROTECTED]: ... | The first point is: Python has global functions, as well as methods. If | f(a) should look up f inside a first, that would shadow any global or | local f. That's bad, because python is dynamically typed, and you | sometimes down' know what a is. Things like open(filename) or | tuple(a,b,c) could behave completely unexpected, if filename had an | open or a a tuple attribute. Well, of course we have to assume as part of the proposal that it would documented and actually would be expected, to the extent that one is entitled to expect anything in Python. It seems to me that if you bring an even slightly open mind to the question, when we apply open to an object that supports open with its own function, what could be more appropriate than to call that function? I will allow that there is some potential for problems here, but there may be ways to finesse them. Haven't thought real hard about it. | The other point is: Python supports named arguments. The algorithm to | put positional and named arguments into the right parameters is rather | tricky, and it _must_ know the function that's being called to work. | So, you simply can't make function lookup depend on the parameters, | it's a hen-egg problem. Ah. I see no reason this system needs to support a named first parameter, though, so I suppose a function application like f(a=x,...) would be exempt from parameter lookup. This seems like an implementation detail. | Of course the whole business is kind of a joke, since there is no way | anyone in their right mind would wish to change Python's notation for | such trivial reasons, but there actually are languages that resolve | functions based on argument types. Overloading in C++ is somewhat | like this, Haskell's typeclass mechanism, and there is a ``multiple | dispatch'' model that I have no experience with but is not without its | supporters. | | Yes, but both C++ and Haskell are statically typed, and neither | supports named arguments. | (We're talking about one function operating on one object, so I don't | see what multiple dispatch has to do with this) Come on, you know that in the unlikely event this idea were to be seriously considered, someone would be hot to extend it to multiple objects before it even got implemented on one, but in any case, single dispatch sounds like just a restricted case of multiple dispatch, so if the latter is feasible, so is the former. I've heard talk about a form of static typing for Python, and obviously that has the potential to considerably enhance the possibilities in this area. Donn Cave, [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
Terry Hancock [EMAIL PROTECTED] wrote: On Thu, 02 Feb 2006 19:27:55 -0600 DH [EMAIL PROTECTED] wrote: But I think most people who don't like the extraneous 'self' in python just consider it a minor inconvenience and don't even notice it after using python for a while. After messing around with Javascript (many magical variables that suddenly show up in your namespaces!), I began to *seriously* appreciate Python's design. Having self as an explicit parameter is beautiful self-documenting design. I have to agree... Here is my experience with the same idea in C++... I've converted lots of C code written in an object oriented style into C++. In C you pass round a pointer to a struct, which gets transformed into the new class on conversion. Typically the code is then full of this-member = that, etc. This is the python equivalent of self.member = that. At this point I usually remove all the this- from the code which then causes it to malfunction horribly at run-time (it compiles fine) because of all the name space clashes between the things in the class and the local variables. The compiler doesn't warn about this - its perfectly legal C++. In a lot of big C++ programs various conventions are used to try to help with this - naming all parameters to functions _name rather than name, or using this-member rather than member. The python way of enforcing self.member is much cleaner and never comes back to bite you! -- Nick Craig-Wood [EMAIL PROTECTED] -- http://www.craig-wood.com/nick -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
[EMAIL PROTECTED] wrote: What do you think? The impression I get from your suggestion is that you haven't really understood Python. I'm sure that some things could be better designed or better documented, but your suggestions would actually make things worse. Sorry. Today, Python has a syntactic shortcut. If 'a' is an instance of class 'A', a.f(x,y,z) is a shortcut for A.f(a,x,y,z). If you don't use the shortcut, there is no magic at all, just the unusual occurence of a type check in Python! If you use the shortcut, Python code looks just like most other OO languages. This isn't very magical. What you suggest doesn't remove magic, but it introduces a bunch of inconsistencies! But: Foo.__dict[bar]__(1,2,3) Does work. I agree that this isn't completely clean, and there are some other ways in which the distinction between functions, unbound methods and bound methods seem a bit quirky to me. I don't think the problem is in the syntax though, and if it had been a real problem, it would had been solved. class Foo: def self.bar(a,b): return a+b Foo().bar(1,2) = 3 First of all, you are using a really poor example of a method, since it doesn't use any attributes of the Foo instance. That function doesn't seem to belong in that class at all. If it should be in the class, it should be a static method, so self should not be involved at all. In modern Python it would look like this: class Foo(object): @staticmethod def bar(a, b): return a+b Anyway, my impression is that you haven't fully understood how namespaces work in Python, at least not the distinction between class namespaces and instance namespaces. Please study this a bit more. Hopefully, you'll find enlightenment and things will fall into place for you. You are really giving self a magic meaning with your suggestion which isn't needed at all. So far, the existence of x.y somewhere in Python always implied that x was already introduced explicitly in the program, and you suggest that we violate that both in the def self.x-row, and inside the methods when we access attributes. Provoking a language can be a way of learning it, and provoking people can sometimes lead to new insights, but it's important to have an open mind. When learning a new language, it's probably better to try to adapt oneself to it, rather than the other way around. -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
That usage (self is second parameter to B.test) is bound to cause trouble in general, but in this case doesn't have any effect I can see. The function call test would be resolved from its first parameter, instance of A, and that function would return 1. One of us is missing something here, could be me. Probably my example wasn't clear, let's try another: class A: def test(a, **kwargs): return 1 class B: def test(b, **kwargs): return 2 test(a=A(), b=B()) self isn't a keyword, so nothing should forbid this code. What is the interpreter to do if it stumbles across this test call? I mean, named-argument lookup is a tricky thing even if you do know what function you're calling. If this would depend on one of the parameters, I think it would become completely unintelligible. (you can think of more complex examples yourself) That's exactly the problem, it doesn't read from left to right, because we swap back and forth between function(parameter and parameter.function notation. That's because they're doing two different things: object.method() does an attribute lookup, while function(parameter) looks for the function in the current scope. -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
Yes, that's what I had in mind when I said it could be made recursion-safe. It's still not thread-safe, but I think that could be done too, using thread-local-variables instead of globals. class TestB: @memberFunction def do(x): z = __ # lambda's shouldn't directly reference '__' x.do(lambda : z) Yes, that's what I meant when I said it wasn't lambda-safe. That means a completely legal and (in my code) common expression can behave totally unexpected. Would be a no-go for me. But I think it gets worse: class TestA: @memberFunction def do(): yield 1 yield 2 yield __ class TestB: @memberFunction def bar(): for x in TestA().do(): print x TestB().bar() Doesn't behave as expected, and the only way I can see to fix it would be to declare a local function inside TestA's do function... -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
On Fri, 03 Feb 2006 12:00:52 +0100, Magnus Lycka wrote: Today, Python has a syntactic shortcut. If 'a' is an instance of class 'A', a.f(x,y,z) is a shortcut for A.f(a,x,y,z). It is easy to work around (break?) that behaviour: class A(object): def foo(self): print normal method foo a = A() def foo(self): print special method foo from new import instancemethod a.foo = instancemethod(foo, a) Now we can see that a.foo() is no longer a shortcut for A.foo(a): a.foo() special method foo A.foo(a) normal method foo So instances can have methods that they don't inherit from their class! -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
First of all, you are using a really poor example of a method, since it doesn't use any attributes of the Foo instance. Agreed. I tried to post a short example, and it obviously was to short to make my point clear. lets take a longer one. Current syntax: class Pair: def __init__(self, a,b): self.a = a self.b = b def sum(self): return self.a + self.b def product (this): return this.a + this.b My alternative syntax suggestion would be this one: class Pair: def self.__init__(a,b): self.a = a self.b = b def self.sum(): return self.a + self.b def this.product (): return this.a + this.b You are really giving self a magic meaning with your suggestion which isn't needed at all. No. I hope this is clearer in the example above. self shouldn't be a keyword. It's a special kind of argument now, so why shouldn't we explicitly _declare_ that it's a special kind of argument? (as explicit is better than implicit) So far, the existence of x.y somewhere in Python always implied that x was already introduced explicitly in the program, Yes, but y(x) also implies that x and y have been introduced explicitly before, unless it's in a def statement. The def statement always introduces new variables. and you suggest that we violate that both in the def self.x-row, and inside the methods when we access attributes. def x(self): declares two new identifiers, x and self Why shouldn't def self.x(): declare two new identifiers (x and self), too? Attribute acces wouldn't change. -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
I still see newbie-friendliness as a MAJOR plus for Python -- it increases the chance that users of your software will become contributors. Yes, I 100% agree to that point! But the point is, the current situation is not newbie-friendly (I can tell, I am a newbie): I declare a method with 3 parameters but when I call it I only pass 2 parameters. That's confusing. If I declare a member variable, I write: self.x = ValueForX, why can't I be equally explicit for declaring member functions? -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
On Fri, 03 Feb 2006 03:23:00 -0800, n.estner wrote: That usage (self is second parameter to B.test) is bound to cause trouble in general, but in this case doesn't have any effect I can see. The function call test would be resolved from its first parameter, instance of A, and that function would return 1. One of us is missing something here, could be me. Probably my example wasn't clear, let's try another: class A: def test(a, **kwargs): return 1 class B: def test(b, **kwargs): return 2 test(a=A(), b=B()) self isn't a keyword, so nothing should forbid this code. What is the interpreter to do if it stumbles across this test call? You could try running it to see: class A: ... def test(a, **kwargs): return 1 ... class B: ... def test(b, **kwargs): return 2 ... test(a=A(), b=B()) Traceback (most recent call last): File stdin, line 1, in ? NameError: name 'test' is not defined Oops! You have defined a name test in two namespaces, the class A and the class B, but there is no name test in the global namespace you are trying to run it in. Since namespaces are critical to Python, your test code is a problem that just cannot happen in Python. It is a non-issue. Python will not get confused between the two definitions of test. I mean, named-argument lookup is a tricky thing even if you do know what function you're calling. If this would depend on one of the parameters, I think it would become completely unintelligible. (you can think of more complex examples yourself) That's exactly the problem, it doesn't read from left to right, because we swap back and forth between function(parameter and parameter.function notation. That's because they're doing two different things: object.method() does an attribute lookup, while function(parameter) looks for the function in the current scope. No, function(parameter) does not look for a function. It looks for any object at all, and then tries to call it. Both calls do almost the same thing. object.method() looks up the name method in the object namespace, function(parameter) looks up the name function in the current namespace. Neither method nor function must be methods or functions, although if they are not callable objects, calling them will raise an exception. But regardless of what sort of objects they are, the look up proceeds in the same fashion. Unless you understand namespaces, you don't understand Python, and any criticism is likely to be due to misunderstanding. As near as I can tell, your original complaint might be solved simply: it seems to me that you are concerned about that extraneous self parameter for methods that don't need it: class Foo: def bar(self, a,b): return a+b Foo().bar(1,2) = 3 If bar doesn't need the instance or class Foo, perhaps it would be better off as an ordinary function rather than bound to a class. But if bar does need to be a method, perhaps you want something like this: # for Python 2.2 and up class Foo: def bar(a,b): return a+b bar = staticmethod(bar) # for Python 2.4 and up class Foo: @staticmethod def bar(a,b): return a+b Foo().bar(1,2) works exactly the same as before, but your definition of bar doesn't need that extraneous self parameter. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
You could try running it to see: class A: ... def test(a, **kwargs): return 1 ... class B: ... def test(b, **kwargs): return 2 ... test(a=A(), b=B()) Traceback (most recent call last): File stdin, line 1, in ? NameError: name 'test' is not defined Oops! You have defined a name test in two namespaces, the class A and the class B, but there is no name test in the global namespace you are trying to run it in. Since namespaces are critical to Python, your test code is a problem that just cannot happen in Python. It is a non-issue. Python will not get confused between the two definitions of test. I've been answering to Donn Cave's suggestion. Read it, and you will understand what I mean. As near as I can tell, your original complaint might be solved simply: it seems to me that you are concerned about that extraneous self parameter for methods that don't need it: No, I wasn't talking about functions that don't use the self parameter. I rarely ever have such functions. I just tried to make the example as short as possible. -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
Op 2006-02-03, [EMAIL PROTECTED] schreef [EMAIL PROTECTED]: First of all, you are using a really poor example of a method, since it doesn't use any attributes of the Foo instance. Agreed. I tried to post a short example, and it obviously was to short to make my point clear. lets take a longer one. Current syntax: class Pair: def __init__(self, a,b): self.a = a self.b = b def sum(self): return self.a + self.b def product (this): return this.a + this.b My alternative syntax suggestion would be this one: class Pair: def self.__init__(a,b): self.a = a self.b = b def self.sum(): return self.a + self.b def this.product (): return this.a + this.b You are really giving self a magic meaning with your suggestion which isn't needed at all. No. I hope this is clearer in the example above. self shouldn't be a keyword. It's a special kind of argument now, so why shouldn't we explicitly _declare_ that it's a special kind of argument? (as explicit is better than implicit) Self is not a special kind of argument. It is the accessing of the method that provides for the magic. Simplified one could say the following is happening. def _Pair__init__(self, a, b): self.a = a self.b = b def _Pair_sum(self): return self.a + self.b def _Pair_product(this): return this.a * this.be class Pair: def __init__(self, ...): self.__init__ = BoundMethod(self, _Pair__init__) self.sum = BoundMethod(self, _Pair_sum) self.product = BoundMethod(self, _Pair_product) self.__init__(...) So when p is an instance of Pair, p.sum is not your defined function but a BoundMethod. -- Antoon Pardon -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
On Fri, 03 Feb 2006 03:51:03 -0800, n.estner wrote: My alternative syntax suggestion would be this one: class Pair: def self.__init__(a,b): self.a = a self.b = b def self.sum(): return self.a + self.b def this.product (): return this.a + this.b This would be a fairly major change to Python, so I think we can say right up front that the chances of this happening before Python 3 are zero, and even in Python 3 the chances are about the same as the chances of Richard Stallman suddenly announcing that he's taken a job for Microsoft writing Digital Restrictions Management software. But still, let's continue. After all, all you have to do is convince Guido that this syntax is better... You are really giving self a magic meaning with your suggestion which isn't needed at all. No. I hope this is clearer in the example above. self shouldn't be a keyword. Which it isn't now either. It's a special kind of argument now, so why shouldn't we explicitly _declare_ that it's a special kind of argument? (as explicit is better than implicit) And a foolish consistency is the hobgoblin of little minds *wink* [snip] def x(self): declares two new identifiers, x and self Why shouldn't def self.x(): declare two new identifiers (x and self), too? Sure, but now the call foo.bar has special meaning inside a def statement than elsewhere. Elsewhere, foo.bar is an attribute access, looking up attribute bar in foo's namespace. Using your syntax, in a def statement foo.bar is a pair of declarations: it declares a name foo, and it declares a second name bar. This inconsistency is, I think, worse than the implicit use of self. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
On Fri, 03 Feb 2006 03:59:10 -0800, n.estner wrote: I still see newbie-friendliness as a MAJOR plus for Python -- it increases the chance that users of your software will become contributors. Yes, I 100% agree to that point! But the point is, the current situation is not newbie-friendly (I can tell, I am a newbie): I declare a method with 3 parameters but when I call it I only pass 2 parameters. That's confusing. Yes, I understand what you mean now. When I was a newbie, it took me a little while to get the difference between ordinary functions and methods too, although I had little OO experience before Python. I don't know if that helped or hindered the learning experience. With the current syntax, you have to learn some special behaviour: class Foo: def bar(self, x, y): pass but you call Foo().bar(x, y) But with your syntax, you still have to learn special behaviour: # outside the class definition self.bar # look up bar in self's namespace. self must already exist. # inside a class definition class Foo: self = Something() # normal class attribute self created # this works because self is not a keyword # Foo now has an attribute self def self.bar(x, y): # create a method bar with self in bar's namespace # Foo now has an attribute bar (which is a method) pass self.bar = None # normal attribute access # Foo attribute self is modified to have an attribute bar # there is no conflict between self the attribute and self the # special parameter because they live in different namespaces # but looking at them, there is an apparent conflict So, most of the time, foo.bar looks up attribute bar in foo; but in a method definition, foo.bar assigns attribute foo in bar. That's special behaviour too, and it seems to me probably harder to live with and even more confusing than the behaviour you aim to remove. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
[EMAIL PROTECTED] wrote: The main reason (at least for me) is that there's simply too much magic in it. Why does the expression left of the '.' get promoted to the first parameter? One of the reasons I like Lua is because it doesn't do this, instead using the : operator to designate method-style calls. eg. a:foo(b, c) -- looks up foo within a, and calls it with (a, b, c) as parameters a.foo(b, c) -- looks up foo within a, and calls it with (b,c) as parameters This means there doesn't need to be a distinction between methods and functions, just a different operator to treat a function as if it was a method. When I started out in Python I figured that I could just assign functions to objects and treat them then as if they were methods, as I would in Lua, but quickly learned that it wasn't that simple. -- Ben Sizer -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
Op 2006-02-03, Ben Sizer schreef [EMAIL PROTECTED]: [EMAIL PROTECTED] wrote: The main reason (at least for me) is that there's simply too much magic in it. Why does the expression left of the '.' get promoted to the first parameter? One of the reasons I like Lua is because it doesn't do this, instead using the : operator to designate method-style calls. eg. a:foo(b, c) -- looks up foo within a, and calls it with (a, b, c) as parameters a.foo(b, c) -- looks up foo within a, and calls it with (b,c) as parameters This means there doesn't need to be a distinction between methods and functions, just a different operator to treat a function as if it was a method. That is nice. I wonder if the following is possible in Lua: fun = a:foo fun(b, c) with the same effect as: a:foo(b, c) -- Antoon Pardon -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
[EMAIL PROTECTED] wrote: Having read previous discussions on python-dev I think I'm not the only Python programmer who doesn't particularly like python's self parameter: bang ! You're dead ! (no no, just kidding !-) class Foo: old-style classes are deprecated. class Foo(object): def bar(self, a,b): return a+b (snip) The point is, I _do_ think it's a good idea to explicitly write self.SomeMember for member-access, With Python's lookup rules, it couldn't be otherwise anyway !-) so I thought: why can't we be equally explicit about member function declaration? Because there's no such thing as a member function in Python. Wouldn't it be nice if I could write (say, in Python 3k, or maybe later): class Foo: def self.bar(a,b): return a+b Foo().bar(1,2) = 3 'bar' is not an instance attribute, but a class attribute - it belongs to *class* Foo, not to an instance of Foo. BTW, 'self' does not yet exist (and cannot possibly exist) when this code is eval'd (how could an instance of class Foo exists before class Foo itself exists ?). That way, the declaration would match the invocation (at least syntactically), and the magic-feeling is gone. In the long run, the old-style syntax (i.e. if there's no '.' in the method name) could be used for static methods. s/static/class/ What do you think? That you should learn more about the inners of Python's object model (and specially at the Descriptor protocol). class Foo(object): def __init__(self, a): self.a = a def bar(obj, b): return obj.a + b f = Foo(1) bar(f, 2) Foo.bar = bar Foo.bar(f, 2) f.bar(2) The only 'magic' here is that when bar() is called *as an attribute of a Foo instance*, the instance is passed as the first parameter. In fact, this is much more explicit (well, IMHO) than the 'this' reference in Java or C++. -- bruno desthuilliers python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')]) -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
Magnus Lycka [EMAIL PROTECTED] wrote: ... which isn't needed at all. So far, the existence of x.y somewhere in Python always implied that x was already introduced explicitly in the program, and you suggest that we violate that both in the Almost... import (and from) statements are exceptions to this. import x.y binds or rebinds name x on the fly, as well as attribute y of x. Alex -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
Steven D'Aprano [EMAIL PROTECTED] wrote: ... Why shouldn't def self.x(): declare two new identifiers (x and self), too? Sure, but now the call foo.bar call? has special meaning inside a def statement than elsewhere. Elsewhere, foo.bar is an attribute access, looking up attribute bar in foo's namespace. or setting it, as in foo.bar=23, or setting both names, as in import foo.bar Using your syntax, in a def statement foo.bar is a pair of declarations: it declares a name foo, and it declares a second name bar. declares isn't really pythonic -- let's talk about binding or setting names, instead. This inconsistency is, I think, worse than the implicit use of self. I don't think there's any inconsistency in deciding that syntax x.y has different meanings (as to what gets looked up or bound) in different contexts, because it already does: mostly look up y in namespace x, but in x.y=... it's bind y in namespace x and in import x.y it's bind x AND then bind y in namespace y. Since def x.y(... is currently a syntax error, it would introduce no backwards compatibility to assign a meaning to it. Since the 'def' statement binds something to the name that follows it (which currently must be a plain identifier), that's what it should do if it allowed the following name to be a compound one, too. Unfortunately, none of this suggests that it's reasonable to have def x.y(z): ... mean the same as def y(x, z): ... and I have no idea of how it would generalize to def x.y.z(t): ... (while import x.y.z generalizes in a pretty obvious way wrt import x.y). So, I'm not supporting the OP's idea; just rejecting the specific objections to it. Alex -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
On Fri, 03 Feb 2006 07:40:38 -0800, Alex Martelli wrote: Steven D'Aprano [EMAIL PROTECTED] wrote: ... Why shouldn't def self.x(): declare two new identifiers (x and self), too? Sure, but now the call foo.bar call? Call? Who said anything about a call? *wink* Okay, poor choice of words. I'm not exactly sure what a better choice would be. Token? Too specific. Maybe it would have been better to just have just said ...but now foo.bar has has special meaning inside a def statement than elsewhere. Elsewhere, foo.bar is an attribute access, looking up attribute bar in foo's namespace. or setting it, as in foo.bar=23, Conceptually, both setting and getting an attribute involves a look up in the general sense: you need to look up the attribute to get its value, or to find out where to put its value. You are correct (of course!) that foo.bar can either be a get or a set, but I'm doing lots of hand-waving here and I didn't think it was necessary to get bogged down in too much detail. or setting both names, as in import foo.bar Ah, I completely forgot about import. But see below. Using your syntax, in a def statement foo.bar is a pair of declarations: it declares a name foo, and it declares a second name bar. declares isn't really pythonic -- let's talk about binding or setting names, instead. Yes, you're right, it is a bad habit. Years of Pascal don't die easily. This inconsistency is, I think, worse than the implicit use of self. I don't think there's any inconsistency in deciding that syntax x.y has different meanings (as to what gets looked up or bound) in different contexts, because it already does: mostly look up y in namespace x, but in x.y=... it's bind y in namespace x Which from my perspective are conceptually two sides of the coin. The model I have is y is a label in some namespace x, and you have to (in some sense) look up where y should go regardless of whether you are setting the value or getting the value. Do you think this model is so far from the actual behaviour of Python that it is useless? Or is it fair to lump getting and setting attributes/names together? and in import x.y it's bind x AND then bind y in namespace y. I assume that's a typo and you mean bind y in namespace x. But even import x.y is conceptually a lookup, equivalent to x.y = __import__(x.y), with the understanding that x = __import__(x) is automagically run first. [hand-waving, hand-waving, hand-waving... of course imports do a lot more than just setting a name in a namespace] But in all three of: foo.bar = something something = foo.bar import foo.bar the hierarchy goes from left to right, with bar being inside foo, for some meaning of inside. The Original Poster's syntax would reverse that, with def foo.bar(x,y) creating parameter foo inside method bar. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
... Unfortunately, none of this suggests that it's reasonable to have def x.y(z): ... mean the same as def y(x, z): ... Actually, it shouldn't. The idea was, that def x.y(z): ... (explicitly) introduces an unbound method. That's not introducing a new conect to python, it's just making the difference between an unbound method and a not-bindable function explicit. Currently, def(x,y): ... can mean two different things: In the context of a class, it introduces an unbound method, in global or local contexts it introduces a function. I don't want to have a new syntax for that, I want two different syntaxes for these two different meanings. and I have no idea of how it would generalize to def x.y.z(t): ... Nor do I. Is that a problem? -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
On 3 Feb 2006 08:58:56 -0800, [EMAIL PROTECTED] wrote: ... Unfortunately, none of this suggests that it's reasonable to have def x.y(z): ... mean the same as def y(x, z): ... Actually, it shouldn't. The idea was, that def x.y(z): ... (explicitly) introduces an unbound method. That's not introducing a new conect to python, it's just making the difference between an unbound method and a not-bindable function explicit. Currently, def(x,y): ... can mean two different things: In the context of a class, it introduces an unbound method, in global or local contexts it introduces a function. I don't want to have a new syntax for that, I want two different syntaxes for these two different meanings. Are you sure you actually understand what's going on? Python 2.4.2 (#2, Sep 30 2005, 21:19:01) [GCC 4.0.2 20050808 (prerelease) (Ubuntu 4.0.1-4ubuntu8)] on linux2 Type help, copyright, credits or license for more information. def foo(): pass ... print type(foo) type 'function' class bar: ... def foo(self): pass ... print type(foo) ... type 'function' print type(bar.foo) type 'instancemethod' Jean-Paul -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
In article [EMAIL PROTECTED], [EMAIL PROTECTED] wrote: That usage (self is second parameter to B.test) is bound to cause trouble in general, but in this case doesn't have any effect I can see. The function call test would be resolved from its first parameter, instance of A, and that function would return 1. One of us is missing something here, could be me. Probably my example wasn't clear, let's try another: class A: def test(a, **kwargs): return 1 class B: def test(b, **kwargs): return 2 test(a=A(), b=B()) self isn't a keyword, so nothing should forbid this code. What is the interpreter to do if it stumbles across this test call? I mean, named-argument lookup is a tricky thing even if you do know what function you're calling. If this would depend on one of the parameters, I think it would become completely unintelligible. (you can think of more complex examples yourself) Still see no problem. Of course, it goes without saying that Python 2.4 doesn't work this way, but given that it's theoretically possible for f(a) to be resolved similarly to a.f, then I really do not see what you're seeing here. The kwargs parameter appears irrelevant from where I'm sitting. That's exactly the problem, it doesn't read from left to right, because we swap back and forth between function(parameter and parameter.function notation. That's because they're doing two different things: object.method() does an attribute lookup, while function(parameter) looks for the function in the current scope. But current scope is actually a compound lookup - function scope, global scope etc. Generalize it to object scope, and then you can have a notation that expresses these things consistently - QED. Donn Cave, [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
Magnus Lycka [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] [EMAIL PROTECTED] wrote: Today, Python has a syntactic shortcut. If 'a' is an instance of class 'A', a.f(x,y,z) is a shortcut for A.f(a,x,y,z). If you don't use the shortcut, there is no magic at all, just the unusual occurence of a type check in Python! As was once pointed out to me some years ago, when I wrote something similar, a.f() is not just a shortcut for A.f(a) [a.__class__.f(a)]. The latter only looks for f in the class A namespace while the former also looks in superclass namespaces. The 'magical' part of accessing functions via instances is the implementation of dynamic inheritance. Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
On Fri, 3 Feb 2006 15:27:51 -0500, Terry Reedy [EMAIL PROTECTED] wrote: Magnus Lycka [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] [EMAIL PROTECTED] wrote: Today, Python has a syntactic shortcut. If 'a' is an instance of class 'A', a.f(x,y,z) is a shortcut for A.f(a,x,y,z). If you don't use the shortcut, there is no magic at all, just the unusual occurence of a type check in Python! As was once pointed out to me some years ago, when I wrote something similar, a.f() is not just a shortcut for A.f(a) [a.__class__.f(a)]. The latter only looks for f in the class A namespace while the former also looks in superclass namespaces. The 'magical' part of accessing functions via instances is the implementation of dynamic inheritance. I'm not sure I follow. Surely you're not suggesting that this doesn't work: class X: ... def foo(self): ... print 'X.foo', self ... class A(X): ... pass ... o = A() A.foo(o) X.foo __main__.A instance at 0xb7cab64c But I can't think what else you might mean. Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
Still see no problem. Of course, it goes without saying that Python 2.4 doesn't work this way, but given that it's theoretically possible for f(a) to be resolved similarly to a.f, then I really do not see what you're seeing here. The kwargs parameter appears irrelevant from where I'm sitting. Then either you didn't understand my answers, or I didn't understand your idea. Could you summarize how exactly f(x,y=z) should be resolved, i.e. where it should look for f? -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
Steven D'Aprano [EMAIL PROTECTED] wrote: ... would be. Token? Too specific. Maybe it would have been better to just have just said ...but now foo.bar has Agreed. model I have is y is a label in some namespace x, and you have to (in some sense) look up where y should go regardless of whether you are setting the value or getting the value. Do you think this model is so far from the actual behaviour of Python that it is useless? Or is it fair to lump getting and setting attributes/names together? I think it's reasonable: Python does first check if type(x).y is an overriding descriptor (==one with a __set__ method), at least in the mainstream case (oldstyle classic are weird;-). and in import x.y it's bind x AND then bind y in namespace y. I assume that's a typo and you mean bind y in namespace x. Yep. Differently from the other bots (tim and /f), I'm programmed to randomly make errors once in a while -- makes it easier to pass the Turing test (many people mistakenly think I'm human, since to err is human, while nobody would think THAT of impeccabile timbot and effbot). But even import x.y is conceptually a lookup, equivalent to x.y = __import__(x.y), with the understanding that x = __import__(x) is automagically run first. [hand-waving, hand-waving, hand-waving... of course imports do a lot more than just setting a name in a namespace] Of course, but so do some other statements that ALSO bind a name (in the current namespace only, in today's Python), such as class and def. We're just focusing on the binding part;-). But in all three of: foo.bar = something something = foo.bar import foo.bar the hierarchy goes from left to right, with bar being inside foo, for some meaning of inside. The Original Poster's syntax would reverse that, with def foo.bar(x,y) creating parameter foo inside method bar. True. Of course, the OP might argue that if x.f() can CALL f(x) [placing x ``inside'' f], it's fair that a def of a composite name should also ``swap insideness and outsideness'' similarly. But, as I said, I'm not supporting the OP's idea; just rejecting the specific objections to it. For once, I have a hard time articulating exactly why I'd dislike such semantics for hypothetic syntax def x.y, besides minor points such as the difficulties wrt generalizing to def x.y.z... but I do know which objections are NOT the ones which make me feel such dislike!-) Alex -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
[EMAIL PROTECTED] wrote: ... your idea. Could you summarize how exactly f(x,y=z) should be resolved, i.e. where it should look for f? Lexically: local scope, outer functions outwards, globals, builtins. Alex -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
Terry Reedy [EMAIL PROTECTED] wrote: ... As was once pointed out to me some years ago, when I wrote something similar, a.f() is not just a shortcut for A.f(a) [a.__class__.f(a)]. The latter only looks for f in the class A namespace while the former also looks in superclass namespaces. Nope: class B: ... def f(self): print 'b.f' ... class A(B): pass ... a=A() a.__class__.f(a) b.f Inheritance applies in any lookup of an attribute in a class, just as well as on an instance of the class. Alex -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
Quoth [EMAIL PROTECTED]: | Still see no problem. Of course, it goes without saying that | Python 2.4 doesn't work this way, but given that it's theoretically | possible for f(a) to be resolved similarly to a.f, then I really | do not see what you're seeing here. The kwargs parameter appears | irrelevant from where I'm sitting. | | Then either you didn't understand my answers, or I didn't understand | your idea. Could you summarize how exactly f(x,y=z) should be | resolved, i.e. where it should look for f? a.f == f(a) I would agree that I didn't understand your answers, but they weren't really answers so much as questions, along the lines of ``well then, how would this work?'' I seem to have missed what you were driving at, but maybe if you were to just came out and explain the point? Of course the whole business is kind of a joke, since there is no way anyone in their right mind would wish to change Python's notation for such trivial reasons, but there actually are languages that resolve functions based on argument types. Overloading in C++ is somewhat like this, Haskell's typeclass mechanism, and there is a ``multiple dispatch'' model that I have no experience with but is not without its supporters. Donn Cave, [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Another try at Python's selfishness
Having read previous discussions on python-dev I think I'm not the only Python programmer who doesn't particularly like python's self parameter: class Foo: def bar(self, a,b): return a+b Foo().bar(1,2) = 3 The main reason (at least for me) is that there's simply too much magic in it. Why does the expression left of the '.' get promoted to the first parameter? It even goes further: Foo.bar(Foo(), 1,2) works, but: Foo.bar(1,2,3) doesn't, just because of the magical first parameter in a member function. But: Foo.__dict[bar]__(1,2,3) Does work. The point is, I _do_ think it's a good idea to explicitly write self.SomeMember for member-access, so I thought: why can't we be equally explicit about member function declaration? Wouldn't it be nice if I could write (say, in Python 3k, or maybe later): class Foo: def self.bar(a,b): return a+b Foo().bar(1,2) = 3 That way, the declaration would match the invocation (at least syntactically), and the magic-feeling is gone. In the long run, the old-style syntax (i.e. if there's no '.' in the method name) could be used for static methods. What do you think? -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
In article [EMAIL PROTECTED], [EMAIL PROTECTED] wrote: Having read previous discussions on python-dev I think I'm not the only Python programmer who doesn't particularly like python's self parameter: class Foo: def bar(self, a,b): return a+b Foo().bar(1,2) = 3 The main reason (at least for me) is that there's simply too much magic in it. Why does the expression left of the '.' get promoted to the first parameter? It even goes further: Foo.bar(Foo(), 1,2) works, but: Foo.bar(1,2,3) doesn't, just because of the magical first parameter in a member function. But: Foo.__dict[bar]__(1,2,3) Does work. The point is, I _do_ think it's a good idea to explicitly write self.SomeMember for member-access, so I thought: why can't we be equally explicit about member function declaration? Wouldn't it be nice if I could write (say, in Python 3k, or maybe later): class Foo: def self.bar(a,b): return a+b Foo().bar(1,2) = 3 That way, the declaration would match the invocation (at least syntactically), and the magic-feeling is gone. In the long run, the old-style syntax (i.e. if there's no '.' in the method name) could be used for static methods. What do you think? I think you make it too complicated. Why shouldn't all functions be declared and called in the same way, that would be the simplest thing for everyone. class Foo def bar(self, a, b): return a + b bar(Foo(), 1, 2) = 3 The virtues of this consistency become more apparent in a more complex functional context: sys.stdin.write(open(file, 'r').read().split(sep)[0]) vs. write(sys.stdin, split(read(open(file, 'r')))[0]) Donn Cave, [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
[EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] Having read previous discussions on python-dev I think I'm not the only Python programmer who doesn't particularly like python's self parameter: How about this decorator-based approach (still need to pick *some* name for self, I picked __). -- Paul def memberFunction(f): def func(self,*args,**kwargs): globals()[__] = self return f(*args,**kwargs) func.__name__ = f.__name__ func.__doc__ = f.__doc__ func.__dict__.update(f.__dict__) return func class Test: @memberFunction def __init__(x,y): __.x = x __.y = y @memberFunction def mult(): Multiply the two member vars return __.x * __.y t = Test(5,4) print t.mult() print dir(t) print t.mult.__doc__ -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
write(sys.stdin, split(read(open(file, 'r')))[0]) So, if I got you right, the interpreter would have to interpret this line like this: 1. Evaluate the first parameter of the first function (sys.stdin) 2. Look up the attribute write in this object 3. evaluate the first parameter of the split function - 4. evaluate the first parameter of the read function - 5. evaluate file (I guess this is a local string variable?) 6. try attribute lookup open on the string 7. fail - call the global open function 8. lookup read in that object, call it 9. attribute lookup split on the returned object 10. call __getitem__(0) 11. pass the parameters to the write function from (1) Is this correct? My main problems are that you have to guess at step 6/7, and that the order of evaluation makes me a little dizzy ;-) Also, member functions seem to shadow global ones, what if I wanted to use some global split function I've written myself instead of the string's one. If I was mean, I'd ask you what this one does: class A: def test(self, this): return 1 class B: def test(this, self): return 2 test(self=A(), this=B()) The current call syntax at least can be read from left-to-right, and you always know whether you call a member function or a global one. -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
Definitely looks interesting. I'd like it more if it was more explicit, but still, it does look nice. I guess you could make it recursion-safe if you saved/restored the global __ variable before/after calling the actual function, and probably there's a way to make it thread-safe, too. But how would you make it generator-safe? Also, wouldn't lambda's you pass around from object to object be bound to use the wrong instance? How would you fix this code: class TestA: @memberFunction def do(f): print f() class TestB: @memberFunction def do(x): x.do(lambda : __) TestB().do(TestA()) # should print out TestB, does print out TestA There really should be something like a wiki for selfishness-proposals with pros and cons, so I could have looked at some before thinking about my own one... -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
[EMAIL PROTECTED] wrote: Having read previous discussions on python-dev I think I'm not the only Python programmer who doesn't particularly like python's self parameter: class Foo: def bar(self, a,b): return a+b Foo().bar(1,2) = 3 The main reason (at least for me) is that there's simply too much magic in it. Why does the expression left of the '.' get promoted to the first parameter? It even goes further: Foo.bar(Foo(), 1,2) works, but: Foo.bar(1,2,3) doesn't, just because of the magical first parameter in a member function. But: Foo.__dict[bar]__(1,2,3) Does work. The point is, I _do_ think it's a good idea to explicitly write self.SomeMember for member-access, so I thought: why can't we be equally explicit about member function declaration? Wouldn't it be nice if I could write (say, in Python 3k, or maybe later): class Foo: def self.bar(a,b): return a+b Foo().bar(1,2) = 3 That's similar to ruby. Really this isn't going to change in python, at least not anytime soon. If it really bothers you, then ruby is something to look into. But I think most people who don't like the extraneous 'self' in python just consider it a minor inconvenience and don't even notice it after using python for a while. It is only when you switch between python and other languages that you notice it again. If python extends decorators to allow them to be applied to classes as well as functions (which is more likely to happen perhaps), then you'll see a bunch of useful hacks pop up to eliminate the need for 'self' in method declarations. -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
In article [EMAIL PROTECTED], [EMAIL PROTECTED] wrote: write(sys.stdin, split(read(open(file, 'r')))[0]) So, if I got you right, the interpreter would have to interpret this line like this: 1. Evaluate the first parameter of the first function (sys.stdin) 2. Look up the attribute write in this object 3. evaluate the first parameter of the split function - 4. evaluate the first parameter of the read function - 5. evaluate file (I guess this is a local string variable?) 6. try attribute lookup open on the string 7. fail - call the global open function 8. lookup read in that object, call it 9. attribute lookup split on the returned object 10. call __getitem__(0) 11. pass the parameters to the write function from (1) Is this correct? My main problems are that you have to guess at step 6/7, and that the order of evaluation makes me a little dizzy ;-) Also, member functions seem to shadow global ones, what if I wanted to use some global split function I've written myself instead of the string's one. If I was mean, I'd ask you what this one does: class A: def test(self, this): return 1 class B: def test(this, self): return 2 test(self=A(), this=B()) That usage (self is second parameter to B.test) is bound to cause trouble in general, but in this case doesn't have any effect I can see. The function call test would be resolved from its first parameter, instance of A, and that function would return 1. One of us is missing something here, could be me. The current call syntax at least can be read from left-to-right, and you always know whether you call a member function or a global one. That's exactly the problem, it doesn't read from left to right, because we swap back and forth between function(parameter and parameter.function notation. It only works if you don't have to mix the two. I'm saying, pick one and use it consistently. Donn Cave, [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
[EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] Definitely looks interesting. I'd like it more if it was more explicit, but still, it does look nice. I guess you could make it recursion-safe if you saved/restored the global __ variable before/after calling the actual function, and probably there's a way to make it thread-safe, too. But how would you make it generator-safe? Also, wouldn't lambda's you pass around from object to object be bound to use the wrong instance? How would you fix this code: class TestA: @memberFunction def do(f): print f() class TestB: @memberFunction def do(x): x.do(lambda : __) TestB().do(TestA()) # should print out TestB, does print out TestA There really should be something like a wiki for selfishness-proposals with pros and cons, so I could have looked at some before thinking about my own one... Here's another pass: __ = None #initialize global __ def memberFunction(f): def func(self,*args,**kwargs): global __ save__ = __ globals()[__] = self try: return f(*args,**kwargs) finally: __ = save__ func.__name__ = f.__name__ func.__doc__ = f.__doc__ func.__dict__.update(f.__dict__) return func class Test: @memberFunction def __init__(x,y): __.x = x __.y = y @memberFunction def mult(): Multiply the two member vars return __.x * __.y t = Test(5,4) print t.mult() print dir(t) print t.mult.__doc__ class TestA: @memberFunction def do(f): print f() class TestB: @memberFunction def do(x): z = __ # lambda's shouldn't directly reference '__' x.do(lambda : z) TestB().do(TestA()) Prints out: 20 ['__doc__', '__init__', '__module__', 'mult', 'x', 'y'] Multiply the two member vars __main__.TestB instance at 0x009DA4E0 -- http://mail.python.org/mailman/listinfo/python-list
Re: Another try at Python's selfishness
On Thu, 02 Feb 2006 19:27:55 -0600 DH [EMAIL PROTECTED] wrote: But I think most people who don't like the extraneous 'self' in python just consider it a minor inconvenience and don't even notice it after using python for a while. After messing around with Javascript (many magical variables that suddenly show up in your namespaces!), I began to *seriously* appreciate Python's design. Having self as an explicit parameter is beautiful self-documenting design. The convention that the self parameter is always self with 4 characters instead of, say, __ or _ or s can get annoying, but of course, you are actually free to break this convention. The advantage to keeping it, of course, is that anybody can google python self and immediately get an explanation of what it is, whereas googling for python _ is less likely to be helpful. In fact, I think this ease of finding documentation is one of the reasons why Python's heavy use of keywords (rather than symbolic operators) is so useful. Recent additions like list comprehensions and generators create a lot of newbie confusion not least because newbies simply don't know that [x for x in mylist] is *called* a list comprehension (if they knew what it was called, they'd answer the question for themselves). They see the code and don't have any idea what it is. It adds to the basic or core knowledge that you have to wade through before you can say you know Python even at the trivial level. One of the things that attracted me to Python (at v1.5.2) was the fact that the core language was so small and simple that I could learn it in just a few days. The more syntactical sugar added, the less that will be true, though. I don't think we've busted the system yet, but I think there's some reason for caution against making things any *more* complicated. I still see newbie-friendliness as a MAJOR plus for Python -- it increases the chance that users of your software will become contributors. I mean, even Perl was probably pretty simple in the beginning. ;-) -- Terry Hancock ([EMAIL PROTECTED]) Anansi Spaceworks http://www.AnansiSpaceworks.com -- http://mail.python.org/mailman/listinfo/python-list