2 ms·
Trying to guess how Python works is quite hard if you're used to Ruby and other languages closer to Java. As I don't know much Python myself, it's hard to tell
by estavaro 14y ago
Trying to guess how Python works is quite hard if you're used to Ruby and other languages closer to Java.
As I don't know much Python myself, it's hard to tell where Python fails the "everything is an Object" check. But in Python some legacy calls were more procedural than OO, like "len(o)" rather than "o.len". I think eventually Python got to support both approaches.
I think Ruby is all objects even in its C abstractions. In Ruby, people create classes and so on in the RubyC abstractions that are visible to the Ruby language too. Not sure how Python does those.
I know Python has reference counting for Garbage Collection, so there are differences to their approaches in that regard and more.
Like Guido Van Rossum said, from 10,000 feet both Ruby and Python are more alike than different. He was saying that people should appreciate them more even if they belong to the community of the other one. That the real enemy is languages like Java that switch around the priority by making code that compilers prefer rather than programmers prefer.
I think Python has a Functions legacy that could not be as OO as they would be in Ruby.
Right now I'm more "in love" with Dart than with Ruby. Ruby was my first real love though.
- _ZeD_ 14y agoJust as note: I don't really would call "len(o)" a "legacy call", as in "something it's here just for backward compatibility, but it's ugly and please don't use it". It's more "the good way to do it" :D len() is a perfect example of the duck typing and the "protocol-based" philosophy of python: its implementation it's something like def len(object): return object.__len__() as in "just return the result of invoking the object method called __len__". this lets you just call len() on every "len-able" object. They can be list, dict, custom objects... instead of the need to, I don't know, implements an explicit interface, or define a "getLength()", "size()", "length()", "length" (just an attribute, not a function to call), you can just define a "magic" (as in "normally you don't need to call this directly") method called __len__. you can create your "not really a container, but it has a length!" object as something like >>> class C: ... def __len__(self): ... return 42 ... >>> len(C()) 42 As indirect effect, it enables you to go on the functional-style approach... a simple map(len, list_of_lists) it's more readable than map(lambda l: l.__len__(), list_of_lists) (probably [len(l) for l in list_of_lists] it's more readable, but bear with me...) I'm not really sure about the "ruby C abstractions": do you refer to the use of "object-like" structs used in the C sources of the "ruby MRI" implementation of "ruby-the-language"? regarding the GC... I don't know, but why is the kind of the GC used by an implementation of the language (or the complete lack of a GC) relevant to the "everything is an object"? just to be clear, I don't dislike ruby :) it's just that I don't find the "everything is an object" a way to discriminate between ruby and python.
- estavaro 14y agoYou see, you wrote a bunch about how len is so cool in Python. But in the face of dynamic typing and polymorphism I didn't expect it to be any different really. Languages like Go that are statically typed make more of an issue about interfaces. Even in Dart they dropped explicit Interface usage in favor of implicit interfaces, considering that Dart is more explicit about matters than Ruby is. Switching those function calls around reminds me of Delphi. When I first learned about Python, those calls reminded me of Delphi which I had used more. But once I learned Java, my frame of mind went from function(object) to object.function. With Ruby I found it quite intuitive. Now all languages work better if they approach things the way Java and Ruby do because of familiarity. That's why I like Dart for what it's worth. Regarding C extensions of Ruby, they are like OO in C. Not sure how Python does it by default. But in Ruby all C extensions have a OO flavor. The first major book about Ruby writes about them: http://www.ruby-doc.org/docs/ProgrammingRuby/html/ext_ruby.html http://www.ruby-doc.org/docs/ProgrammingRuby/html/ext_ruby.h... I think if you're counting references in the GC perhaps your C extensions are not very OO yet. In Ruby as in Java, the GC is an abstraction over reference counting. I think reference counting is often said to lead to more predictable performance at the cost of increasing the maintenance burden. So again, not sure where Python is not "Objects all the way down." But Ruby has had the OO philosophy from early on. I think the Ruby OO approach started with the OO of the C extensions and went from there. Unlike Python that had a stronger procedural influence. The gap has closed since, but in Python a class is not written like this yet: class InRuby def aMethod end end class InDart { aMethod() {} }
- _ZeD_ 14y agoI don't get the last part... in python a class is written as class InPython: def aMethod(self): pass but... what I'm missing? I can't follow the reasoning... regarding the C extensions... I didn't really needed to write one, but from http://docs.python.org/3/extending/extending.html#a-simple-example http://docs.python.org/3/extending/extending.html#a-simple-e... I see static PyObject * spam_system(PyObject *self, PyObject *args) ... so I assume also on C level the python objects are mapped on some structs in OO fashion... I honestly have no idea on how is (or if it has some meaning) to extend python in rpython on pypy, but in this case I assume there are some objects involved :D