Deciding between ruby and python

def combine_blocks(one, two)
Proc.new{|*args| one[ two[*args] ] }
end

this returns a new block that combines the two blocks passed.

I once played around with this:

class Proc

def compose(other)
    lambda { |*args| call(*other.call(*args)) }
end

alias :* :compose

def curry(*my_args)
    lambda { |*args| call(*(my_args + args)) }
end

alias :+ :curry

def rcurry(*my_args)
    lambda { |*args| call(*(args + my_args)) }
end

alias :- :rcurry

end

f = lambda { |x, y| x + y }
g = lambda { |x| 2 * x }
h = g * f
h[1, 2] # => 6
i = h + 1
i[2] # => 6
j = h + 2
j # => 6

It doesn’t look much different than ML or Haskell modulo dynamic typing.

Yes, Ruby and Python are not all that different. I guess most Ruby
fanatics
There’s only one fanatic plainly visible here…

I wonder why they always come here?

I think I caught a whiff of elitism there… Perhaps Pythoners would be
happy with a forked version of Ruby? I doubt it. And I doubt that
Rubyists want a forked version of Python.

Perhaps he has read Bruce Eckel’s half-hour-reading-in-the-bookstore
language critic of Ruby: “a bad ripoff of Python”. Somehow it has
vanished from his website, though. At least we got this wonderful
response of Matz out of it:

“Many people think Riding motorcycle isn’t worth learning. They feel
motorcycle are bad ripoff of cars (because of fewer tires). But others
don’t agree.”

···

On 2004-04-02 16:44:20 +0900, Mark Hubbart wrote:


#!/bin/sh

Hello! I’m a signature virus! Execute me and watch me spread!

s=.signature; cat $0 >/tmp/$s && mv /tmp/$s $s && chmod a+x $s

No. When implementing a join method, you have a choice: let
Strings understand something about Arrays, or let Arrays
understand something about Strings. Does it make much
difference either way? Should we choose to make a special
case of Strings, or Arrays?

It does make a difference, because sequences (or ‘iterables’) are a
much more fundamental concept than strings. It’s not just one Array
class.

> pre-existing method. But for most things, we just use
> blocks. What's so special about using methods?

I guess that’s exactly the point - what’s so special about methods
that they can’t be first class objects?

> again: blocks? Can you give an example where blocks don't
> fill the spot functions take in Python?

Nope. I consider modern Python and modern Ruby to be
feature-equivalent. Someone might have some examples, but I really
don’t have deep experience in programming Ruby. I’ve just read the
docs, and played around with it a little bit. Didn’t bump into
anything that I was missing in Python, and bumped into several things
that I consider design glitches (mostly perlisms), so I didn’t feel
the desire to become more proficient in it.

>> Calling to_s() seems kinda brutal from the Python POV. Perhaps
>> this is one of the areas where Ruby chooses the follow the Perl
>> school of Convenience.

> it makes perfect sense. Ruby uses duck typing... so when you
> call join, it assumes that you want the array items
> interpreted as strings. It

I don’t think it’s a good example of duck typing, because it coerces
everything to the particular kind of duck it wants to work with.

>> Yes, Ruby and Python are not all that different. I guess most
>> Ruby fanatics

> There's only one fanatic plainly visible here...

Please read back a few posts, I bet you’ll find at least one fanatic
more ;-).

> I think I caught a whiff of elitism there... Perhaps
> Pythoners would be happy with a forked version of Ruby? I
> doubt it. And I doubt that Rubyists want a forked version of
> Python.

From a purely technical standpoint, there are virtues in having a
pre-existing code base that is individually maintained. Ruby people
would only need to maintain the patches that provide blocks, extra
methods and ‘end’. Python is the more mature, popular and minimal of
the two, so forking Ruby wouldn’t make as much sense.

Obviously history has taken its course, and the two languages exist
independent of each other. But if Ruby started today, would you
implement it from scratch? Or would you rather just add blocks and
‘end’ to Python?

···


Ville Vainio http://tinyurl.com/2prnb

> I think Ville means that making join a method on a list means
> that lists must now know about strings.  Unfortunately,
> removing join as a list method still leaves lists
> knowledgeable about string for every object implements a to_s
> method.

I mostly meant that the sequence has a special case for the list of
strings. We have str in Python too, but ‘’.join doesn’t call it:

‘-’.join([12,13])
Traceback (most recent call last):
File “”, line 1, in ?
TypeError: sequence item 0: expected string, int found

Calling to_s() seems kinda brutal from the Python POV. Perhaps this is
one of the areas where Ruby chooses the follow the Perl school of
Convenience.

And it certainly is convenient:

the following is hypothetical, but useful:

class Socket
def to_s
“src: #{source}, dest: #{dest}”
end
end

Then with an array of Sockets, you can do:

[......].join("\n")

src: 10.10.0.0 dest: 10.10.0.1
src: 10.10.0.0 dest: 10.10.0.2

Useful?

The tradition of duck-typing and various kinds of hammer to coerce
objects into acting like the appropriate types is an appealing part of
Ruby.

Ari

independent of each other. But if Ruby started today, would you
implement it from scratch? Or would you rather just add blocks and
'end' to Python?

and security, this is more, more important ... (at least for me)

Guy Decoux

i think alan turing would disagree. strings are THE fundemental concept
behind all computing and this has been agreed upon in computer science since
1936.

-a

···

On 2 Apr 2004, Ville Vainio wrote:

It does make a difference, because sequences (or ‘iterables’) are a much
more fundamental concept than strings.

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
URL :: Solar-Terrestrial Physics Data | NCEI
TRY :: for l in ruby perl;do $l -e “print "\x3a\x2d\x29\x0a"”;done
===============================================================================

“Florian Frank” wrote:

this returns a new block that combines the two blocks passed.

I once played around with this:

class Proc

def compose(other)
    lambda { |*args| call(*other.call(*args)) }
end

My arity preserving solution to this problem was

class Proc
class << CMP_TABLE =
def add_comp(n)
s = (1…(n < 0 ? 1 - n : n)).collect{|i| "#{i},"}.join
a = n >= 0 ? s.chomp(‘,’) : s << '*

