Nikolai Weibull wrote:
I'm a passionate Ruby user myself and I find Python quite limiting in
some aspects (I agree with Francis Hwang's response to your posting),
but as a Ruby user I still have to disagree with / add to some of the
responses you give.
This is a joke, no? I'll assume it is and will stop here.
It isn't and it can make for quite some elegant code if you can call
functions directly, though this doesn't fit at all into the Ruby model.
(Because we have no public fields and use accessors that look like field
access all over the place.)
The elegance of having a () operator IMHO is that you can do things like
this directly:
[1, 2, 3].each(output)
Where output can either be a built-in method (or a variable referring to
one) or a custom one. (Lambda in Ruby.)
It's also interesting how this lets you assign functions to fields and
get methods automatically:
var obj = [1, 2, 3]
obj.each = function(block) {
this.reverse().each(block)
}
This model has downsides of course, a big one being that you can't have
accessors (I think properties are commonly used, which is just a set of
callbacks for assignment/accessing a field.) and the other one being
that you want to omit parentheses. Python solves the latter one by
making core functions like print no real functions, but rather a piece
of built-in syntax.
I have to say that I prefer Ruby's model here, though I can see some of
the elegance of the other one, too.
Multiple inheritance has its merits, but generally it makes class
hierarchies both harder for the compiler and for the programmer to
understand. Very few objects one may want to model require multiple
inheritance (mostly geometrics). You can do fine without it.
I think Mix-Ins are generally seen as a more limited (and thus easier to
understand and maintain) form of Multiple Inheritance. I personally have
not needed more than what Mix-Ins provide yet, but Evil Ruby has support
for Multiple Inheritance via Module#inherit in case anybody wants to try
this out in practice. (It works by converting the given class to a
Module and calling include() with it as the argument.)
Why? In Ruby, everything but false and nil is true, so why would you
want this? If you would want a #to_bool, then use that instead. Using
pseudo-truthvalues on objects is both bad style and confuses the
intention of the code.
Because you might want to have Objects that act like other Objects.
In current Ruby there is no way of having a WeakRef or some other kind
of Proxy act like nil or false. This is a limitation.
I would also find this useful for implementing Perl6-style Junctions,
but that might not be a big point.
Also, if they are useless, why does Python have them?
Python has blocks? As far as I know it only has some crippled form of
lambdas that are only allowed to have one statement inside. The
non-crippled form are nested defs, but those don't have closures by
default. (There is a way of emulating closures via default arguments,
but it is quite cumbersome.)
- list comprehensions are far better than map() and the likes
Yes, that's why Ruby doesn't have map(); that's why we have .map. Why
do you find that
l = [1, 2, 3]
[i * 2 for i in l]
is far better than
l = [1, 2, 3]
l.map{ |i| i * 2 }
? It's not like one version is longer than the other, or one is easier
to follow than the other? In fact, the Python version requires the use
of two keywords and an additional feature of list creation.
There is one benefit of list comprehensions that I can think of right
now -- they don't need to construct immediate lists which makes them act
like Shell pipes.
I can think of various ways to emulate this in Ruby, but still -- it is
simpler to do it in Python.
Other than that I think that Ruby's list iteration capabilities feel
generally more powerful. Being able to directly use blocks instead of
using a nested def with some odd default argument hack contributes a lot
of it, but the bigger point is that Ruby has a lot of this already
built-in via the Enumerable module.
Yes, certainly, and look how easy it is to simulate in Python:
http://www.ps.uni-sb.de/~duchier/python/continuations.html
But note that this is just a way of emulating them. This won't give you
the power you have with built-in continuations.
I'm not sure if you're really implying here that Continuations are evil,
but they can certainly be useful in more esoteric contexts. (Note that
Continuations allowed me to implement Binding.of_caller in pure Ruby
with a quite reasonable interface.)
That's why Ruby isn't Perl. I can't really tell what you are getting at
with this point.
I disagree with both these opinions. Python's view is that there is only
one truly right way of doing things. But of course this isn't true and
not even consistently applied in Python -- requirements vary all the
time and solutions to problems ought to vary with them.
Yes, they are. Finally, an argument that actually stands up against
simple critique. Ironic that it should be your last choice ;-).
Also note that we are getting close with RDoc. What is currently missing
is a nice way of accessing RDoc documentation from irb. I would like to
see support for that included in a further irb version.
Regards,
Florian Gross