> Can you discuss some of the linguistic edges that you find in Ruby?

Ruby is close to Smalltalk, but with an Algol-family syntax that goes to painstaking lengths to make visual clutter optional while being familiar.

There's nothing really new in Ruby in terms of semantics. What Ruby did was fuse a number of language concepts into something that reads well. Syntax is the primary linguistic edge of Ruby.

We get the dynamism of Smalltak, in a more familiar packaging, that then goes to extremes to try to let you strip out ceremony.

This to me contributes to compact but readable code. Outside of golfing, the Ruby community values readability very highly, and syntax is a big part of that.

A typical example is the block sytax, which seems trivial on the surface, given that it is just a very thin veneer over the lambda syntax. To give a (very) contrived example:

Ruby's "full length" lambda syntax:

def foo l
print "Hello "
l.call
end

foo ->{puts "World"}

The block syntax:

def bar
print "Hello "
yield
end

bar { puts "World" }

The first thing to note is that the full length syntax has become very compact too, and the difference on the surface looks rather pointless (though it used to be bigger), but reducing the visual clutter makes the block syntax acceptable in a lot of circumstances where lambdas would otherwise "look ugly". E.g. in Ruby there is "timeout", which is a method that takes a number of seconds, and a block, letting you write "timeout 5 { call_something }". You could do implement one with lambda's too, but you'd end up with "timeout 5,-> { call_something }" at the bare minimum, and in instances where () around the argument list becomes necessary, you end up with even more clutter, while the block syntax avoids it.

This probably seems very minor, and in a way it is, but in my experience when visual clutter disappears people think about code differently and use constructs more or less sparingly. E.g. you can do most of the semi-functional stuff you do casually in Ruby in C++ too, but the extra ceremony and clutter quickly puts people off. Cutting down on the clutter matters.

Another example is the DSL functionality which in Ruby is often done by defining context classes with methods, or by injecting methods in the meta-class of the class you're defining.

In particularly defining methods on the meta-class to be executed during the definition of a class. E.g. as a example from Sequel:

class Movie < Sequel::Model
plugin :validation_helpers

...
end

"plugin" here is a method on the meta-class of Sequel::Model that pulls in the relevant methods of the specified plugin by running this code while defining the class. Being able to basically define a DSL to mutate the class while it is being defined leads to code where boilerplate very quickly ends up extracted into libraries in ways that tends to produce a lot of extra clutter in other languages.

> Unless you're engaging in the above-referenced symbolic soup, Python and Ruby code usually end up looking pretty similar. I don't know how you can say that one "looks awful" v. the other.

I agree it looks relatively similar, which is exactly why I believe most of those of us who have chosen Ruby tends to have very strong opinions about why Ruby works for us. For me the most immediate one is that I refuse to work with languages where significant indentation levels is a big thing. I both really want the visual indication, and really hate working with significant indentation (including things like YAML)

Part of the reason why I feel comfortable making that choice is exactly that the benefit of picking Python over Ruby to me is slim enough that I can afford to make that decision over issues that otherwise would be marginal, but that matters to me.