148 comments

[ 2.2 ms ] story [ 208 ms ] thread
Nice to see some of the differences clearly laid out.
Subjective opinion presented as fact? Say it ain't so.
Weird criticism.

If I say that halloumi is better than tofu, do you not assume I'm talking about my personal opinion? Do I need to make it painfully clear that it's my subjective opinion?

Taste, as much as readability, are subjective so that can be assumed.

Also, if you read the post, you'll have noticed the author is constantly saying "I find this more readable", and engaging the reader with "what do you think?" questions on each point made, which makes it very obvious that they're presenting a personal, subjective view.

> Do I need to make it painfully clear that it's my subjective opinion?

Yes. Because a sentence written in the Arial font, as much as I might find that font distasteful, is more readable than the same sentence written by a Captcha-generator.

A bubble-sort written in Golang is easier to read than the same bubble-sort written in Brainfuck.

Yes, there are exceptions to the rule (I imagine someone who knows Brainfuck, but doesn't know Golang for example), but the rule is very clear in both cases. The clickbait flamewar-inducing headline is saying, essentially, Ruby is the former in the examples I gave, and Python the latter.

We're not junior-high students trying to one-up one-another with cute gotchas. We're technical professionals. We should expect higher standards of communication skills from other technical professionals.

If you mean "I have a useless opinion that no-one should care about," then state it. If you mean "I have statistical evidence that most technical professionals will be able to comprehend programs written in Ruby better than the same programs written in Python," then state it. But don't expect a good reaction when you say the former, while tricking us into thinking you were saying the latter.

Every sentence said by a person is their opinion. That's what saying things is.

Even the "obvious" counter-example, lying, works because every sentence said by a person is their opinion. You couldn't lie if it wasn't.

> If you mean "I have a useless opinion that no-one should care about," then state it.

I don't. People will care about. Not everybody but some will, and that's fine.

> We should expect higher standards of communication skills from other technical professionals.

Reading comprehension is just as important as writing. I expect my peers to know that an opinion is subjective without me needing to say so.

For instance, I would have expected you to not gloss over my last paragraph on the previous post, just as much as I would have expected you to understand, by reading the article, that everything written there is the author's opinion but I guess that wouldn't have been such a good straw man.

This is a matter of style; we encourage writers to write this way and trust that readers know the difference between fact and opinion.

Go through a typical college writing class and the teacher will direct you to delete phrases like “I think” and “I believe” from your writing.

Use the Active Voice.
New Rails 8 feature? (I’ll see myself out).
I get this, and I've started to write this way, because it gets a better response; but it feels to me like it's designed to maximize an emotional response and not a cognitive response, and find I have less trust in people who write this way (Which is most things, i get)

I do wonder how this style of writing has impacted the psychology of argument, I imagine there are others who read this style of writing and assume it is written in stone or as an objective statement, and not a subjective one. This may just be human nature.

I have to say I appreciated but also laughed at the sheer number of the qualifiers you're discussing in your post... "it feels to me", "I find I", "I do wonder", "I imagine", "this may"

I find it makes for less combative discussions. So I like it.

I'd say that these qualifiers are much more useful in informal communication, like HN, and inappropriate for long-form stuff like essays. Essays are longer, more coherent, and denser.
I think it’s more distasteful in the modern clickbait blog world then more intellectual and well thought out books/essays/etc, where your perspective is not designed for a purely emotional response.
“Yeah? Well, you know, that's just like uh, your opinion, man.”
Oh. So this is why clickbait and trolling have increased so dramatically? The kids are being encouraged to do it by their teachers?

Eternal September gets worse when their teachers are teaching them bad habits from the get-go.

you think click bait and trolling have increased dramatically

In your opinion eternal September....

Not that way - only when it's someone else's opinion, not mine.
> you think click bait and trolling have increased dramatically

Assuming "click bait", "trolling" and "dramatically" are all either explicitly defined or implicitly defined by consensus or what have you, this would not be a matter of opinion but of fact, so stating "I think" would either be incorrect or would be an admission of uncertainty about whether the fact is true. If he is correct and honest, he has no reason to add the phrase. If he is dishonest or incorrect, he has reason not to add the phrase.

Additionally, in the context of the full sentence, it would imply that the subject pronoun "this" is causing his thoughts rather than causing the object of his thoughts, but I know what you mean. I think.

What concerns me is that I see quite a lot of writers who don't know the difference between fact and opinion. Without that, the reader doesn't have much hope. Especially when the writer has some incentive to muddy the waters.

I'm all for pieces clearly from a personal perspective. There one can drop the redundant "I think" bits. But often dropping the qualifier turns it from a statement about one person to a universal statement, as with the title of the article. For me this erases the many interesting possibilities in between.

For example, a post title something like, "Which programmers find Ruby more readable than Python?" is way more interesting. The universal is false, but I'm sure it's true for some people and false for others. An exploration of that could lead to interesting ways to think about languages. E.g., is it better for novice programmers? For programmers from non-engineering backgrounds? For programmers with difference cognitive styles or capabilities?

> "Which programmers find Ruby more readable than Python?"

What if you don't care about analyzing the psychologies of programmers, and just want to say why one thing is more readable than another thing?

Readable for whom? And how could you possibly understand why something is readable for a given person or group without touching upon psychological topics? Reading is a mental experience that varies from person to person in many ways. Reading code even more so.
This has always been true. However, the way that you should distinguish fact from opinion is analyzing the content. You should not rely on other people to explain to you which things are facts and which things are opinions.

In a world where people (in general) are capable of distinguishing fact from opinion (most of the time), you can omit the "I think", "I believe", "I feel" crap. In a world where people are bad at distinguishing fact from opinion, you can't rely on the "I think", "I believe", "I feel" crap because writers wouldn't be able to use them correctly.

That the reader should distinguish fact from opinion in no way absolves the writer of doing that first and expressing clearly which is which.
The author relies on you, the reader, to exercise thought? Say it ain't so.
Maybe the blog post title should then be "Why a Ruby dev finds Ruby more readable than Python".

And the post body reads: "Because that's what they're used to." Fin. Roll credits.

Personally, I find Python more readable, because I know Python better than Ruby.

I don't think there's anything inherently more discoverable about @@ to denote a class field. Python instance fields are all prefaced with self, so a bit of cursory Python learning makes it clear.

But yes it feels weird that you can't declare them upfront. (And it gets weirder when using libs like Pydantic where class level fields are used to describe instance fields in (de)serialised objects.)

IMO, Java's static keyword is far more discoverable because it's far easier to google.

As I discovered when trying to figure out what an @ meant in a TS import statement.

But, I'm not writing a blog post about why Java is more readable than Ruby, because that's just, like, my opinion man.

Right, but the goal of an essay is typically not to disseminate certified, proven fact beyond all possible dispute. In fact, many essays argue points that are inherently fuzzy—e.g. an essay on your interpretation of your favorite novel will make an argument for your interpretation but it will never prove that it is the one true interpretation of a novel since that’s ridiculous and impossible.

Often the goal in writing an essay is to share a personal view or experience, and sometimes to get others to share their thoughts on a topic. For example, if you did write an essay on why Java’s static is better than Ruby’s @, it might lead others to engage with you, share their thoughts, and help you learn more or modulate your own viewpoint as a result.

Montaigne, the oft-touted father of the essay as a form of literature, in fact explicitly wrote essays as a means of self-reflection and self-exploration.

This isn’t some technical paper coming from a research lab or standards body, it’s someone interested in a particular topic sharing their thoughts on that topic, potentially influencing others and potentially being influenced themselves.

You get facts from measuring devices, not people. And even then, when you read the number on the display, or try to figure out if the device is functioning correctly, the facts instantly become opinion again. If it helps you, prefix everything that everyone ever says from now on with "It is my opinion that..." e.g. "it is my opinion that it is 6 o'clock."

The "that's just your opinion, man" thing is the only thing I'd like to see as a universally ban-worthy offense on the internet. It's an entirely empty statement that can be made about anyone who said anything, is always a bitter defense against somebody who took the risk of putting themself out there, and shouldn't be seen as anything but a troll.

And I'm fully aware that this is my opinion, which is why I said it and not someone else.

No. If the author were truly trying to present this as fact there’s be far more remarks against anticipated disputes “pythonistas will say… blah blah blah… but here’s why they’re wrong” or more extreme statements, “it’s an objective truth that… only fools would deny…”

The author doesn’t do any of this, in fact the author is barely even arguing a point. It’s pretty clearly an opinion piece. Human beings have been writing like this and differentiating between fact and opinion for centuries. Demanding that all writing be watered down to hedge-laden statements and statistics would land us in a very boring world indeed. People can read, judge, and think for themselves. We don’t all approach literature like computers reading instructions.

Currently I’m working in a large ruby codebase and previously I was working with Python and Go. Until this moment, I do prefer Python.
Both Python and Ruby can become extremely hard to read if you start leaning heavily on the metaprogramming parts. When I was learning ruby on rails circa 2012 I frequently got frustrated with libraries writing their own DSL.
Interesting. Even with the examples given, I found Python considerably easier to follow, with the possible exception of the inheritance example.

Just goes to show how subjective it all is!

I agree, ruby's @ and @@ probably will make it a bit harder to read for anyone that is new to both languages, plus it seems more lengthy to me, python wins.
As an aside, it's bad practice to use @@ variables (IMO), they're easily clobbered. Class instance variables are much better[1].

I might also add, if you create getters for an instance variable then you don't need to use the @, except in the getter itself (and you don't even need to do that as there is the `attr_reader` helper for that).

