1. Functions know internally what object they belong to.
2. The object that functions belong to is passed as the first argument, no matter how that function is referenced:
a.foobar() b = a.foobar() b() # same as a.foobar()
3. Thus, Python queries the function first - if it belongs to no object (object.im_self == None), it makes no change to the argument list, otherwise it passes object.im_self as the first argument to that function.
4. As for making methods that fail in odd ways - sure, if you don't know Python, of course you can. If you don't know Java, I suspect that the pass-by-value nature of primatives would confuse people too. But once the programmer is familiar with the language, it's a mistake that's very rarely made, and easily spotted when it is.
Thus, I'm not sure where you're coming from. Sure, you might not like the syntax - I'm not sure I do, either. But this bears no relation to Python's internal OO model. Functions know which object they are assigned to, and pass a reference to this object as the first argument, no matter how they are called. The difference between Java's "this" and Python's "self" is purely superficial.
Whilst this may seem odd, it also has it's advantages, the main one being that you can attach a function to a previously created object or class.
If you're arguing that you don't like the 'self' syntax, then that's perfectly fine. But saying that Python's OOness is somehow less clean as a result is nonsense, as there's no practical difference between 'this' and 'self'. As I said before, all differences are superficial.
Really? I noticed that foobar didn't print any information about the object it belonged to. Without changing the method signature, why don't you add a variable to the class and have it print that out. If foobar *really* knows which object it belongs to, you'll have no trouble with this.
I'm not entirely sure what you mean. Is this what you meant?
A.new_variable = "Something" a = A() b = a.foobar print b.im_self.new_variable
As you can see, the 'foobar' function clearly knows which object it belongs to.
On the other hand, you might have picked up on my error, since I forgot to give foobar() any arguments:
class A:
def foobar(self):
print "Foobar"
But this is irrelevant, since my previous code shows that each function holds a reference to the containing object, which rather proves my point.
In addition, I should also mention that Python's way of taking self reference from the first argument is not without its advantages:
Why does an OO language needs to implement scalars, hashes and arrays as objects to be a trully OO language?!?
I didn't say this. I said Perl had an incomplete object model. Since scalars and such aren't naturally objects in Perl, not all data types in Perl are objects. Therefore, Perl's object model is incomplete. QED.
The code was written specifically to show how Python objects have a very sketchy grasp of object identity.
I have to disagree:
class A:
def foobar():
print "Foobar" a = A() b = a.foobar assert a == b.im_self
The 'foobar' method knows exactly which object it belongs to. That seems a very solid grasp of object identity to me.
That's why "self" is an explicit parameter that is mutable and all references to class variables and methods must be prefixed with "self." That is not clean OO.
I'm trying to see your point, but I'm afraid I can't see why you're so hung up on this. You're saying that Python OO is not clean because it allows you to redefine 'self', and languages like Ruby or Java are clean OO, because they will throw an error if you try to do that.
This doesn't matter in practise, of course - methods don't commonly go around redefining 'self'. But if it's such a big deal to you in theory, then I'm curious; what language would you consider has clean OO? Obviously not Java... Perhaps Ruby?
Sigh. We still have to have a language hate-fest every time a language-specific article shows up?
Because arguments, when intelligently debated, often offer previously insight to both sides. It's a competitive exchange of ideas. Whilst I can't comment on what brpr thinks, his arguments have made me think more carefully about Python closures and scoping, and has opened up some fascinating avenues of thought.
True lexical scoping seems, to me, to blur the distinction between a function and an object. Such realisations aren't going to come about by blindly agreeing with people, but by engaging in good, old fashioned arguments.
Whilst Python is not without it's problems, in this case the problem lies with you misunderstanding how both Java and Python handle objects and references.
Let's take the following Python code:
ob = A()
The class 'A' is instantiated into a new object, which is placed on the heap. The constructor 'A()' returns a reference to this new object, which is stored in the variable 'ob'. Note that 'ob' stores not an object itself, but merely a reference to one. All variables in Python are references to objects, without exception.
Java works in a similar way. Excepting primatives, all variables are references to objects. Java has a special variable called 'this' which is a reference to the current object. Python handles things differently; classes pass a reference to themselves through the first argument of a method. By convention, this is called 'self'.
Both 'self' in Python, and 'this' in Java are references to the current object. The only difference is that Java forbids you from redefining it, whilst Python merely discourages the practise.
The only reason you think that your example is "not clean OO", is because you don't fully understand the distinction between objects and references. Let's take another look at your code:
self = Bad()
This assignment is no different from any other in Python. You're assigning a reference returned by Bad() to the variable 'self'. This does not affect 'ob', because 'ob' is a unrelated reference. Most OO languages take this approach, including C++, C#, Java and Ruby.
True, but that basically amounts to saying "lexical scope isn't particularly useful". You have a point here I admit -- it's easy enough to get along in a language with little or no lexical scoping (e.g. C, prior to C99). But it's still anoying that closures are so limited in Python, if you like functional programming, as I do.
I think it might be a case of programming style. I used Perl for years before I discovered Python, and I find myself liking the latter a lot more. But then, I've always taken a very OO approach to programming, and it's only recently that I've started to adopt more functional programming techniques. Given this, Python's very clean OO approach appeals to me greatly.
On the other hand, you seem to take a very functional approach, with a minimalistic only-when-needed approach to OO. So I can understand your frustration with Python's closures.
That's not to say that there aren't things in Python that irritate me. The lack of anonymous closures. The __annoying__ naming scheme for internal class members. The decision to make base classes (str, int, etc.) unmodifiable. Python's far from my perfect language, but it's possibly the best that I've found, overall.
Because the scoping itself works fine. The problem lies with variable assignment and declaration in Python being ambiguous when dealing with multiple scopes. This means that closure support in Python is incomplete, in that closures are essentially 'read-only', in that inner assignments won't work. This can be overcome with mutable types, but I agree that this isn't a ideal solution.
This is why I say incomplete, and not broken. By the same standards, I say that Perl's object model is incomplete, rather than broken. If you claim that Python's closures are 'broken', then you must also accept that Perl's object model is 'broken'.
Perl has a perfectly well-defined object model.
When last I looked, Perl didn't treat scalars, hashes and arrays as objects. Perl's incomplete object model is, in my view, a far bigger problem than Python's read-only closures. And on the subject of things Perl doesn't have, as far as I know, it has no metaclass support, either.
Even ignoring Python's problems with closures, you still have the problem that whenever you write "a = b", you can't be sure whether you're binding a new variable, or assigning a new value to an existing variable.
Only in the scope of a single function, and realistically speaking, if your functions are so long that you don't know whether a local variable has been assigned or not, then perhaps your function is too long, anyway. Certainly when I'm programming in Python, functions tend to be under a dozen lines long.
That isn't a problem with lexical scoping; that's a problem with ambiguous assignments within closures. The lexical scoping problem was something else altogether. And whilst Python closures are read-only, this doesn't mean that they are broken; just incomplete.
Whilst read-write access of closures would be nice, it's trivial to get around this. It's certainly not enough to get me to switch back to Perl - yuck! No thanks! I like my well-defined object model:)
IIRC Ruby has read-write closures? Why not use that over Perl?
There are numerous cross-platform open source OpenGL 3D engines that have scriping hooks. OGRE, CrystalSpace and Panda3D spring to mind. I'd personally go with Panda3D and Python, if I wanted to create a modern-looking 3D game with minimal effort.
I'm another. I prefer KDE over GNOME, OS X and XP. Given that KDE is one of the largest open source projects in active development, I suspect myself and the grandparent poster aren't alone in prefer KDE over the alternatives.
Now, it's certainly plausible that this happened, but its not the slam dunk the likes of Dawkins would have us believe. My own experience in this matter suggests to me that we are so far missing something fundamental in our understanding.
Oh, I certainly agree that we have gaps in our knowledge, and that there is still a lot to learn about the mechanisms of evolution. We're far from a complete understanding of DNA, and that is the cornerstone of modern evolutionary biology. But this said, I don't believe that the Theory of Evolution is incorrect; the gist of the theory, that creatures adapt to their environment over successive generations, is in my opinion indisputable. So too the theory that life evolved over billions of years from simple beginnings. But the exact processes involved are certainly very much open to debate; a billion years of spaghetti code is hard to unravel.
Don't even bother with that. I seriously doubt that any computer in any universe could simulate another one in anything even approaching real-time, even if a significant portion of that universe contained computers and storage to do it.
Most of the Universe is unseen, and does not directly affect us. There wouldn't be any need to simulate the Universe as a whole, just to simulate the bits that we interact with. One could even go further, and use approximations when no direction measurement has taken place, as we do in modern computer games.
Besides which, who says it has to be in real time?
It's hardware based. The key that you need is embedded in a chip such that you need a million-dollar laboratory to get at it.
This assumes that the corporations manufacturing these chips, and the content producers using them, are flawless. Clearly this isn't the case; one mistake with the key, one errant piece of code, one lapse in security, and the genie it out of the bottle; the jig is up; game over, man.
Treacherous/Trusted Computing works only so long as the distribution chain is secure. This is fine in theory, but in practise it quickly breaks down. There's just too many components that could be compromised.
Further, economically, the more DRM companies try and lock down value, the more value is removed from the product, and the more attractive alternatives become, even if they are illegal.
Now, I'll grant you that I didnt have several hundred million years to work on the problem. However, I did experiment with population sizes in the 100'000s and I did evolve them for 10,000s of generations. Those are small numbers when considering evolution of bacteria, but they're pretty realistic numbers when considering evolution from an Ape to a human (or some equally fit alternative).
Your data is interesting, but your conclusion is incorrect. With genetic algorithms, we start off with pseudorandomly chosen 'genes'. In evolution, we start off with genes that have already been through billions of years of natural selection. You see the difference?
Your results are interesting, but not because they somehow show that sexual/natural selection is invalid. They're interesting because they suggest that an animal is 'fittest' not only due to their physical characteristics, but also due to how malable their genes are - how fast they can adapt to changes in the environment. Those animals that have genes that change slowly will be overtaken by those that have genes optimised for fast evolution.
Hence, humans evolved through a relatively short period, whilst your algoritms couldn't match that, because your algoritms had an inferior starting point.
I didn't say it has native multimethods; it does, however, have everything required to implement them in such a way that they "look" native (that is, like a normal method call). You simply cannot do it in Java, nor, AFAIK, in Ruby.
Well... It's true that Ruby doesn't have decorator sugar like Python 2.4 has. I'm not sure I'd go so far as saying that Python multimethod implementations look native, though. Not enough to be convinient for everyday use, at least - but I take your point, all the same.
Any chance that this new 3d accelerated rendering can help make anti-aliased fonts actually look good ? Unbelieveable that OS X and Windows have better looking (smoother) anti-aliased fonts then linux ever dreamed.
Eh? If anything, my fonts look smoother in Linux than in Windows (especially on serif fonts). Fonts haven't been a problem in Linux for years.
I found that hardware acceleration on X.org with a 5900 worked flawlessly, whilst a much older card (300 or something) crashed after only 5 minutes of hardware acceleration being switched on. There does seem to be stability issues with older NVidia cards.
Select a rectangular area with the select tool. Click the 'selection to path' button, then the 'draw path' button. Not exactly that direct, I'll agree, but there's no fiddling around with masks required.
It does if the code has to be signed by the manufacturer of the device you just bought before it can be installed. Who says the manufacturer has to allow a user override option?
In which case, the device has DRM. But code signing is not DRM in itself, because it doesn't by itself deny the user anything. The signed RPMs of Redhat aren't DRM, because you have the option of installing unsigned packages.
Cryptographic signing is not DRM, anymore than strong encryption is. They can be used in DRM, but they are not, themselves, DRM systems.
Why are you asking me? Why not ask Larry Wall?
1. Functions know internally what object they belong to.
2. The object that functions belong to is passed as the first argument, no matter how that function is referenced:3. Thus, Python queries the function first - if it belongs to no object (object.im_self == None), it makes no change to the argument list, otherwise it passes object.im_self as the first argument to that function.
4. As for making methods that fail in odd ways - sure, if you don't know Python, of course you can. If you don't know Java, I suspect that the pass-by-value nature of primatives would confuse people too. But once the programmer is familiar with the language, it's a mistake that's very rarely made, and easily spotted when it is.
Thus, I'm not sure where you're coming from. Sure, you might not like the syntax - I'm not sure I do, either. But this bears no relation to Python's internal OO model. Functions know which object they are assigned to, and pass a reference to this object as the first argument, no matter how they are called. The difference between Java's "this" and Python's "self" is purely superficial.
Whilst this may seem odd, it also has it's advantages, the main one being that you can attach a function to a previously created object or class.
If you're arguing that you don't like the 'self' syntax, then that's perfectly fine. But saying that Python's OOness is somehow less clean as a result is nonsense, as there's no practical difference between 'this' and 'self'. As I said before, all differences are superficial.
On the other hand, you might have picked up on my error, since I forgot to give foobar() any arguments:But this is irrelevant, since my previous code shows that each function holds a reference to the containing object, which rather proves my point.
In addition, I should also mention that Python's way of taking self reference from the first argument is not without its advantages:
I didn't say this. I said Perl had an incomplete object model. Since scalars and such aren't naturally objects in Perl, not all data types in Perl are objects. Therefore, Perl's object model is incomplete. QED.
I'm trying to see your point, but I'm afraid I can't see why you're so hung up on this. You're saying that Python OO is not clean because it allows you to redefine 'self', and languages like Ruby or Java are clean OO, because they will throw an error if you try to do that.
This doesn't matter in practise, of course - methods don't commonly go around redefining 'self'. But if it's such a big deal to you in theory, then I'm curious; what language would you consider has clean OO? Obviously not Java... Perhaps Ruby?
Because arguments, when intelligently debated, often offer previously insight to both sides. It's a competitive exchange of ideas. Whilst I can't comment on what brpr thinks, his arguments have made me think more carefully about Python closures and scoping, and has opened up some fascinating avenues of thought.
True lexical scoping seems, to me, to blur the distinction between a function and an object. Such realisations aren't going to come about by blindly agreeing with people, but by engaging in good, old fashioned arguments.
Let's take the following Python code:The class 'A' is instantiated into a new object, which is placed on the heap. The constructor 'A()' returns a reference to this new object, which is stored in the variable 'ob'. Note that 'ob' stores not an object itself, but merely a reference to one. All variables in Python are references to objects, without exception.
Java works in a similar way. Excepting primatives, all variables are references to objects. Java has a special variable called 'this' which is a reference to the current object. Python handles things differently; classes pass a reference to themselves through the first argument of a method. By convention, this is called 'self'.
Both 'self' in Python, and 'this' in Java are references to the current object. The only difference is that Java forbids you from redefining it, whilst Python merely discourages the practise.
The only reason you think that your example is "not clean OO", is because you don't fully understand the distinction between objects and references. Let's take another look at your code:This assignment is no different from any other in Python. You're assigning a reference returned by Bad() to the variable 'self'. This does not affect 'ob', because 'ob' is a unrelated reference. Most OO languages take this approach, including C++, C#, Java and Ruby.
I think it might be a case of programming style. I used Perl for years before I discovered Python, and I find myself liking the latter a lot more. But then, I've always taken a very OO approach to programming, and it's only recently that I've started to adopt more functional programming techniques. Given this, Python's very clean OO approach appeals to me greatly.
On the other hand, you seem to take a very functional approach, with a minimalistic only-when-needed approach to OO. So I can understand your frustration with Python's closures.
That's not to say that there aren't things in Python that irritate me. The lack of anonymous closures. The __annoying__ naming scheme for internal class members. The decision to make base classes (str, int, etc.) unmodifiable. Python's far from my perfect language, but it's possibly the best that I've found, overall.
Because the scoping itself works fine. The problem lies with variable assignment and declaration in Python being ambiguous when dealing with multiple scopes. This means that closure support in Python is incomplete, in that closures are essentially 'read-only', in that inner assignments won't work. This can be overcome with mutable types, but I agree that this isn't a ideal solution.
This is why I say incomplete, and not broken. By the same standards, I say that Perl's object model is incomplete, rather than broken. If you claim that Python's closures are 'broken', then you must also accept that Perl's object model is 'broken'.
When last I looked, Perl didn't treat scalars, hashes and arrays as objects. Perl's incomplete object model is, in my view, a far bigger problem than Python's read-only closures. And on the subject of things Perl doesn't have, as far as I know, it has no metaclass support, either.
Only in the scope of a single function, and realistically speaking, if your functions are so long that you don't know whether a local variable has been assigned or not, then perhaps your function is too long, anyway. Certainly when I'm programming in Python, functions tend to be under a dozen lines long.
That isn't a problem with lexical scoping; that's a problem with ambiguous assignments within closures. The lexical scoping problem was something else altogether. And whilst Python closures are read-only, this doesn't mean that they are broken; just incomplete.
:)
Whilst read-write access of closures would be nice, it's trivial to get around this. It's certainly not enough to get me to switch back to Perl - yuck! No thanks! I like my well-defined object model
IIRC Ruby has read-write closures? Why not use that over Perl?
There are numerous cross-platform open source OpenGL 3D engines that have scriping hooks. OGRE, CrystalSpace and Panda3D spring to mind. I'd personally go with Panda3D and Python, if I wanted to create a modern-looking 3D game with minimal effort.
Or invest in Torque3D.
This is no longer true, and hasn't been for years.
With Opera, I couldn't find good replacements for:
Adblock
Flashblock
StumbleUpon
Del.icio.ous post
PasswordMaker
Google Preview
I'm another. I prefer KDE over GNOME, OS X and XP. Given that KDE is one of the largest open source projects in active development, I suspect myself and the grandparent poster aren't alone in prefer KDE over the alternatives.
Oh, I certainly agree that we have gaps in our knowledge, and that there is still a lot to learn about the mechanisms of evolution. We're far from a complete understanding of DNA, and that is the cornerstone of modern evolutionary biology. But this said, I don't believe that the Theory of Evolution is incorrect; the gist of the theory, that creatures adapt to their environment over successive generations, is in my opinion indisputable. So too the theory that life evolved over billions of years from simple beginnings. But the exact processes involved are certainly very much open to debate; a billion years of spaghetti code is hard to unravel.
Most of the Universe is unseen, and does not directly affect us. There wouldn't be any need to simulate the Universe as a whole, just to simulate the bits that we interact with. One could even go further, and use approximations when no direction measurement has taken place, as we do in modern computer games.
Besides which, who says it has to be in real time?
This assumes that the corporations manufacturing these chips, and the content producers using them, are flawless. Clearly this isn't the case; one mistake with the key, one errant piece of code, one lapse in security, and the genie it out of the bottle; the jig is up; game over, man.
Treacherous/Trusted Computing works only so long as the distribution chain is secure. This is fine in theory, but in practise it quickly breaks down. There's just too many components that could be compromised.
Further, economically, the more DRM companies try and lock down value, the more value is removed from the product, and the more attractive alternatives become, even if they are illegal.
I think your trolling technique needs work. Try to be more subtle, rather than pretending to be such an obviously over-the-top nutcase.
Your data is interesting, but your conclusion is incorrect. With genetic algorithms, we start off with pseudorandomly chosen 'genes'. In evolution, we start off with genes that have already been through billions of years of natural selection. You see the difference?
Your results are interesting, but not because they somehow show that sexual/natural selection is invalid. They're interesting because they suggest that an animal is 'fittest' not only due to their physical characteristics, but also due to how malable their genes are - how fast they can adapt to changes in the environment. Those animals that have genes that change slowly will be overtaken by those that have genes optimised for fast evolution.
Hence, humans evolved through a relatively short period, whilst your algoritms couldn't match that, because your algoritms had an inferior starting point.
Well... It's true that Ruby doesn't have decorator sugar like Python 2.4 has. I'm not sure I'd go so far as saying that Python multimethod implementations look native, though. Not enough to be convinient for everyday use, at least - but I take your point, all the same.
Python doesn't support multimethods. You can approximate them with decorators, but they're not natively supported.
Eh? If anything, my fonts look smoother in Linux than in Windows (especially on serif fonts). Fonts haven't been a problem in Linux for years.
I found that hardware acceleration on X.org with a 5900 worked flawlessly, whilst a much older card (300 or something) crashed after only 5 minutes of hardware acceleration being switched on. There does seem to be stability issues with older NVidia cards.
Select a rectangular area with the select tool. Click the 'selection to path' button, then the 'draw path' button. Not exactly that direct, I'll agree, but there's no fiddling around with masks required.
In which case, the device has DRM. But code signing is not DRM in itself, because it doesn't by itself deny the user anything. The signed RPMs of Redhat aren't DRM, because you have the option of installing unsigned packages.
Cryptographic signing is not DRM, anymore than strong encryption is. They can be used in DRM, but they are not, themselves, DRM systems.