self << eval(“proc {|f,g| proc {|#{s}| f[*g[#{a}].to_a] }}”)
end
(-14…14).each {|n| CMP_TABLE.add_comp(n) }
remove_method :add_comp
end
CMP_TABLE.freeze

def *(other)
CMP_TABLE[other.arity - 15][self,other]
end
end

These days one might also want to preserve “block lambda-ness” -
which depends on a proc (a Proc instance) being formed using the
“Proc.new { … }” or the “proc { … }” syntax.

Which brings up the question on how to test “block lambda-ness”
without writing a C-extension?

/Christoph

Hmmm… you’re missing the two things that completely turned me off of
Python (and eventually led me to Ruby): gratuitous use of underscores
and passing self everywhere. The former might be fairly easy to patch
out of the language, but from my limited understanding, I think the
latter is rather deeply embedded in the semantics of the language. I
doubt it’s as simple as marking instance variables with an ‘@’ sign.

Nathaniel
Terralien, Inc.

<:((><

···

On Apr 2, 2004, at 08:19, Ville Vainio wrote:

From a purely technical standpoint, there are virtues in having a
pre-existing code base that is individually maintained. Ruby people
would only need to maintain the patches that provide blocks, extra
methods and ‘end’.

Calling to_s() seems kinda brutal from the Python POV. Perhaps this is
one of the areas where Ruby chooses the follow the Perl school of
Convenience.

And it certainly is convenient:

the following is hypothetical, but useful:

Yes, this type of coding is very useful in Ruby… Like this example
(simplified from something I wrote once…):

class Markup
initialize(style, text)
@style, @text = style, text
end
def to_s
“<#{@style}>#{@text}</#{@style}>”
end
end

Now put together an array of Markup instances, and join it to get a
string. Nice, huh? This is especially useful if you want to dynamically
determine what type of markup to generate:

html = Markup.use_html{ elems.join “\n” }
ansi = Markup.use_ansi{ elems.join “\n” }
rtf = Markup.use_rtf { elems.join “\n” }

Useful?

The tradition of duck-typing and various kinds of hammer to coerce
objects into acting like the appropriate types is an appealing part of
Ruby.

I agree heartily.

–Mark

···

On Apr 2, 2004, at 3:33 PM, Aredridel wrote:

Calling to_s() seems kinda brutal from the Python POV. Perhaps this is

> And it certainly is convenient:

> Then with an array of Sockets, you can do:

> [......].join("\n")

> src: 10.10.0.0 dest: 10.10.0.1
> src: 10.10.0.0 dest: 10.10.0.2

> Useful?

Indeed it is. We do the same thing in Python (just define str() in
your classes), but with the added spice of “explicit is better than
implicit”. So you need to coerce thems to strings before you join
them:

list_as_strings = [str(e) for e in list_of_objects]

I consider this a feature, because it leads to more robust code and
less surprises. If I expected to have a list of strings, but one
element is a socket, I should know about it.

‘Explicit is better than implicit’ comes from “Zen of Python”, if
someone didn’t know. Those who didn’t, check out:

http://www.python.org/doc/Humor.html#zen

> The tradition of duck-typing and various kinds of
> hammer to coerce objects into acting like the
> appropriate types is an appealing part of Ruby.

The duck part applies to Python too (even though we usually speak of
dynamic typing ;-). The implicit coercion is going to burn you on
large projects (“Errors should never pass silently. Unless explicitly
silenced.”), though. Perhaps this is indicative of the more general
Ruby tradition (taking influence of perl?) of optimizing shorter
scripts at the cost of large scale development?

···


Ville Vainio http://tinyurl.com/2prnb

Ara.T.Howard said:

It does make a difference, because sequences (or ‘iterables’) are a much
more fundamental concept than strings.

i think alan turing would disagree. strings are THE fundemental concept
behind all computing and this has been agreed upon in computer science
since
1936.

I am also having problems with the phrase “much more fundamental”. I
would agree that iterables/sequences are more abstract than String
(which is quite concrete). And I would also agree that (in general) we
prefer to have dependencies run from concrete to abstract and not the
other way.

However, join is defined without any reference to the concrete class
String. So the dependency is a very weak one. In fact, if you define
join as it is in Python, you don’t even need the “to_s” conversion so join
would have no reference to strings at all. It need only assume that the
objects in the sequence are “joinable” in some fashion.

In fact, if you push this to its logical conclusion, you can even make the
Enumerable#join polymorphic on a string type (another common reason given
for " ".join). First, define a pairwise join method …

class String
def join(left, right)
left.to_s + self + right.to_s
end
end

Now the join operation is polymorphic on the type of string. Now define
Enumerable#join in terms of the pairwise join …

module Enumerable
def join(delimit)
inject { |res, item| delimit.join(res, item) }
end
end

There! We know have the best of all worlds. This is what we get:

o Enumerable#join is completely decoupled from string
o Join is polymorphic on the delimiter (which provides the pairwise join).
o And we get the nice, method chaining syntax!

To demonstrate the decoupling from string, consider the following.

class Numeric
def join(left, right)
left * self + right
end
end

We use a Struct for our demo because the original Array#join still
overrides the new one in Enumerable …

S = Struct.new(:a, :b, :c)
s = s.new(1,2,3)

s.join(100) #=> 10203 # Note the non-string return!

Ok, that’s bizzarre! But it was fun getting there. I’m thinking we don’t
need an RCR for this new design though. I’m happy with the current
situation.

Except … is there a reason join is defined in Array and not Enumerable?

···

On 2 Apr 2004, Ville Vainio wrote:


– Jim Weirich jim@weirichhouse.org http://onestepback.org

“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)

Just to totally confuse the ongoing discussion, I’d like to throw in my
reasons for learning Ruby.

A couple of years ago it became obvious that I needed to learn another
language. And, unlike the incredibly intelligent folks on this list, I’m
merely bright. While I could probably out-code most of the people on this
list in assembly language for a dozen different processors, particularly
when it comes to real-time applications, I’m not very good at learning
languages (human or computer). So, having such a limited ability to
learn, I went to a social email list that I’m on that is heavily populated
with geeks and asked “Should I learn Java or Python”. Surprisingly
enough, I didn’t get the usual set of answers, “Yes”, “No” and “Install
Linux”, instead I was pointed at Ruby. So, I found a copy of the Pickaxe
book and here I am.

All in all, I’m very happy with the language. I think the fact that Matz
is a native Japanese speaker caused him to think about the language and
how it interacted with the programmer much differently. Personally, I
find Ruby to be much more “poetic” than most computer languages.

– Matt
Attitude: The difference between ordeal and adventure

I was faced with this decision just about a month ago. What I wanted was
to learn a scripting language better than ksh and Tcl.

The choice between Python and Ruby was about aesthetic hair-splitting,
and for my taste, Ruby wins in this department.

Nathaniel Talbott wrote:

Hmmm… you’re missing the two things that completely turned me off of
Python (and eventually led me to Ruby): gratuitous use of underscores
and passing self everywhere.

I didn’t like both of these things, too - but not strongly enough to
turn to Ruby. I have made my choice after reading about Python lambdas.
Lambda in Python is a single expression, and the standard way to
overcome this fact involves creative use of logical operator precedence.

By the way, I don’t know if it’s right or not, but were I looking for an
application programming language, rather than scripting (e.g., to get
away from Java), I would choose Python. It has a more mature appearance.

Not that I am expecting to get away from Java in this area any time soon

  • in the “army of junior coders” business model, static type-checking is
    vital :slight_smile:

Brgds,
Alex

···

On Apr 2, 2004, at 08:19, Ville Vainio wrote:

> Then with an array of Sockets, you can do:

> [......].join("\n")

> src: 10.10.0.0 dest: 10.10.0.1
> src: 10.10.0.0 dest: 10.10.0.2

> Useful?

Indeed it is. We do the same thing in Python (just define str() in
your classes), but with the added spice of “explicit is better than
implicit”. So you need to coerce thems to strings before you join
them:

list_as_strings = [str(e) for e in list_of_objects]

I consider this a feature, because it leads to more robust code and
less surprises. If I expected to have a list of strings, but one
element is a socket, I should know about it.

Hm. In this case, defining (locally!) the Socket#to_str method seems to
me to be saying “Yes, I know this could be a socket”. Instead of putting
it in the code that deals with the list, though, we just put it in the
class – same thing said, a different way.

‘Explicit is better than implicit’ comes from “Zen of Python”, if
someone didn’t know. Those who didn’t, check out:

http://www.python.org/doc/Humor.html#zen

This is one reason Python is better than Ruby: More english-language Zen
stories.

Actually, though, I think that the Zen of Python sums up the differences
very well, and shows why people prefer one language or the other.

Beautiful is better than ugly.

We agree here.

Explicit is better than implicit.

Or just “do what I wanted, as long as it’s clear”

Simple is better than complex.
Complex is better than complicated.

Absolutely.

Flat is better than nested.

I don’t think Ruby programmers thing either way on that one.

Sparse is better than dense.

Clear and modular is better than dense and coupled.

Readability counts.

Readability counts, but if things are too plain, you won’t like
programming in it.

Special cases aren't special enough to break the rules.

Special cases that are actually used warrant some attention.

Although practicality beats purity.

Certainly!

Errors should never pass silently.
Unless explicitly silenced.

Though what is an error and what is simply not pure is a matter of
taste.

In the face of ambiguity, refuse the temptation to guess.

But sometimes, the right thing is obvious, even without mathematical
proof.

There should be one-- and preferably only one --obvious way to do it.

If it is surprising that it doesn’t work that way, too, then it should
be added.

Although that way may not be obvious at first unless you're Dutch.

Though you should read “surprising” as “surprising to Matz”

Now is better than never.

Definately. But don’t forget to unit-test it anyway.

Although never is often better than *right* now.

Just pick a scope for your work, and stick to it.

If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.

If it can be stated in blunt, clear English by Matz in less than 76
characters, people will listen.

Namespaces are one honking great idea -- let's do more of those!

Yes, but open classes let you do neat stuff. Just be aware of what
others do with code, so you don’t step on their toes.

> The tradition of duck-typing and various kinds of
> hammer to coerce objects into acting like the
> appropriate types is an appealing part of Ruby.

The duck part applies to Python too (even though we usually speak of
dynamic typing ;-). The implicit coercion is going to burn you on
large projects (“Errors should never pass silently. Unless explicitly
silenced.”), though. Perhaps this is indicative of the more general
Ruby tradition (taking influence of perl?) of optimizing shorter
scripts at the cost of large scale development?

I think Ruby walks a very fine line, one crafted by Matz with immense
skill: I continuously find myself amazed, thinking “that would be really
fragile if it were any different”, but it’s not different.

When it comes down to it, I use Ruby and not Python, because I like
Ruby’s syntax, and the method names are obvious to me. It walks the
right path for me to follow – not too brittle, not too heavy-handed
design for me. I write smallish programs, but that’s only because when I
wrote large systems before, I realized how much simpler they could be.

Python never attracted me for small scripts, so I never really learned
it (I learned perl and sh and bash and zsh and a bit of TCL first.) …
then I decided I liked Ruby, because I could start with a script, and
grow it into a well-designed, tested system.

It comes down to the design of the language – little things. I’m
attracted to Objective C and Smalltalk and Lisp, and pushed away from
C++ and Java, ambivalent about Python (Let me say: I hate having to get
in and mess with it, but I so rarely have to, because things written in
it usually work). I like “messy” languages like sh and awk. Perl is a
nice tool, though I hate it for anything over, say, 100 lines. I do use
it less now that I use Ruby, though while so many people have compared
Ruby to Perl, that doesn’t really hold lately. (Actually, how many
python-lovers who read this have tried Ruby 1.8? 1.6?)

I also learned Object Pascal as my first real language, so I like begin
and especially end, not { and }, and not indentation for blocks.

I also like tabs to indent. I resent folding editors. I search for
begin keywords often to navigate code: I often type /if, /else, /def,
just to jump around the screen. (Yes, I use vi)

Matters of taste.

Ari

Hi,

> Then with an array of Sockets, you can do:

> [......].join("\n")

> src: 10.10.0.0 dest: 10.10.0.1
> src: 10.10.0.0 dest: 10.10.0.2

> Useful?

Indeed it is. We do the same thing in Python (just define str() in
your classes), but with the added spice of “explicit is better than
implicit”. So you need to coerce thems to strings before you join
them:

list_as_strings = [str(e) for e in list_of_objects]

I consider this a feature, because it leads to more robust code and
less surprises.
[…]
The implicit coercion is going to burn you on
large projects

A little foolishly, probably, I feel somewhat impelled to point
out that these “you need X(==explicit conversion) or you’re going
to be burned on large projects” arguments, . . . . seem
categorically indistinguishable from arguments people make with such
conviction–and often faux authoritative certitude–about static
typing. You need static typing our you’re going to be burned on
large projects!

. . . And the Smalltalkers sing,
Doot, doo doot, doo doot, doo doot doo
Doot, doo doot, doo doot, doo doot doo doot

:slight_smile:

So, … you seem to feel comfortable with Python’s dynamic
typing for large projects. Plenty of people are out there, ready
to argue with you that you’re wrong and that you need static
typing. … Perhaps you could go argue with them about why you
don’t need static typing, instead of arguing with us about why
we do need explicit conversion.

Just having fun, (but with no fear of undertaking a large Ruby
project in a Test Driven Design environment)

Regards,

Bill

···

From: “Ville Vainio” ville@spammers.com

> In fact, if you push this to its logical conclusion, you can even make the > Enumerable#join polymorphic on a string type (another common reason given > for " ".join). First, define a pairwise join method ...

nice!

-a

···

On Sat, 3 Apr 2004, Jim Weirich wrote:

===============================================================================

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
URL :: Solar-Terrestrial Physics Data | NCEI
TRY :: for l in ruby perl;do $l -e “print "\x3a\x2d\x29\x0a"”;done
===============================================================================

Bill Kelly wrote:

From: “Ville Vainio” ville@spammers.com

The implicit coercion is going to burn you on
large projects

A little foolishly, probably, I feel somewhat impelled to point
out that these “you need X(==explicit conversion) or you’re going
to be burned on large projects” arguments, . . . . seem
categorically indistinguishable from arguments people make with such
conviction–and often faux authoritative certitude–about static
typing. You need static typing our you’re going to be burned on
large projects!

I’ve been enjoying this thread, as it teeters on trolling but yet is
largely interesting and informative.

I haven’t much to add, except I, too, had the same reaction to the
“#{ruby_feature} works for small projects, but will burn you on the
large ones” comments. I immediately thought of those who argue for
static typing, claiming that it is somehow essential for large-scale
development while never quite backing up the claim.

. . . And the Smalltalkers sing,
Doot, doo doot, doo doot, doo doot doo
Doot, doo doot, doo doot, doo doot doo doot

:slight_smile:

Now I have that tune in my head, trying hard not to make up words about
dynamic typing and implicit conversion.

But, for some, those things really are the wild side, and not everybody
is ready to take that walk.

James

I haven’t much to add, except I, too, had the same reaction
to the “#{ruby_feature} works for small projects, but will
burn you on the large ones” comments. I immediately
thought of those who argue for static typing, claiming that
it is somehow essential for large-scale development while
never quite backing up the claim.

Alright, let’s assume that we have a function f that should always
return a string.

output = “”.join([f(entry) for entry in [1,2,3,4,5,6] ])

If f suddenly returned something else, it’s usually indicative of an
error of some kind. Too bad this error can easily go unnoticed if the
code is in production. OTOH, if the implicit conversion wasn’t done,
the customer would just call you and said “the code crashed, and I got
this exception traceback…” which immediately points you to the right
line of code.

> Now I have that tune in my head, trying hard not to make up
> words about dynamic typing and implicit conversion.

No need to make up words about dynamic typing, I’m a big advocate of
that (which maked this a bit of a strawman argument). This was merely
about debunking the claim that implicit conversion is somehow an
example of duck typing, whereas duck typing also has the flip side of
the coin - if it doesn’t quack and walk like a duck, it’s not a duck,
and an exception is in order.

> But, for some, those things really are the wild side, and
> not everybody is ready to take that walk.

Aren’t you blowing this out of proportion? Would Python be on the
‘wild side’ if it added the following function:

def join_as_strings(seq, sep):
return sep.join([str(s) for s in seq])

See? Everyone can opt to choose the Ruby way in Python too, it’s just
not the default because it’s deemed dangerous and a violation of
“explicit is better than implicit”.

I think this thread has been an interesting example of how similar the
two languages are - it started from “Python OO is a hack, Ruby is
better in FP also because it supports List Processing” (someone still
needs to tell me what List Processing is in Ruby) but it all really
boils down to are these small cultural differences. And they have been
hashed again and again in the past.

I bet you could use either language, and get exactly the same
productivity.

···


Ville Vainio http://tinyurl.com/2prnb

As you say, this whole thread has been done many times before.

Alright, let’s assume that we have a function f that should always
return a string.

output = “”.join([f(entry) for entry in [1,2,3,4,5,6] ])

If f suddenly returned something else, it’s usually indicative of an
error of some kind. Too bad this error can easily go unnoticed if the
code is in production. OTOH, if the implicit conversion wasn’t done,
the customer would just call you and said “the code crashed, and I got
this exception traceback…” which immediately points you to the right
line of code.

A Ruby advocate would likely suggest putting some sort of unit test on
f to make sure that it always returns a String. In fact, that’d likely be
better in Python as well, as you’d get an error message that it failed the
particular test case with specific information, rather than simply getting a
random place in your code where a String was expected and failed to
show up.

Neither method is much better than another.

No need to make up words about dynamic typing, I’m a big advocate of
that (which maked this a bit of a strawman argument). This was merely
about debunking the claim that implicit conversion is somehow an
example of duck typing, whereas duck typing also has the flip side of
the coin - if it doesn’t quack and walk like a duck, it’s not a duck,
and an exception is in order.

Actually, in a sense, the automatic conversion is duck typing in this case.
Defining #to_s in a Ruby class means, “You should call this to automatically
convert if a String is expected.” If you just want to be able to cast to a
String, you define #to_str. This is not called for implicit conversion, and is
more analogous to the str method in Python, I think. The only difference
is that Object has a default #to_s, so if you want it to raise an exception,
you need to redefine it to do so.

At least, that’s how I’ve seen it described (and a quick check reveals that
join calls #to_s, never #to_str, and when I redefine #to_s, it can throw an
exception, just like Python would).

Aren’t you blowing this out of proportion? Would Python be on the
‘wild side’ if it added the following function:

def join_as_strings(seq, sep):
return sep.join([str(s) for s in seq])

See? Everyone can opt to choose the Ruby way in Python too, it’s just
not the default because it’s deemed dangerous and a violation of
“explicit is better than implicit”.

And the Ruby community doesn’t always follow that principle, so our
default is the opposite. Neither is inherently better.

I think this thread has been an interesting example of how similar the
two languages are - it started from “Python OO is a hack, Ruby is
better in FP also because it supports List Processing” (someone still
needs to tell me what List Processing is in Ruby) but it all really
boils down to are these small cultural differences. And they have been
hashed again and again in the past.

I’m not the poster of that opinion, but I imagine he was referring to
things like #each and #inject and the Enumerable module. I don’t
know Python, so I don’t know what the analogues to these are, or
if it has them at all. Perhaps whenever he looked at Python, it didn’t.

Ruby doesn’t have list comprehensions like Python and Haskell do,
though, if that’s what you took it to mean. Not having list
comprehensions doesn’t mean your bad at list processing, though.
Otherwise Lisp would be bad at it (by default, at least), and Lisp
stands for List Processing. :slight_smile:

I bet you could use either language, and get exactly the same
productivity.

I don’t know that one is inherently better than the other at anything,
really. It’s mostly a matter of taste. We should probably stop
quibbling. :slight_smile:

Have a nice day.

  • Dan

Actually, in a sense, the automatic conversion is duck typing in this
case.
Defining #to_s in a Ruby class means, “You should call this to
automatically
convert if a String is expected.” If you just want to be able to cast
to a
String, you define #to_str. This is not called for implicit
conversion, and is
more analogous to the str method in Python, I think. The only
difference
is that Object has a default #to_s, so if you want it to raise an
exception,
you need to redefine it to do so.

At least, that’s how I’ve seen it described (and a quick check reveals
that
join calls #to_s, never #to_str, and when I redefine #to_s, it can
throw an
exception, just like Python would).

I had the exact opposite understanding of the meaning of #to_s and
#to_str.

$ cat str.rb
class Toto; end
t = Toto.new

begin
puts("hello " + t)
rescue Exception => e
puts("Error " + e.message)
end

class Toto
def to_str
“toto”
end
end

begin
puts("hello " + t)
rescue Exception => e
puts("Error " + e.message)
end

$ ruby str.rb
Error cannot convert Toto into String
hello toto

#join on the other hand calls #to_s on each element of the Array.

Guillaume.

···

Le 4 avr. 04, à 05:37, Dan Doel a écrit :

Aren’t you blowing this out of proportion? Would Python be on the
‘wild side’ if it added the following function:

def join_as_strings(seq, sep):
return sep.join([str(s) for s in seq])

See? Everyone can opt to choose the Ruby way in Python too, it’s just
not the default because it’s deemed dangerous and a violation of
“explicit is better than implicit”.

And the Ruby community doesn’t always follow that principle, so our
default is the opposite. Neither is inherently better.

I think this thread has been an interesting example of how similar the
two languages are - it started from “Python OO is a hack, Ruby is
better in FP also because it supports List Processing” (someone still
needs to tell me what List Processing is in Ruby) but it all really
boils down to are these small cultural differences. And they have been
hashed again and again in the past.

I’m not the poster of that opinion, but I imagine he was referring to
things like #each and #inject and the Enumerable module. I don’t
know Python, so I don’t know what the analogues to these are, or
if it has them at all. Perhaps whenever he looked at Python, it
didn’t.

Ruby doesn’t have list comprehensions like Python and Haskell do,
though, if that’s what you took it to mean. Not having list
comprehensions doesn’t mean your bad at list processing, though.
Otherwise Lisp would be bad at it (by default, at least), and Lisp
stands for List Processing. :slight_smile:

I bet you could use either language, and get exactly the same
productivity.

I don’t know that one is inherently better than the other at anything,
really. It’s mostly a matter of taste. We should probably stop
quibbling. :slight_smile:

Have a nice day.

  • Dan

I’m not the poster of that opinion, but I imagine he was
referring to things like #each and #inject and the Enumerable
module. I don’t know Python, so I don’t know what the
analogues to these are, or if it has them at all. Perhaps
whenever he looked at Python, it didn’t.

#each is just a for loop (at least the #each usages I’ve seen
here). Python has always had it, but but it didn’t probably have
generators, which provide ‘yield’ functionality. Well, it has now.

>> I bet you could use either language, and get exactly the same
>> productivity.

> I don't know that one is inherently better than the other at
> anything, really. It's mostly a matter of taste.  We should
> probably stop quibbling. :)

Seconded.

···


Ville Vainio http://tinyurl.com/2prnb