[1] https://maximomussini.com/posts/ruby-class-variables

Indeed. I started working with Ruby for at least a year before I started working with Python. To this day I still can't do anything useful in Ruby, and I'm proficient in Python.

Python is far more readable and comprehensible than Ruby.

Haven't even bothered to read TFA because it's just weird flamewar bait.

Yes, up until the mention of multiple inheritance, I thought the post was mediocre satire.
Same. The amount of boilerplate and "unnecessary" symbols in Ruby make it considerably less readable to me. The Python examples aren't just readable, they're glanceable.
I find Ruby to be more straightforward than Python. In isolation, I’d argue Ruby is greatly more readable and understandable than Python.

In practice, Ruby code isn’t. Once someone starts doing advanced meta programming, get the shovel, because you’re going to kill whoever wrote it and need to bury the body.

Rails largely gets away with this by having opinionated design, good documentation, and a large user base who have already written answers to your questions.

That really mirrors my experience as well. Ruby is a very consistent language but I think one of the things people get really enamored with Ruby is the meta programming -- myself included and soon you're going to need a bunch of context in your head to understand all the "magic" that's happening.
I feel this comment so much. Having never done Ruby programming and was given a task from a client to work on a Ruby project. I didn't think much at the time because having dealt with all kinds of programming challenges I was confident in taking it on. Much to my surprise the amount of "magic" methods, meta-programming and anonymous classes in the source code required a lot of hand holding from the devs who had been working on it from the start to teach me how to find/read and debug everything the "Ruby" way.
> required a lot of hand holding from the devs who had been working on it from the start to teach me how to find/read and debug everything the "Ruby" way.

