The Python vs Ruby thing is tired by now but reading this reminds me again of how many problems Ruby managed to solve with just one construct (blocks).
Python was my first "scripting" language but modern idiomatic Python is almost unrecognizable compared to the Python I started out with in 1997.
The fact that the Ruby I was writing in 2002 looks almost modern is a testament to Matz' foresight.
You are right - it's very tired. Also, most Python users couldn't care less about language wars.
Maybe with the exception of Java.
I'm also sure the idiomatic FORTRAN or C I wrote in college would be odd to someone who just came in contact with current versions of both languages, but all it means is that they have been around literally for ages.
The code still looks stylistically modern, except for its use of getopt, but that's a library issue, not a syntax one. It's by far from "almost unrecognizable."
Can you therefore elaborate with an example from that era?
Python from that era didn't have generators, new classes, list comprehensions, annotations etc. If you're not using any of these in your code now you're not writing idiomatic modern Python.
But the point of my post wasn't to bash Python but rather to note that Ruby got an unusually large number of thing right on the first try.
Or that it hasn't fixed the warts it has. I use Ruby rarely enough to really, really miss explicit imports. I guess it's not a problem if you use it all the time and magically know what's in the global namespace at any given time but it's a pain in the ass when you have to touch a legacy rails app twice a year.
Some of the new things in 1.8 include allocate, respond_to, fully qualified names, Array#zip, and "In Ruby 1.8.0, both break and return exit the scope of the proc, but do not exit the scope of the caller."
That reads like Ruby of 1.6 (about 10 years ago) would be stylistically different from modern Ruby, in about the same way that Python is stylistically different.
Going back further, early Ruby had a lot more influence from Perl, like magic variable names and the "discouraged" flip-flop operator. The plan is to remove these in some still hypothetical Ruby 3.
List comprehensions have been around in Python since 2000 and generator expressions were introduced in 2.3 (but you could import them from __future__ as early as 2.2) and also build generators without them.
Every future version of Python that tweaks the class system will always be able to claim every previous version didn't have "new classes".
Decorators (we don't call them annotations) have syntactic support since 2.4.
I'm not an expert in Ruby's evolution but it certainly looks like it got a lot of stuff right. I can't find much about its evolution, however. I'd like to see how it changed over time.
Maybe you both have a point. Code you wrote for Python 1.6 (1998) could still look like normal Python.
But, code I write now for Python 2.7 looks very different. I use:
list comprehensions
sets
with...as
yield
new "collections" classes like Counter
looping constructs like enumerate and zip
It's true that you could implement the last two in Python 1.6. But the first four are new language constructs. And list comprehensions, in particular, can be sprinkled all around, not just localized like with/as and yield.
In short, the language has grown. Old stuff looks OK, new stuff looks new.
Python was my first "scripting" language but modern idiomatic Python is almost unrecognizable compared to the Python I started out with in 1997.
The fact that the Ruby I was writing in 2002 looks almost modern is a testament to Matz' foresight.