Yes. And even just _finding_ relevant bits of code is difficult and painful, because you can't simply `grep` for the names of these metaprogrammed methods. They're simply not in the codebase.

> Once someone starts doing advanced meta programming, get the shovel, because you’re going to kill whoever wrote it and need to bury the body.

Metaprogramming in application code is one of those trends I'm glad is behind us. Might look cool and work great initially, but a painful refactor is near inevitable once there's been some turnover on the team and the problem space shifts in a way that invalidates the underlying assumptions.

Library code is another matter though.

I think that misses the point. Ruby doesn’t have macros! The metaprogramming makes it possible to create very readable DSLs but it’s all very consistent not “magical” like macros.

At the end of the day coding is hard. I’d rather have nice DSLs to learn than verbose spaghetti to read.

Absolutely. DSLs are a great application of metaprogramming. Same with libraries like ActiveRecord.

Metaprogramming in a pull request at work? Nope. I'm going to smack some knuckles with a ruler. :)

Depends. In library code? Great (probably). In application code? That's a paddlin'.
I chuckle-snorted at the Simpsons reference. Thanks you for that.
> Once someone starts doing advanced meta programming, get the shovel, because you’re going to kill whoever wrote it and need to bury the body.

This is why Elixir makes me hate life sometimes. They took a language like Erlang where it seemed almost impossible to write an unreadable program even when it was doing very sophisticated things, and Rubied it up.

Until metaprogramming, autoloading, DSLs and everything that eventually makes Ruby code unreadable takes place due to personal preferences.

Ruby is clever, it can be beautiful, but I've never seen a good codebase using it grow well without enforcing strictly opinionated ways of writing it to ensure maintainability. Which breaks a lot of the expectations of some Ruby developers that chose the language because they like to write it in their own way.

> Ruby is clever, it can be beautiful, but I've never seen a good codebase using it grow well without enforcing strictly opinionated ways of writing it to ensure maintainability. Which breaks a lot of the expectations of some Ruby developers that chose the language because they like to write it in their own way.

Yeah, this is one of the major disadvantages of Ruby. Every Ruby shop of any size has its own idioms and internal code style, which means a lot of unnecessary overhead when onboarding new people. Even experienced devs need to take some time to feel out their team's norms.

The expressiveness also lends itself to bike shedding - I've seen many a PR comment questioning why a dev chose method A versus method B, where method B is an alias of method A. Probably an hour of staff time spent on something that has zero impact on functionality, maintainability, or performance.

> without enforcing strictly opinionated ways of writing it to ensure maintainability

But a team cannot have its own opinions with Python. They're already built in.

A team can absolutely have its own opinions about Python. “There should be one— and preferably only one —obvious way to do it” from the Zen is very much aspirational, rather than a declaration of an immutable truth about Python and it's ecosystem.
> Ruby is clever, it can be beautiful, but I've never seen a good codebase using it grow well without enforcing strictly opinionated ways of writing it to ensure maintainability.

I believe every good maintainable software needs an enforcing strictly opinionated ways of writing it to ensure maintainability.

Language need be general to be useful. Any language can create utterly unmaintainable code. If you shift "opinionated" into the language, it is less easy to write unmaintainable code, but it is also more difficult to write fitting maintainable code because that "opinionated" opinion may not best fit (and usually can't best fit) a specific application, a specific team, and a specific set of experience. On the other hand, if we shift "opinionated" to the programmer, the language inevitably need add more meta-programming ability or simply more ways to do the same/similar thing. The code can easily become unmaintainable under less experienced programmers who are not opinionated and aren't disciplined.

The current programming culture expect programmers to be commodities, thus favors opinionated languages and idiomatic code. I can easily imagine a shift in culture that favors experienced and opinionated and disciplined programmers, where different set of languages will be favored.

Today's software, once grow to certain size, are all quite unmaintainable.

I find it odd that getters and setters are implemented in Ruby … manually. attr_accessor is the idiomatic way to do it (or attr_reader / attr_writer if you want more granular control).
It's for encapsulation. You can switch them out for a method with logic without changing your interface. I don't know Python very well - is that the same there?
You can override the relevant dunders, but why would you.
> but why would you

To migrate an API - that's what I said.

Apologies - I mean “the author implemented their getters / setters in the ruby example by writing actual methods by hand. The idiomatic way to do it in ruby is to simply write: “attr_accessor :title”.

There’s no change in interface needed in the ruby example if you decide that you want to replace that with fully-written getter/setter methods like the post shows; attr_accessor generates exactly those same signatures for you.

Yes, you can replace attributes with properties without changing the consuming code. For example:

    >>> class Foo:
    ...     @property
    ...     def bar(self):
    ...         return "hello from a property"
    ...     @bar.setter
    ...     def bar(self, value):
    ...         print(f"tried to replace bar with {value}")
    >>> Foo().bar
    'hello from a property'
    >>> Foo().bar = "asdf"
    tried to replace bar with asdf
I know it's completely subjective and intellectually irrelevant, but wow I think those annotations are super ugly. In Ruby it's all just method calls - properties, methods, user control-flow, everything.
It's all just method calls in python too!

    @foo
    def bar():
      ...
Is just syntactic sugar for:

    def bar():
      ...
    bar = foo(bar)
It's a bit of a weird take when attribute definition in Ruby also uses at signs specifically. Which part do you find ugly?
> It's a bit of a weird take when attribute definition in Ruby also uses at signs specifically.

No that’s instance variables.

> Which part do you find ugly?

In Ruby to modify a method you just call a method. I guess I think a second, redundant, way to call methods is not elegant.

In Ruby if else is not a method for some reason also blocks are not objects for some reason "seems inelegant"
> In Ruby if else is not a method for some reason

This is because there’s not a good way to pass two delayed computations - two blocks. Looping constructs were replaced by method variants.

> also blocks are not objects for some reason

Yeah they’re reifiable but not sure why not reified by default.

But passing two blocks/lambdas/etc doesn't inherently need to be that difficult it's not in other languages.

I don't know that much about Ruby's implementation but I think both the if else and blocks not being objects are that way to prevent Ruby from being even slower. My understanding is if you turn a block into a proc it gets a lot slower.

Instance variables != attributes? If that's the case what do you call "attribute"?
Attributes are an interface - a getter and setter method with predictable names. They can be implemented with instance variables as the underlying storage, but they don't have to be.
I write Ruby for a living and I'd argue than in my case it has to do with blocks, which are so much more relatable coming from C# than tabulation-based code blocks... To me, it feels much more natural.
Ruby, like so many other good things, is best enjoyed alone :-)

I've loved every Ruby codebase that I've written. I still consider it one of my favorite programming languages, and (in pedagogical terms) one of the best languages for learning "practical" functional programming (point-free style, blocks as intuitive closures, &c.). But when I work with others, I find that all of the things that I love are obnoxiously clever to others, and that the things they love are obnoxiously clever to me.

Python isn't immune to that kind of cleverness, but subjectively it's not as common. I chalk that up to the higher pain threshold for doing really obnoxious metaprogramming in Python, a lower community tolerance for unidiomatic interfaces, and (broadly) better QA tooling (RuboCop is great, but MyPy + isort + Black + flake8 is really hard to beat).

My theory is this is also why Lisp never took off. Powerful macros are wonderful for the solo programmer but difficult for a large team to reason about.
Programmers are not Computer Scientists, and the world is poorer for their conceit.
I think this is a tooling problem, as far as LISPs go, because unlike C, you (as far as I remember, perhaps I'm wrong) aren't relying on the compiler to fill in the bits, the macro is just a shortcut, if you will, to functionality.

Not always transparent, but it should be solved with correct tooling. I think the bigger problem was LISP was far too long tied to LISP Machines, rather than being able to run independently on any hardware, which helped C and Pascal gain traction early

Lisp itself precedes the Lisp Machines for about 20 years, and was available in UNIX workstations as well, in fact that is where Allegro Common Lisp started.
Lisp wasn't necessarily tied to specific hardware, like Lisp machines, but to powerful hardware with lots of RAM and processing power.

The "Unix workstation" of the 1980's was about the most powerful, expensive machine you could get your hands on that still qualified as a microcomputer. No wonder they got some sort of industrial Lisp to fit on it.

Unix ran on a lot less than that before that; what sort of Lisp was there for V7 Unix on a PDP-11, and what were its applications?

PDP-11 could hardly run something like Multics or VMS, adopted a programming language whose genesis was to Bootstrap CPL compiler, let alone having a Lisp.
You're not the only one, "The Lisp Curse"[1] essentially says the same thing (but spends a lot more time praising/criticizing the "lisp hacker").

> The expressive power of Lisp has drawbacks. There is no such thing as a free lunch. > - The Lisp Curse

[1]: http://winestockwebdesign.com/Essays/Lisp_Curse.html

The author of Lisp Curse had no experience with Lisp even in solo work, let alone in a team of two or more people.

It's purely made up stuff.

Lisp absolutely took off and had a heyday.

We are decades past "peak Lisp".

Lisp grew in capability and complexity at a voracious pace and required expensive, powerful hardware, always at the edge of the hardware envelope.

Then microcomputers happened, featuring the power and speed of big iron machines from 15-20 years prior.

Almost no software survived the transition from big iron to microcomputers. Pretty much no operating system, and few programming languages or applications---everything was "rebooted". Microcomputers went through their own cultural evolution, with entirely new software.

Customers were buying microcomputers, including lots of new customers that didn't have computers before, and you couldn't sell them software that wouldn't run (or fit) onto those.

Simple as that; nothing to do with macros.

(Unix jumped to microcomputers because it was a lean, resource-efficient minicomputer operating system; the lag between micros becoming as powerful as minis was not as great (decade or so) and basically dove tailed with the Unix timeline. Unix was ready just as micros were becoming ready.)

If it was about macros, we wouldn't be talking about Lisp; it would be entirely dead. HackerNews would be in written in Paul Graham's small dialect of PL/I or something, which would still be here due to not confusing anyone with macros.

People keep saying this (especially here, lately) but it's a nonsense strawman argument. People can do stupid and sufficiently unreadable things in any language. Further, at sufficient scale - a large, long lived proprietary codebase - it hardly matters, it becomes the local dialect.
Interesting!

I spent a few years doing ruby in pair programming contexts and never had that problem. It was a great experience for me. I guess we didn't have that problem because pairing both gives you immediate feedback on "too clever" and because it's much easier to understand a clever thing if you do it with somebody rather than coming across it later in the code.

Yeah, I think pair programming (and constructive review) go a long way towards ameliorating this issue.
I chalk that up to the higher pain threshold

I never could quite articulate why Python doesn’t resonate with me without hyperbole or snark or both.

But that’s it. Python’s design includes inducing pain deliberately with the rational that I deserve it.

Don’t misunderstand me. I think Python is useful. It is just that I don’t find it enjoyable and I inflict enough pain on myself with my code.

It’s not that you “deserve it”… it’s more like having an electric fence, the non lethal kind used by farmers all around the world to stop various livestock from knocking over fences in an attempt to eat the grass or mate with the animals in the next field over. It’s a strong discouragement. It’s unpleasant enough that collectively everyone just avoids it, why put yourself through the pain to do it that way when there’s another way to get it done that’s not going to hurt.
I’d rather eat well and get laid. YMMV.
> I chalk that up to the higher pain threshold for doing really obnoxious metaprogramming in Python

If you're going to quote it, don't you think you should quote the whole thing? The whole point of making the pain threshold higher for certain kinds of metaprogramming painful and obvious.

I think that is a good thing. You can use it when you need to, but when it comes up in a code review, it's extremely obvious that you are reaching for a powerful tool which can (and in my experience, almost always) impedes ease of code readability and reasoning about behavior. These things are toxic to growing organizations with growing teams.

It sounds a reach to misconstrue that the design "includes inducing pain deliberately with the rational that I deserve it" -- it's not that you deserve it, per sé, but you may not be using it for the use case it was intended for.

My use cases have spanned decades of experience across dozens of organizations serving billions of dollars of industrial strength pressure. Having used other languages (including Ruby, Java, Go, Scala, Cxx), accounting for tradeoffs between ecosystem maturity and language flexibility, it remains my overall top choice for getting work done and building durable, maintainable codebases.

The important thing for me is that the pain is by design.

That someone thinks it’s good for me doesn’t justify the deliberate application of pain to me.

I don’t mind that “it works on your machine.”

My distaste for Python’s philosophy is my distaste.

I simply think my life is richer without aspirations to be Pythonic.

And now I can put my finger on why.

Thanks.

(comment deleted)
It sounds like we're talking past each other. It appears to me (and I may be wrong here) that for you, writing code is an activity that you partake in for pleasure, or otherwise aesthetic or artistic reasons. For me, while there are elements of writing code that are pleasurable, I predominantly engage in it in a professional setting, to get business goals accomplished.

In the former case, I think that having a "distaste for it[Python]'s philosophy" where one's life is "richer without aspirations to be Pythonic" is pretty reasonable.

In the latter case, there isn't as much room for that. Instead, the more practical considerations I mentioned predominate: the question is how to get the most mileage out of language in a large organization to accomplish large, complex business goals with technology in a durable way.

It's not to say that one or the other is more important (I think there is plenty of space in this world for both), but I would say that the vast majority of ecosystem space around programming languages is and very likely always will be taken up by the latter use case. If you're curious about why things are the way they are (which you may not be, or which you may simply not care about, or which may simply not apply to you), then I think it's worth considering.

Yeah, Ruby is like poetry.

Most poetry is like https://hitchhikers.fandom.com/wiki/Vogon_poetry.

And the worst is that I'm unable to do poetry.

---

I'm enthusiast about learning about languages, and enjoy everything I see about APL, Ruby, Scheme, Forth, Haskell, etc. I actually LIKE the concepts.

Is kind of relaxing take a look around the basic tutorial or read what the "good" poets say about that.

But my instinct tell me it will be torture to live like a poet.

So, for actual work, is much better (for me) all languages that have restriction and strict ideas about stuff.

- Python FORCE indentation? SOLD!

- Pascal DEMAND declare all before use? GIVE ME MORE!

- Rust SMASH YOUR HEAD at every keystroke? SHUT UP, TAKE MY MONEY!

I can answer this.

Ruby is my favourite language!

Am I a haiku

Well, the second verse

has an extra syllable,

but that's fine by me :)

Ruby is too flexible for me to ever want to work on a Ruby codebase.

Also, those ruby examples aren't readable, I have no idea what your sigils and double sigils are doing beyond giving me Perl flashbacks.

(comment deleted)
I initially thought this article was being sarcastic. After each comparison when they said Ruby was more readable I thought they were joking, until we got to multiple inheritance.
There's more than one way to write the corresponding Ruby snippet. If I had been writing it, I might have translated it something like this:

    class BlogPost
      class << self
        attr_accessor :count
      end
      self.count = 0

      attr_accessor :title, :body

      def initialize(title, body)
        @title = title
        @body = body
        @published = false
        BlogPost.count += 1
      end

      def publish!
        @published = true
      end

      def to_s = @title
      def count = self.class.count
    end
This avoids needing to understand what `@@count` means, and lets you use the same syntax as in python: `BlogPost.count += 1`.

Or, if I were in a codebase using static type annotations with Sorbet, I'd do something like this[0]. To each their own, write code in the language and style that makes the most sense to you.

[0] https://sorbet.run/#%23%20typed%3A%20true%0Aclass%20Module%3...

That’s without even mentioning the footguns available in @@count

Jez!

Ah sure, this alternate implementation assumes that the BlogPost class is final and never subclassed.

If you plan to subclass BlogPost, the translation is not identical, as the alternate implementation would not keep track of a global count of posts across all subclasses, only of `BlogPost` instances exactly.

Depends who accessed it first ;)
I saw you closed my ticket on sorbet for generics + sealed + exhaustiveness, that’ll allow some very welcome code cleanup!
“ I didn't work hard to make Ruby perfect for everyone, because you feel differently from me. No language can be perfect for everyone. I tried to make Ruby perfect for me, but maybe it's not perfect for you. The perfect language for Guido van Rossum is probably Python.”

“I hope to see Ruby help every programmer in the world to be productive, and to enjoy programming, and to be happy. That is the primary purpose of Ruby language.”

- Yukihiro Matsimuto

Maybe I am an outlier, but the few jobs I have had with a ruby codebase have been super fun and relatively easy to pick up. Every project has a learning curve, and I have experienced some pretty bad ones that were not written in Ruby.
Moving to Python from Ruby, one very early scarring experience was battling trying to get the length of a string, before eventually discovering len() - a free function, whereas in Ruby (OO purist that it is), everything is a method.

Well I thought this was rather silly and counterintuitive of Python, and said so in some forum or other, whereupon i discovered the very passionate views of folks who have come down hard on one side or other of this debate.

So, lesson learned: keep one's opinions on such matters to oneself, as one man's banquet is another's poison. In which vein, it would be splendid if this comment did not occasion another screed about the manifest glories of __len__ to enlighten us heathens.

> was battling trying to get the length of a string

This makes it sound like you where trying to learn the language by typing in random stuff and just hoping something runs.

Yes every language will leave you scared if your path to learning it doesn’t even involve reading a single page about its most basic functioning.

What an extraordinarily patronising response !

Firstly, not 'scared', 'scarred' - merely a bit of harmless hyperbole to indicate a briefly frustrating situation.

Secondly, this is not monkeys-at-typewriters, merely an expectation that Python would conform to any other object-based language and have a public method on string to report its length. This should be a discoverable, not an RTFM case.

While I agree with you the grandparent was unnecessarily patronizing, they do have a point. “Built-in functions” is the first chapter of the documentation following the introduction, there’s no way to miss it. If you don’t even skim the introductory documentation, I’m not exactly sure what you expect to happen. Python is not Ruby nor is it Java, and it predates both. Why would it follow the idioms of those languages?
It does have a public method, __len__(). It’s a protocol method that’s more discoverable than size/length/len/count or whatever other ad-hoc name.
Yes I'm aware, and yes it's 'public' in the sense that all Python methods are but my point was that it is not meant to be called directly. The whole argument as to whether or not this is a superior mechanism was exactly the cause of heated debate the first time around and something I was keen to avoid here!
Does Ruby have support for just exporting functions around? All these examples are class based. When I was a Python programmer, we found functions scaled infinitely better over time (with the exception of data classes, unfortunately) for complex business logic especially.
No, unfortunately. This is one thing I've always wished Ruby had.
Ruby is object-oriented, for better or for worse. Similar to Java, you can have static methods, but they have to live in a class (or module in Ruby's case).
I assumed OP was asking if Ruby had a way to import specific functions from a module (i.e. "from math import pi".) the way that many other languages (like Python) support. Instead, Ruby forces you to require the entire module, which makes tracking public interface usage harder.
If you're looking for that level of granularity, you can implement each method as a class, or as a static method on a class or module. Then it's fairly easy to figure out where things are used.
Not sure what you mean.

You can do…

    module Foo
      extend self

      def bar
        “Bar!”
      end
    end

    Foo.bar #=> “Bar!”

And you can include that module in other modules. No classes required.
In python you can ‘from foo import bar, buzz’ and get JUST those two functions, without having to prefix them or clobbering your namespace.

This really nice when the one function you need is giantlib.helpers.foobar.convert_baz_to_qux - it’s both less bytes (especially if you are calling it a lot) and more importantly to the next reader of the code it means that c_b_to_q is the only thing you’re using in giantlib

I see. Yeah because of this Ruby kind of pressures thoughtful coders into small modules. Heck, I created Ruby Facets and it’s basically one method per file!
I think the smallest footprint would be a module ? Importing a module add all the functions declared in the module to your current scope. From memory, you can't restrict to one or two specific functions, but in practice it's rarely an issue.
Not really. Your options would be implementing one class per method, static methods on a class/module, or making a module you can include in classes that need them.

I tend to go with static methods on modules.

I think he proved the opposite case -- and gave examples, too!
Surely there's a correlation between ease of reading and ease of compilation?

I'm thinking in terms of avoiding back-tracking in your syntax.

E.g.: regices are hard as shit to read, and I don't think that back-tracking helps

   (ab + c)*
Or

   *+(ab, c)
The first says ab, no - it's the union of ab and something, something is c, no - it's one or more of those.

The second says one-or-more of the union of (ab) and (c).

Why haven't languages pushed that way?

> regices

Please no. It's bad enough that people insist on using foreign plurals in English, let's not pretend "regex" is some latin word (it's just REGular EXpression).

Words are about the only damned thing where mere belief conjures existence.
Also, if you're going to bother to reply, reply to the content - rather than the terrible pun that I through in for the sake of my own bored amusement.

I'm a fucking programmer (at very least I'm a dude commenting on HN) - I know what regex is short for.

The article closes with this thought:

> While both languages are much easier to read than say, PHP or Java, [...blah blah blah...]

Which leads me to wonder: Have there been any serious studies of the readability of programming language syntactic and semantic conventions? For instance, a good friend of mine (whose day job is working as a software consultant, and whom I imagine would disagree with the author's assertion) finds it extremely difficult to understand python code in particular due to his dyslexia, and I wonder how common such problems are, both as a % of people and % of programming languages.

PHP has a bunch of hacks that are here for technical reasons. Function names are inconsistent and terse because they were inherited from C, and there is the historical name-resolution quirk. The prefixed variable names don't bring anything and are not here for any good reason (compared to shell where "naked" identifiers are interpreted as strings). A lot of the object-oriented features had to settle for unusual tokens like backslashes. You might find that the PHP syntax is objectively problematic.

For Java, Rust, etc it's a bit different. I would say that's up to taste. Using "public static" is very verbose but more obvious than @ or _ prefixes.

I agree with your specific assessments here, but I was trying to get at the question of whether there are meaningful and measurable differences in the broad-scale accessibility of e.g. whitespace-centric syntax vs lispy syntax vs curly-brace syntax.

Admittedly, it's hard to tease this apart from the standard library and communal conventions of any given language: Java occasionally devolving into an endless sequence of ProducerFactoryFactory.newProducerFactory().initializeProducerBuilder(new ProducerBuilder())... certainly impacts its readability in a practical sense, just as the Haskell community's perhaps ill-advised love of point-free programming and highest-order polymorphism doesn't always do it favors on the readability front. Those sort of details seem like they'd really complicate a rigorous and systematic study, but on the other hand, lacking a good methodology has never stopped _other_ supposed quantitative studies of programming languages as they relate to e.g. "developer productivity" and "defect rates," so who's to say...

What’s the historical name resolution quirk?
With better unicodes I wish computer language could use fancier characters to express loops, conditionals and in general without using the english language. goodbye to [if, else, switch, break, lastly, each etc..] let us crate a language that uses no letters but unicode symbols to express abstractions. Like emojis.
Please no.

Font ligatures are bad enough

You can use Emojicode [0] if you'd like. I'd rather keep using Ruby, Go, Python, etc but to each their own.

[0] https://www.emojicode.org/

It makes sense to go the emoji way. We already get emojis on our IDEs with lightbulbs, lightnings and the dreaded red x mark.
I read through the article waiting the whole time to see that "this is more readable", but I found nothing. Also I'm not sure if the Python examples are so blatantly wrong on purpose or if the author read one Python tutorial beforehand and then decided to write this article. For example this:

> In Python, you will never do post.__str__ for example. Instead, you’ll do str(post)

No you dont. You do the same thing you did with `puts post` in your Ruby example: `print(post)`, which will call `__str__()` method.

> In Python, it’s easy to accidentally write to the count attribute — which can break your program.

To address writing into attribute directly - you can use @property decorator, which will stop you into writing into given attribute, unless you add a setter.

However the main problem in this fabricated example wouldnt be that you can break your program by accidentally writing into an attribute. I'm not sure how common is it in Ruby, but mixing the instance variables together with class variables this way seems like a bad design, and that is what will break your program.

Regarding the Django example - ok that is far from perfect, but comparing a framework which maintains backward compatibility for years with code you write from scratch without worrying about anything is barely a fair comparison.