return to table of content

I Love Ruby

bakuninsbart
38 replies
20h2m

I think the point about expressiveness is exactly what makes ruby so divisive: It is great when you are deep within the ecosystem or do exactly what the ecosystem expects you to want to do, and an absolute pain if you want to do anything non-standard.

The supports_feature-method is probably defined somewhere 5 abstractions deep. If you are lucky that is, it might also be part of some library's weird meta-programming of supports-* that no LSP can point you towards. I've never worked in an ecosystem that celebrates implicitness as much as ruby does, and it is driving me nuts.

The fact that finished code looks great and reads well doesn't balance the scales in my book.

rezonant
20 replies
13h41m

The supports_feature-method is probably defined somewhere 5 abstractions deep.

Yes, but pro tip: you can do object.method(:supports_feature).source_location to inspect where it comes from. It may be a module included into the class, the class itself or one of its super classes, or a concept built on modules like ActiveSupport "concerns". But source_location works in almost all cases.

might also be part of some library's weird meta-programming of supports-* that no LSP can point you towards

Yes, if this comes from method_missing, you can't check it's source_location. You need to use your knowledge that the method name works and that method_missing is how such things are done, and then you do object.method(:method_missing).source_location and read the logic there.

The lack of safe and reliable IDE introspection and design-time type support are my number one issue with Ruby, and why I tend to use typed languages instead.

However, there are workflows for inspecting a codebase that work, they just don't fit in well to the usual LSP+IDE pattern. You are expected to use irb/rails console to do your inspection of the structure and behavior of your programs.

vidarh
18 replies
8h50m

To me this is why I don't like IDEs.

My Ruby projects often have a wrapper that reloads code and puts me in a pry prompt. I can edit code and introspect objects live as the code changes.

It's a natural extension of Ruby's Smalltalk legacy.

I recently replaced my X window manager with one I've written in Ruby, and I can just attach to it and modify state or change code live to test or fix things.

Being confined to JS and Java in VS Code for work is like having one arm tied behind my back.

rezonant
5 replies
7h22m

Indeed, the live interactivity of Ruby is it's strongest asset, and the best part of it's Smalltalk legacy. I think it's the thing non-Ruby devs understand the least. For instance in good Rails apps, your models don't just serve as the business layer of your web forms, background jobs and rake tasks-- they serve as the interface for developers and operations folks too. The ability to get directly into the machinery to inspect and command the state of your systems is super powerful, and as a result, very little work is put into higher level ops tooling like it might be in more opaque systems.

This is true in the dev space too. In dev, you can just set breakpoints by inserting a pry/byebug call and the debugger is just part of the application at runtime. Can you do it in a sufficient Ruby IDE too? Of course. In my experience this isn't super common though, and isn't going to give you the best debugging experience, because it's separating you from that hands on direct inspection context.

And IDEs like Rubymine like to think that the excellent deterministic automatic refactorings of languages like Java are actually feasible in a Ruby codebase, but I have seen that first hand go horribly wrong with a developer who trusted them.

darkwater
2 replies
6h47m

The ability to get directly into the machinery to inspect and command the state of your systems is super powerful, and as a result, very little work is put into higher level ops tooling like it might be in more opaque systems.

Yes, but this is something that IMO didn't age too well when we transitioned from pet servers to cattle servers (and that's even more true in a serverless scenario or even just Kubernetes). I'm not saying that you can't do it but 1) it will discouraged by security best-practices in most places 2) the Ruby in which you are in might disappear under your feet in a second

vidarh
1 replies
6h25m

Yes, but this is something that IMO didn't age too well when we transitioned from pet servers to cattle servers

A significant part of the utility is in development, and that doesn't go away.

I'm not saying that you can't do it but 1) it will discouraged by security best-practices in most places

I've yet to see an ops team (I've been involved in ops work for 28 years at this point) that doesn't have plenty of escape hatches, irrespective of the language. One can pretend that it's locked down all one wants, but the moment the ability to open a root prompt in a container exists that is just an illusion.

The most brutally locked down systems I've seen still wouldn't usually prevent you from getting access one way or another (sometimes the means of getting access have been painful, like going via an IPMI console or other "fun" detours, on a very few rare instances it's required physical presence in a specific location; most places the most locked down setups you'll tend to find require a VPN or going via a bastion host), but would ensure the containers were destroyed after you exit (to prevent cattle from turning into pets... so you can debug but not leave changed state).

I'm not saying there aren't people who actually lock their systems down to a point where their ops team can't gain access to use a console; but I am saying that even a lot of places where people think that is the case, it often isn't actually the case. It may well be locked down too much for developers to be able to use it to debug in normal circumstances, though. I'd rather people are honest about it and secure and restrict the access properly than pretend there aren't workarounds that are in regular use, as I've seen way too many times.

2) the Ruby in which you are in might disappear under your feet in a second

If you don't have a way of mostly preventing processes from being killed when a connection is ongoing, that is a choice you made. If your technology is fighting you because of choices you made and you keep it that way, that is also a choice. Maybe it's right for you, but no system I've built would randomly pull the rug on me other than due to actual system failures.

williamcotton
0 replies
4h41m

but I am saying that even a lot of places where people think that is the case, it often isn't actually the case.

Yup, one day someone was poking around our mess of over-engineered k8s web app ephemera, clicked a button, and realized we finally had a working Rails production console, albeit one in a web browser, without our tooling, and that would drop connectivity every 15 minutes. When this was discovered this was told to be all part of the plan… welcome to the spin zone.

williamcotton
0 replies
5h4m

they serve as the interface for developers and operations folks too. The ability to get directly into the machinery to inspect and command the state of your systems is super powerful

Which was awesome and super efficient and kept developers close to the production environment and the necessary knowledge of that context to properly build applications.

Then DevOps came along with a bunch of great new ideas…………

vidarh
0 replies
6h53m

I think you're right many don't understand it, but also many who do understand it a bit seem to be scared of trying to embrace it, and so never really experience the power of it.

Even within the Ruby community a whole lot of people just stop at fairly basic exploration in the Rails console and don't explore the full level of flexibility they get you.

And I think a good Ruby IDE would be one that tried to be more of a Smalltalk like environment - if you want to refactor Ruby code, you're far better off starting by introspecting an actually loaded app environment rather than starting from a static parse.

quickthrower2
5 replies
7h26m

Do you mean you do all coding, including file saves in a REPL? Just trying to understand.

rezonant
3 replies
7h17m

They explain elsewhere that they use an external editor, though they do sometimes use pry's builtin shortcuts and EDITOR convention integration to perform quick edits.

vidarh
2 replies
6h58m

I'll note an additional take on this, represented by my editor to illustrate just how far down the rabbit hole this goes with Ruby:

My editor is in Ruby, and uses DrB to talk to the backend. It has a key combination to throw me into a pry prompt, and also throws me into a pry prompt if any exception is thrown. Since DrB will forward any exceptions during the execution of any messages (and here we really see the message passing bit - they are literally messages passed over a socket and via proxies that don't know what they mean) back to the client, this means that any exceptions in the server will throw me into a pry prompt where I can dynamically edit the code of the server process and continue execution.

The server process holds the open buffers, and I can reattach to it, and thanks to that use of DrB I was able to switch to using my own editor day to day at a point where it was still wildly unstable without losing any data. Sometimes I'd edit the editor with itself while it was in a broken state, and reload the offending code to fix things and just keep working.

With most other languages - with a few exceptions - I'd have to wait until I had something more finished and more stable to start using things. With Ruby I often feel comfortable with starting to use projects while they're still crash-prone and half-finished and lacking because it's so easy to metaphorically replace the engine in mid-flight.

rezonant
1 replies
6h54m

Fancy, custom editor or something that's out there?

vidarh
0 replies
6h36m

Very custom, to the point that the current iteration is dependent enough on a bunch of details of my environment (part of this is an ongoing drive towards minimalism - e.g. the editor doesn't know how to open files or select buffers or select themes; all of those things are delegated to scripts that currently use rofi) to the point I'm not convinced it'll even start on someone. I'm slowly cleaning it up to at least pretend it might work for someone else, but that means also deciding on a cleaner interface to the helper scripts so I don't have to package up my entire environment in one go.

The beauty of the DrB part of it, though, is that the shell of that is very small: Just spawn a DrB server, spawn a client, and wrap the client in a begin/rescue block with binding.pry, and put any critical data on the server side. Suddenly your server-side is near crash-proof and your data much less likely to disappear. If you want an extra level of protection, run a threat on the server side to checkpoint the data regularly (I used to checkpoint it every 5 seconds at the start; it's now at around 5 minutes, which also means every buffer I've opened and not bothered to kill from the last 5-6 years are still accessible... I never bothered to add code to clean them up as they just don't take up much space)

vidarh
0 replies
7h15m

You can do that. E.g. pry has an "edit [methodname]" command that will spawn $EDITOR. But I usually keep my editor in a different window and just call a "reload" method at the pry prompt where I've wrapped up the logic to reload the running code.

Occasionally I may restart, if e.g. object state has changed enough, but this means that if I've set up a bunch of test data for example, and run into a bug, I can fix the bug, "reload", and the state of the running objects remain the same but the method will have updated and I can retry the same method call with the exact same object state.

busterarm
3 replies
8h18m

Shh, you're giving away our secrets. :)

Just let the bliss wash over you and ignore the haters.

vidarh
2 replies
7h40m

Hah. It always seems to me in these threads that a lot of the hate starts from a point of not understanding the language very well. If you're used to seeing working on a software project as a static, batch-oriented process, Ruby - like Smalltalk - is alien. When people then try to force it into a batch-oriented process they're throwing out so many of the nice things I'm not surprised they dislike what they're left with.

But I don't let it bother me. I instead enjoy rewriting an ever-increasing part of the software I use day to day in Ruby (my editor, shell, file-manager, contextual menus, menu bar, font renderer, window manager so far - I keep telling myself I need to stop myself before I start writing an X or Wayland server too, or even worse, before insanity takes me and I start writing a browser)

bbkane
1 replies
7h26m

You should make a "my tooling" YouTube video or GitHub org- I would love to see your unique little tool ecosystem

vidarh
0 replies
7h12m

I'll do something once I've cleaned it up a bit more. It's a bit all over the place at the moment as I went on a bit of a spree this autumn and rewrote whatever annoyed me, and one of the luxuries of having done this pretty much just for my own use is I haven't had any strong incentives to make it pretty... But I do intend to tidy it up and when I do I'll at a minimum do a writeup.

geospeck
1 replies
8h23m

My Ruby projects often have a wrapper that reloads code and puts me in pry prompt. I can edit code and introspect objects live as the code changes.

That sounds very interesting! Can you please share the wrapper that does all that magic? Thanks!

vidarh
0 replies
7h55m

Pry provides most of the value, so my script is usually basically just something like this:

    def reload
       load "app.rb"
       # If you want to load multiple files, remember that if app.rb 
       # uses require/require relative, the files will only be loaded 
       # once; you can change that but really it's not usually what 
       # you want for production; in that case either look into a proper
       # reloader, or you'll want to load the rest of the files here.
       # Sometimes it's  fine to e.g. do a Dir.glob("*.rb").each {load _1}.

       load "dev.rb" 
       # Put "dev niceties" in this file. E.g. maybe load table_print or
       # awesome_print, Hirb,  or whichever nice formatting tools you
       # want, or define any custom introspection methods that are
       # helpful. Eg. for an analytics project I worked on had a few tools to
       # wrangle CSV test data there. (I really ought to extract the best
       # from my various projects into a gist or something, but these 
       # files often accumulate really project-specific stuff.
    end

    require 'pry'

    reload
    binding.pry # Throws you in the Pry prompt at the top level scope.
It does require that you're somewhat careful not to make the loading of your files too stateful, which is a good practice anyway, and you do need to be mindful that things will occasionally fall apart if you reload the running code as it will modify the classes of objects that already exists but not e.g. update their instance variables, so if you add a method that expects @foo to have been initialized, but existing objects do not have it initialized, things will go obviously go badly.

Since pry supports "edit some_method_name" and will spawn $EDITOR you can even do edits in the same terminal that way, but I tend to prefer to have my editor open in another window. (And since so many here seems to struggle to find methods, in addition to "edit", "show-method some_method" in the right context in pry is also highly useful)

Sometimes I'll keep ways to trigger pry in applications during regular runtime because it's so useful for debugging issues, and sometimes even fixing issues in a running process.

EDIT: While I prefer pry, it's worth noting that Irb has gotten a lot better (lots of features from pry) in recent versions, and also "rdbg" (debug gem) is awesome if you don't want to use a separate script like this - you can equally well run your code under rdbg and just have a script handy to load tools you want for a debug session; the downside of rdbg is if e.g. attaching remotely you'll be running in a trap context, which means you don't have quite the same freedom with respect to what code you can actually run - that may or may not matter.

gorgoiler
0 replies
7h24m

At its heart, Ruby just doesn’t do static analysis. Program behaviour is defined at runtime and at runtime only. This ethos is why method calls in the language are implemented with message passing and also why everything is a mutable instance of Object.

The behaviour of a Ruby program, right down to the types and methods available, is only defined by running the program itself. It allows for all the glorious freedom of meta programming for which the language became famous as well as the often times inscrutability of the source code.

With a language like Python, the source code at the start bears a good resemblance to the structure of the program when any particular function executes.

With Ruby, the source code at the start of a program is merely a hint as to what the ObjectSpace will contain when your particular function ends up being called!

Doctor_Fegg
7 replies
18h56m

The supports_feature-method is probably defined somewhere 5 abstractions deep

This is the classic mistake of confusing Ruby with Rails. That might be true of Rails. It absolutely isn't true of vanilla Ruby. The article was not "I love Rails".

madeofpalk
6 replies
15h25m

Does Rails not use Ruby?

lstamour
5 replies
15h15m

It does, but at this point it’s like saying that JavaScript is DOM even though you can use it outside a web browser. Or it’s like blaming Python for TensorFlow. Like, yes, Rails is a use case for Ruby, and a popular one, but not the only one.

lloeki
1 replies
8h47m

Agreed. Ruby is not Rails in so many ways, even on philosophical grounds. Rails is full of magic, implicitness, and conventions, which enables a great deal of very speedy development but also becomes† a minefield if you steer away from The Way; while plain Ruby is very explicit and in plain sight, there's no magic. It's a blank page, an open field, it's raw material for creative ground.

Rack or Minitest for example are very Ruby. RSpec on the other hand is full of Railsy magic, just yesterday testing some threaded stuff I was bit by `let` because it has concurrency consequences, and the magic becomes darkness as you have to look behind the curtain and beat it into submission in roundabout ways that obscure the thing you're actually doing.

† or sometimes is a minefield, all by itself, like this nonsense: https://github.com/rails/rails/blob/1512cf2ba578282c898b8eb6...

rezonant
0 replies
7h0m

also becomes† a minefield if you steer away from The Way

Reminds me of Angular vs React-- In my opinion it's much easier to get immediately productive in React, but it's very easy to produce a rats nest over time if you aren't experienced with the framework. Versus Angular which has a lot of upfront learning curve, but it's prescribed structure makes it fairly easy to scale out the app over time.

Rails is definitely more like React in this respect. It turns out you can absolutely color outside the lines and still enjoy the speediness, but it's not something that I experienced devs should try to do without making a huge mess.

heeton
1 replies
8h35m

The point is valid though. Yes Rails is particularly bad, but I've been working with Ruby for ~15 years now, and plenty of non-rails codebases in that time. The metaprogramming and implicitness runs deep in most of the community, it's common to find highly magic and hidden implementations in Ruby generally.

rezonant
0 replies
7h5m

I often find the sort of over-the-top implementations you describe in gems that were written by Rails users. Since other frameworks and vanilla are not super uncommon, it's fairly normal to make your gem that you envisioned being used within a Rails app not dependent on Rails. If those developers read too much Rails framework code (or toxic blog posts from DHH) and got the wrong idea, then it's not surprising they imitated what they thought was the way to do things.

madeofpalk
0 replies
2h8m

If the DOM APIs were full of really bad patterns, or used a bad language feature, then the blame would partially lie on Javascript for promoting those patterns or not having better alternatives.

Ruby is not Rails, but Rails is Ruby.

pqdbr
4 replies
19h53m

In my experience this is almost never the case. #supports_feature? would be defined right there where you'd expect - in that Subscription model.

Even tough you can reach for metaprogramming (like define_method or method_missing), that's really not how the entire ecosystem of guides and tutorials will point you.

Anyways, when in doubt, just plug a debugger and call "@subscription.method(:supports_feature?).source_location`, and generally that's all it takes.

mplewis
1 replies
19h27m

Rails is the biggest Ruby project and it’s heavily based on metaprogramming. Even Rubymine has trouble finding the canonical definition of a named method sometimes – it has to guess. I love Ruby but I totally understand this criticism.

sodapopcan
0 replies
5h4m

Rails is a library, though, the advice applies to application/business code. Metaprogramming is extremely useful for making really simple-to-use libraries. If your business logic is full of metaprogramming, that's more of a problem, especially in this day of age where it's common for developers are only sticking around at any given job for 2 to 3 years.

Fire-Dragon-DoL
1 replies
18h4m

The most common framework in ruby disagrees. It wiuld be 5 layers deep

rezonant
0 replies
7h15m

Well, it would probably be 2-3 layers deep in a concern, really. Concerns are just fancy modules, and modules are just reusable parts of a class. In Rails basically everything is a concern. To a concerning degree actually, as a professional Rails developer of many years, I think they went way overboard with it. My team and I also curse it's single minded design when we have to drill down there. Thankfully that's a pretty rare thing to have to do.

As for the abstraction, Rails does take it pretty far, but you also have to take into account that it's a framework that supports numerous pluggable strategies and disparate backends, and extensibility. I think most mature frameworks are pretty complex-- the goal of the framework is that it's all encapsulated away from you for the vast majority of tasks, and in Rails, that is extremely true.

pdntspa
1 replies
16h54m

It's a pretty simple heuristic to track down the source of metaprogrammed functions... just check for method_missing() or define_function() or a handful of other keywords. I believe the regular syntax is just shorthand for these features anyway.

edit- as another comment points out, you can just do `@subscription.method(:supports_feature?).source_location` too

rezonant
0 replies
6h57m

Another strategy is just to step into the method call in pry/byebug. I've done that for particularly tricky cases. At that point it's pretty easy to walk it up to the mechanism that does the metaprogramming.

znpy
0 replies
6h57m

Weird that nobody is mentioning how poorly ruby is documented on its main site.

There is no proper tutorial, only links to external resources of varying accuracy and levels of update-ness.

It really doesn’t help with grasping such a customisable runtime.

notjoemama
0 replies
16h9m

The fact that finished code looks great and reads well doesn't balance the scales in my book.

IMO this is because software engineers both get bored and feel a need to compete. The more abstract they can make code the better (more safe?) they feel. That lets them play chess on their terms and eliminate the competition. But that's just my take, I may be wrong. Fortunately the most commonly used gems wrap this abstraction into usable APIs, and most have good documentation.

While this can be correctly attributed to ruby or the devs in its ecosystem, I've been on teams with staff using other languages and stacks that let their completion/anxiety fly making it hard to read and understand their code. I guess my point is it's a good critique, but it falls beyond the meta programming in ruby.

tines
28 replies
20h17m

I know it's not the point of the article, but, as a code reviewer, this:

Well written ruby code can often read like natural language. Features like predicate methods even give up punctuation. [...] This is often why ruby programmers don’t like comments. In most cases, the language makes comments unnecessary.

churns my stomach. Good comments are rarely about saying what the code does, they're about explaining _why_ the code does what it does. Regardless of how comprehensible ruby code is, it doesn't change the need for comments. If I had a nickel for every time I gave a commit a -1 review because it had too few comments or the wrong kind of comments or lacked a "why" commit message, I'd be a rich man.

pmgei48t
3 replies
20h12m

out of curiosity how many ruby codebases have you worked on?

stickfigure
2 replies
19h52m

Why do you ask that? I worked in Ruby at Pivotal, with lots of people who espouse the "comments are just lies waiting to happen" philosophy. I agree with the parent, it's wholly misguided. Good comments save many, many hours of rediscovery by people who are new to the code - which includes the original author after walking away for a few years.

If I had to guess, the anti-comment attitude comes from consultants who re-implement the same CRUD webapp on Rails over and over. Sure - no surprises, no comments, fine.

pmgei48t
1 replies
19h41m

'cause i have no trouble reading ruby code without comments and neither do most rubyists in my experience

stickfigure
0 replies
17h32m

Reading code is easy. What's hard is to read the mind of the programmer who wrote it. The reason we argue about Chesterton's Fence is that Chesterton was too damn lazy to leave a comment.

thih9
2 replies
19h41m

The example was: ‘if @subscription.supports_feature?(:feature_a)’.

In a different language you might deal with more boilerplate (getting some data access object for feature status, passing the db connection, extracting the subscription id, etc), or less clear naming schemes (importing namespaces, aliasing them for convenience, your subscription might come from some one letter temp variable), or something else. At this point the “why” comment might be not that different from the actual ruby code.

Note that we only see one line of ruby code; the parent method name, or the if body would have more context.

cloverich
1 replies
18h58m

I honestly found that particular example puzzling. I've written code in at least three other languages that would look nearly identical to it. Unless they were referring to the `?`, or perhaps the lack of a trailing `:` / `{` which seems very superficial to me. Maybe the `@` instead of a `self`? Genuinely unsure.

thih9
0 replies
6h48m

In general yes, there are other languages where this is easy too.

Then again, ruby and rails make it especially easy; perhaps the amount of conventions helps. Other things, like the ‘?’, clean syntax and focus on structure (OO), help too.

maximus-decimus
2 replies
20h6m

My latest comment I wrote was for Ruby legacy code. It was "This method's documentation says it returns a string. That is a lie, it can return an object of any type."

What's even better than comments, is a compiler that actually guarantees you're gonna be given something of the type you expect.

soulbadguy
1 replies
19h48m

To be fair in a weakly/duck typed languages a string can be an object of any type. The fair question to ask would : do those type quack and walk like a string.

maximus-decimus
0 replies
19h46m

They don't, it was returning settings from a json file and so was returning booleans, ints and floats.

jacobsenscott
2 replies
19h50m

I can probably count on one hand the number of comments I've written a comment in over a decode of coding ruby. I've never encountered code I couldn't understand just from reading the code. It really just isn't done in the ruby world. And good - comments are just noise in any language. You need to read the code because comments are wrong often enough (and 1% of the time is more than often enough) you can never trust them.

Consider the overhead of a comment - first you need to read the comment because they are always above the code so that's what your brain will do. This will prejudice your reading of the code.

Then you need to read the code while trying to block the comment prejudice out of your mind.

Then you need to sort of mentally diff the comment and the code, and if the comment is wrong (spoiler...) decide if you are going to delete the comment (the best choice, unless you get a code reviewer who likes comments) or fix the comment (the worst choice, a waste of time, but maybe the only way to get it through code review).

Now consider code without a comment: you just read the code.

tines
0 replies
9h4m

You're still stuck in the mindset that the comment is about what the code is doing. Good comments are orthogonal to the code they're attached to.

t-writescode
0 replies
19h45m

Sometimes you just need comments. I’ve written graphing algorithms that traverse databases in Ruby. I named functions well, too; but the actions I was doing were so weird without sufficient context that when someone might need to change it, 6 months or a year from now, they would have absolutely no idea why I was doing. And no amount of clean code patterns, nor code as documentation patterns would have clarified what was being done as much as the multi-paragraph with ascii art comment I wrote above the function.

Sometimes you just need comments.

stouset
1 replies
20h4m

I love Ruby and this is spot-on. Comments in any language should explain why and not what.

nextos
0 replies
19h55m

Sure, not justifying code without comments. But keep in mind Ruby is a bit like Lisp, where there is a strong tradition of building DSLs.

Hence, lots of Ruby code is a sequence of trivial declarative blocks that look like natural language.

In these parts of the code, comments are redundant. I think that is the OP's point. Other parts definitely need them.

krupan
1 replies
19h51m

Occasionally it's necessary to write code that would make people ask, "why?!?" and comments definitely help there, but I feel like that's generally rare, especially when you use good variable/function names, keep functions small, keep nesting to a minimum, and follow all the other good programming practices. If you are writing/reading code and thinking it needs comments, maybe think a little harder about how the code itself could be made more clear.

Comments are not checked by compilers, linters, code formatters, unit tests, integration tests, or any other automated tools for correctness, consistency, and good formatting. They rot quickly.

tines
0 replies
19h17m

It's not about the clarity of the code though. It's about things that are uncheckable by compilers, linters, etc. That is to say, when I'm reading code I may perfectly comprehend what the code does. But knowing what it does doesn't help me understand why it does that thing, how it fits into the overall design, and things of that nature.

For example, if code is operating on a list, and then it sorts that list and passes it along to some other code, I can see perfectly that the list will be sorted. But that doesn't tell me _why_ it needed to be sorted in the first place. Often that is not knowable except by reviewing things outside the scope of the code in question, or outside any code at all. A comment is essential in that context.

gorgoiler
1 replies
20h9m

One of the features I hope we’ll see in the next generation of source control is having better support for annotating lines of source code with commit message information. We have good old “blame” right now but it’s very easy to lose that information across refactors or reformatting (for example if someone introduces an auto formatter to the codebase, or if you move some code but also edit it such that your tool doesn’t understand the old code and the new code were related.)

Commit messages are such a good place to explain code and I rarely need the same explanation in a comment. I worry though about the fragility of the connection between (a) the source code and (b) the important commits that explain why the code is there.

Perhaps there are some very good UIs out there already that show something a little more intelligent than than the most recent commit from blame?

Another idea might be to attach blame-like functionality to the syntax tree so that the explanatory messaging can be tracked at the function level, rather than as lines of source code. Can others here can point me in the right direction for either a more tangible description of this feature, or an existing research?

tcoff91
0 replies
19h56m

There is a git-blame-ignore-revs that you can configure to keep your git blames more useful.

chihuahua
1 replies
20h5m

Yes, this part of the article seems like nonsense to me. If it didn't have a question mark, we would need a comment? But because the predicate name contains a question mark, that's the only reason why we don't need a comment? That's nonsense.

This only makes sense if we're in the school of thought that writes

i = i + 1 // increment i by one

woodruffw
0 replies
19h46m

This is an uncharitable reading; I don't think the author is literally saying that predicate-style methods are a perfect replacement for comments.

The more charitable interpretation is that they're pointing out the developer ergonomics of things like predicate methods remove the need for comments that might otherwise be reasonable to insert. Whether or not that is true is subject to reasonable debate, but it's definitely a more nuanced opinion than "Ruby's predicate idiom means I don't have to document my obvious code."

soulbadguy
0 replies
20h11m

+1

I would even go a step further : I prefer a cryptic code with good comment explaining what the code does and why it does what it's trying to do vs a very clear code with comment on How the code works.

monlockandkey
0 replies
19h58m

The most challenging part of reading code is the WHY. But is easier said then done when it comes to documenting code with this in mind. Happy medium is to make sure the author peppers in enough context of why something is like this.

krupan
0 replies
19h59m
kazinator
0 replies
19h50m

Some code needs "why" comments, and other code just needs "what" comments (unless it's written in a clear, high level language; then not).

"Why" comments need to go onto code that make some kind of arbitrary decision. Or code which is integrated with processes that are happening elsewhere and has to behave in a way that complements those behaviors. Otherwise the reader would have to read that code together with all those other pieces (or specifications) in order to understand it. Code that is written in a certain way (particularly, an unusual way) for some reason that is not obvious deserves a "why" comment. E.g. "due to a compiler/library bug [give specific version info], we cannot just do this: ...".

Code that doesn't make arbitrary decisions or integrate with things elsewhere, or make unusual coding decision for reasons, often doesn't require "why" comments.

The author of the article hastened to add:

And when you do need [comments], it’s often when you’re doing a very specific or obscure thing that requires context to understand. It’s clear from the code why you need a comment in that case.

It's clear from the code why you need a comment, because it's a "why" comment.

fny
0 replies
19h47m

Also, literate programming is a feature of any language. Sure Ruby has punctuation, but is there enough of a difference between `Array#empty?` vs `Array#isEmpty` to break a absolutely not.

I say this as someone who wrote Ruby for 6 years and loves the language for its other features (e.g. everything is an object, functional programming, DSL-capabilities)

dudul
0 replies
20h3m

Maybe it's a hot take but I even disagree that code that reads like natural language is good.

Is mathematic better when it reads like English? I personally don't think so. Yeah it's a bunch of symbols and conventions to learn but it ends up being more precise.

I dont have anything to back it up :) I just think that natural language is almost by design messy and imprecise so I'm not really looking for that in my code.

dbrueck
0 replies
19h58m

Yes! Well-written code can be a joy to read, but it represents a subset of the total amount of useful information about what's going on in a program or system. Obviously code can be overly and unhelpfully commented, but poorly commented code is usually a very strong indicator of a mediocre programmer.

Why does this function exist? Why was it implemented this way and not that way? Sometimes these are really important bits of info. Here's where this approach breaks down. Here's a sharp edge that we hope to remove someday. This part here incurs some technical debt but this is why we did it.

In order to really maintain a codebase (meaning: safely fix bugs and add new features), you need to have an understanding that at least approaches that of the person who wrote the code originally, and good comments (e.g. level of intent comments) can help you do that. This is true even for your own code that you're returning to after some amount of time.

atomicnumber3
24 replies
20h6m

I love Ruby too. It's a great language, and as a language I like many things about Ruby a lot more than python. In particular, chains of functional operations like:

    arr
       .map{|o| ... }
       .reject{|o| ...}
       .reduce(init_acculm){|init_acculm, o| ...}
are super super clean and expressive. Very similar to what I like about Java streams.

And the library ecosystem is great, I like how it shares spiritual similarities with python where libraries are very "no nonsense" (you don't need extensive configuration and builders and researching a million configuration items etc etc... looking at you, Java) and you typically just import and go. Rails, of course.

I keep picking python over ruby though, for things I'm going to have to actually maintain. And I typically pick Java over python if I smell I'm going to care even an iota about performance. (Often I don't, though). But ruby vs python, I keep coming back to the divergent opinions they've taken on gradual typing. I like that python3 lets you include the types as part of the program, part of the grammar. Ruby relegates them to a separate file. I guess the intent is that it's more for libraries, like how js libs will ship typescript type files? But I don't like that, I want types for myself. Sorbet exists, of course, but I don't like that it's a) a gem and b) still not a first-class part of the grammar but is instead just operating "in-language". I know it works and e.g. Stripe uses it to great effect (I worked there) but I just don't like it, personally, and I find that python3 with its built-in type hinting tends to get typed more readily than ruby where it's a much further reach away.

But I really love ruby. I hope it improves its type-hinting story because I like most other things about it. But I was pretty unenthusiastic about python prior to it getting its type hinting built-in, so apparently this is a big deal for me.

woodruffw
9 replies
20h3m

Blocks and `yield` are a killer feature; I regularly pick Python over Ruby for similar reasons as you, but I consistently find myself missing those two (and all the things that get built out of them, like the `Iterator` APIs).

Python is a lovely language, but context managers often feel like a shabby substitute for what I can do with `yield` in Ruby :-)

endgame
5 replies
19h37m

This is basically how I feel about true first-class functions when I have to wrangle ruby and care about blocks, procs, and lambdas.

MichaelDickens
4 replies
19h32m

I love the syntax of Ruby blocks (IMO it's the best syntax for higher-order functions in any language) but I don't understand why they were implemented the way they are, where some things are blocks, some things are procs, and neither one is really a function. I would prefer if Ruby blocks were just functions.

zoky
1 replies
15h33m

You can convert between blocks and Procs very easily. Ruby has several methods to let you do that, both as syntax and as methods. They are really two sides of the same coin; a block can be thought of as a Proc that is intended for immediate usage (though this is convention, and of course nothing prevents you from converting a block into a Proc and stashing it away for later).

As for functions, Ruby doesn’t really have them—or, rather, blocks and Procs really are the closest you get to a function. Instead, since everything is an object, Ruby has methods instead of functions. Critically, because methods are defined on objects they have inherent object context, which is why you can’t treat a defined method as an anonymous function. Of course, there are ways to extract the method as a Proc and pass it to another object (with or without its object context). But having methods be objects the way they are in, for example, JavaScript would require extra magic under the hood, and lead to all sorts of context gotchas, which is probably why it doesn’t work that way.

djur
0 replies
12h4m

In 15+ years of writing Ruby for production I can't think of a single time where the distinction between blocks and procs caused a problem. Blocks are a syntactic element, procs are a data type (that you can construct with a block). I honestly don't even know where the problem is supposed to come from.

vidarh
0 replies
9h28m

Blocks are Proc objects whenever you take their value, and it's only an implementation dependent optimization that they are not that all the time in MRI. It's perfectly viable to implement a Ruby where blocks are always Proc's. You don't need to care about that distinction.

Ruby doesn't have functions at all - it has objects with methods, and you can treat a block as an object whenever you want.

jez
0 replies
14h56m

Not saying it’s the optimal choice in the languages design spectrum, but it is a little defensible:

If you’re prototyping a new interpreted language and don’t want to have to build a JIT that can optimize code, but still want some semblance of good performance, the block approach Ruby picks can be pretty useful.

Ruby doesn’t haven to allocate a full-on, garbage-collected, closure object every time a function accepts a block: it only has to do this if the block gets stored to a variable. If the block is only ever yield’d to, the allocation can be skipped.

And when your language’s primary looping mechanism is done with blocks, the difference adds up:

    xs.each do |ys|
      # with normal closures and no fancy JIT,
      # the VM has to allocate a closure once per loop:
      ys.each do |y|
      end
    end
Ruby was able to get away with its closure-heavy standard library APIs without a JIT for almost 3 decades because of the affordances that blocks provide over procs/lambdas.

nrclark
2 replies
12h10m

Is Ruby's "yield" different than Python's "yield"? I use Python generators all the time, and I think they're the bee's knees.

thomasz
0 replies
11h23m

Completely different. Ruby‘s yield calls a block, which is basically an anonymous method with some special syntax tacked on.

NegativeLatency
0 replies
11h51m

It’s kinda different although you can do some similar things.

IMO the ruby one is more powerful because it effectively allows you to customize language syntax by supplying a block. And it fits nicely with the stdlib and libraries (ex map yields to a block to do the mapping). Ruby also has an enumerator that does some similar things to pythons yield: https://docs.ruby-lang.org/en/master/Enumerator.html

Pythons yield is more commonly used for iteration and stuff although it does allow some neat tricks for scoping things.

dbalatero
5 replies
16h9m

I also worked at Stripe, and loved Sorbet-ified (typed) Ruby, but any time I'd recommend it to a friend it would fail to work in their project out of the box. I think it works really well on Stripe's codebase, and might work on another one if you have what it takes to wrestle with it. And aren't ahead of Stripe on Ruby versions…

ecshafer
4 replies
13h45m

Sorbet works well on Shopify's codebase. We are basically always on the new version of Ruby and Rails both. Sorbet wasn't a huge effort to get working on the code I work on, but its been mostly easy keeping going.

grogenaut
1 replies
11h35m

question, first glance sorbet looks like an awkward version of typing syntax wise that makes ruby look like other languages. At that point what still stands out about ruby that makes it still great with a lot of type overhead? I did ruby / rails for years and enjoyed int. Just wondering.

ecshafer
0 replies
4h12m

I am not a fan of sorbet. I just know its been relatively painless. I haven't really had any extra confidence refactoring from Sorbet, nor have I noticed much beyond it being another step in making code. Mostly I think its kind of an ugly solution, and I would like something else for optional typing.

dbalatero
1 replies
4h50m

My friend's experiences ranged from "too many papercuts to deal with, gave up" to "broken entirely on Ruby 3", but good to hear it works for you. For the Shopify case, do you not have a Ruby infra team that manages the install?

ecshafer
0 replies
4h18m

Yeah there are teams for ruby and rails infra, so my pretty smooth experience might just be that team doing the work to hide the issues from the rest of the developers.

cardanome
3 replies
16h12m

Honestly, I think both Python and Ruby have a subpar gradual typing story.

The problem is that Python type hints are not enforced at runtime. They can can not be trusted. You have to rely on external type checkers that are relatively slow and different checker might give you different results.

Probably the only mainstream backend-language getting gradual typing right is PHP. Yes, good old PHP. Dead simple type system, no productivity-sucking compile step like in Typescript, actual runtime enforcement of types contrary to Python and great static linting.

Though PHP is also a fair bit less expressive and dynamic compared to both Python and Ruby so it can get away with an much simpler type system. Then again, as someone who has to work with many legacy systems, sometimes I am very grateful for the lower expressiveness.

Spivak
1 replies
14h17m

Ruby have a subpar gradual typing story

Whether you agree with it or not Ruby's (the language not the developers) resistance to static typing is just how Ruby wants to be written. There are no types, only messages. The whole culture surrounding Ruby is burying all the underlying data in favor of pure message-passing nirvana. I have no ducks but I must quack.

djur
0 replies
11h56m

This is partially true, but a pretty large chunk of idiomatic Ruby is focused on Enumerable method chaining, transforming arrays and hashes, slicing and dicing strings, etc. A language that was totally dedicated to message-passing nirvana wouldn't have regexes as a built-in data type with a literal syntax (or dictionaries, ranges, and so on)

atomicnumber3
0 replies
15h37m

Y'know it's weird but it's never bothered me too much that python type hints don't do anything at runtime. It's enough to just know what someone, at some point, intended. (And PyCharm is pretty good about pointing out when they're wrong, anyway). I guess when it comes down to it, given we're not statically typing, I still get an awful lot of mileage out of just knowing when my assumptions about the code conflict with someone else's assumptions about the code (even if that other person is subtly wrong, like anystr vs str or something).

Sorbet has a runtime time-checking mode I think, too, so that's actually a point in favor to ruby for you (though again with the drawbacks I mentioned of being a gem and imo being a little clunky syntax-wise).

soulbadguy
1 replies
20h0m

I agree that pipeline functional stream processing are in many case simpler and clear than weird nested loops with early exit conditions. However, besides maybe the needs for lambda expressions, this is mainly a function of good API design as opposed to something code to the language. In particular here i don't think the niceness of this approach is related to anything core to ruby. C# with link, F# with computational expression (and haskel monadic structures) and as you mentioned java stream do the same thing and even a bit better in my opinion

atomicnumber3
0 replies
15h33m

Ruby's blocks as a way to express a HOF is pretty accessible, and I like that I can switch from "arr.map{|o| ... }" to "arr do |o| ... multiple lines ... end" seamlessly, to be terse when I want to be but then be verbose when I need to be. But that's not exclusive to Ruby, Java's lambda syntax behaves similarly.

More generally, and more to your point, I think extensive use of blocks/HOFs lends to the "spirit" of Ruby being a lot more functional-style than python, which iirc got lambda support late and they're kind of ugly (I mean, you literally type lambda! almost as bad as go!).

usefulcat
0 replies
14h19m

I also love Ruby. I've been using it for over 20 years now, although always in a 'supporting' role--like at most maybe 5-10% of the code I write, and I definitely don't read or write it every day.

I've also never written anything particularly large in it. Like around a few thousand LOC, tops, for any one tool. And at that point, I often find myself writing a lot of things like assert { foo.is_a?(Foo) } to check parameter types, because beyond a certain size I just can't keep all the details in my head, and I don't want to rely only on comments.

Guess I'm saying that even though I really love it for small things, I'm also skeptical of its ability to scale.

neonsunset
0 replies
19h50m

You can do this in C#, F#, Rust and many other languages too with 10x better performance (in Rust in particular those usually get completely optimized away).

soulbadguy
22 replies
20h12m

It's interesting how different languages resonate so differently with each of us. I have tried a bunch of languages, and got pretty deep into ruby at one point in time when rails was the main web framework i was using. However ruby is probably my least favorite language. Most of the features which actually make ruby unique are exactly the one that turned me away and toward something like F# when i want funtional goodness, C++ when i feel adventurous and scheme/racket when i want dynamic language fix.

Ruby is probably the most expressive programming language on Earth

I wonder if there is a generally accepted quantifiable definition of programming language expressiveness. Here the author seems to equate it to closeness to natural languages.

In my experience, ruby code is easy to write, but hard to follow without being familiar with the code base and it's idom. A lot of the information required to understand it is passed through implicit context.

haolez
10 replies
20h7m

On the other hand, I find it extremely difficult to follow C# code. It's a lot of type gymnastics and dependency injection noise that makes it hard to understand where's the actual business logic.

replwoacause
7 replies
15h44m

I dislike C#. Too much ceremony for me. I want type safety without a ton of boilerplate. Is there any compiled language that offers this? Or languages built for the web? Go maybe? Not interested in a whitespace sensitive language though.

rewgs
1 replies
13h6m

Probably Go, yeah. I'm a big fan of Python and have really enjoyed learning Go.

cryptos
0 replies
9h53m

But would Go really reduce the "ceremony" compared to C#? I doubt it. Just look at Linq (functional programming APIs in C#) and compare this to the typical Go approach with auxiliary lists and for loops! Or what about error handling? Or null safety? Not that cool in Go, I think.

soulbadguy
0 replies
15h6m

I would have say F#, but it's white space sensitive, and sadly pretty much a dead language by now.

Pretty much all the new-ish language have less boiler plate than C#/Java. Kotlin and swift are somewhat good.

neonsunset
0 replies
15h12m

What kind of boilerplate are you seeing?

If it's an old project, that's a given but the culture is changing and community is slowly accepting terseness and performance as key factors to consider when writing new code.

lmm
0 replies
13h56m

I dislike C#. Too much ceremony for me. I want type safety without a ton of boilerplate. Is there any compiled language that offers this? Or languages built for the web?

Scala might be what you're looking for. (Or Haskell, but that's a bigger leap). You can write code that looks like Python/Ruby (some libraries are quite symbol-heavy, but you don't have to use them; check out lihaoyi's libraries for some Python-inspired simple interfaces), but everything's fully typed. And it has an excellent JavaScript backend that integrates with typescript/definitelytyped for using web libraries.

jinushaun
0 replies
11h43m

What boilerplate? Just use var everywhere and the compiler will type it for you.

I think the main problem with C# is that even though you can write scripty “pythonic” C# since like 2010, people are still coding C# likes it’s early 2000s enterprise Java. The .NET library doesn’t help either, since it sets the “style guide” that many developers follow.

cryptos
0 replies
9h57m

I would suggest Kotlin. It is concise and readable and the language itself is a bit leaner than C# (delegates are, in my opinion somewhat redundant, if there are first-class functions, for example).

soulbadguy
1 replies
19h56m

Agree. However i think this is mainly an artifact of API/framework designed in the 2000 and 2010 with over-enginered and over used designed patterns from the GOF. Both java and C# have their root deep in enterprise land were those are still sadly too common.

Modern framework are a bit better.

haolez
0 replies
16h51m

And type gymnastics seem worth it on something like F#, but on C#, it feels a lot like bureaucracy with not a lot of benefit.

jrumbut
3 replies
15h46m

A lot of the information required to understand it is passed through implicit context.

This is the counterintuitive genius of Ruby/Rails.

Ruby projects need an idiom and Rails gives you a good one. If a team knows Rails and its conventions they are a good ways toward developing a shared understanding of how to build (certain kinds of) software. You become acutely aware that writing code is an act of communication.

Other languages, ones with certain kinds of type systems and where there is more explicitness, can create an illusion that coders don't need to do the work to develop a shared mental model of the problem and how to solve it. As long as it compiles, everything's OK.

But I think there is always information being passed through implicit context and if it isn't handled correctly then quality will suffer, one way or another.

soulbadguy
2 replies
15h13m

Ruby projects need an idiom and Rails gives you a good one.

I can't say i agree. Projects need idiom reflecting the particulars of said project. Rails as a framework, shouldn't impose idioms to the whole project.

But more importantly from my view is that implicitness is not a requirement to any of the idiom that rails imposes.

Other languages, ones with certain kinds of type systems and where there is more explicitness, can create an illusion that coders don't need to do the work to develop a shared mental model of the problem and how to solve it.

Here again, i don't agree. I would be surprise to find any language designer trying to replace the need of a shared mental model. IMO, the point of a type system and explicitness is to make the sharing of the mental model easier. The type system make the space of possible software smaller and therefore eaiser to grasp. And explicitness reduce the need to keep things in one's head.

the_other
0 replies
7h59m

I don't think the GP was centring their comment on language creators, but on teams building software using a given language.

I feel that some teams don't spend enough time discussing the mental model required to contribute well to their codebase. I feel that type systems can hide this, and that people creating the types for a project forget to make a coherent, understandable model (either this, or I'm too junior with my typing and don't yet have the skill to infer a model from the visible types).

I also think this model-building work has two related aspects:

1. it's hard to do and hard to describe

2. one of the best ways, in my opinion, is to build comfortable abstractions that reinforce the model.. but that's even harder to do. It's easier to "enforce" than it is to "educate"; types and patterns get used to enforce structure first, rather than to explain the structure. To be honest, I only have a light grasp on this myself... I've just seen a few cases where a codebases chosen abstractions and patterns of abstractions help to reinforce a structure, but don't help to explain anything about that structure or the problem it attempts to solve

ryanbrunner
0 replies
4h9m

I can't say i agree. Projects need idiom reflecting the particulars of said project. Rails as a framework, shouldn't impose idioms to the whole project.

I disagree pretty heavily. There are certain things where it may be valuable for a project to have it's own bespoke idioms or conventions (if it was doing something especially novel because that's what was necessary to solve the problem), but there's all kinds of decisions where this level of uniqueness actively harms a project, because it's not something that developers should be expending energy on. How to log data, how to deal with basic straightforward security concerns, how routing should work, how to connect to a database, how to run routine queries and get an object graph back are all boring problems with well established "good enough" solutions and no particular need to innovate, and expending cycles on those, either in initial development or when new people onboard is wasted time.

I can be pointed at almost any Rails repo and have a baseline understanding of where to find things on day 1. That is almost never the case with a Javascript project.

philomath_mn
2 replies
20h8m

I wonder if there is a generally accepted quantifiable definition of programming language expressiveness

In my opinion, expressiveness is used as the catchall, je ne sais quoi whenever someone likes a language and needs another bullet point to put in the "Pros" column.

jjgreen
0 replies
19h57m

It has a certain je ne sais quoi but I don't know what it is.

Spivak
0 replies
14h9m

I don't think that tracks because the reason people like Go is due to it's lack of expressiveness.

It feels like expressiveness is the quality of a language to allow the programmer to change the behavior of the language constructs themselves. Python __getitem__ would be a good example allowing the programmer to control [].

uticus
0 replies
19h50m

I wonder if there is a generally accepted quantifiable definition of programming language expressiveness.

If there is such a definition it would not fit into these sorts of conversations. I love Ruby but every time I see someone mention Ruby "expressiveness" it is never mentioned as a subjective fact like syntax feature count. Instead it is always closely tied to emotional feeling, assumptions, and intuition. "Ruby's expressiveness means it just gets out of the way and lets me code." I've probably said that myself a hundred times.

OTOH it is great for DSLs and metaprogramming, gives a taste of what the LISPers have always had. Maybe that is a good definition of "expressive".

[edit: added thought about DSLs]

rewgs
0 replies
13h7m

I wonder if there is a generally accepted quantifiable definition of programming language expressiveness.

I doubt it, considering "expressive" tends to only ever describe something that's subjective.

gtf21
0 replies
7h22m

I wonder if there is a generally accepted quantifiable definition of programming language expressiveness. Here the author seems to equate it to closeness to natural languages.

I was going to make a similar comment -- it seems there might not be well agreed definitions of "expressiveness" here. I write most of my own projects in Haskell, precisely because I find Haskell to be extremely expressive, but I mean something different to "reads like English" (for which I think AppleScript is the closest example I can think of): to me, the expressiveness of the language is "how accurately can I describe my problem domain to the computer in a way that lets me naturally reason about it in code". I think this is mostly a function of the type system, not the particular syntax (e.g. allowing "?" in a method).

I am really interested in what other people consider "expressiveness" to mean, however.

davidw
0 replies
16h29m

It's interesting how different languages resonate so differently with each of us

Because programming languages are, at the end of the day, for communicating with other people trying to make the computer do things. And people have different styles, ideas and preferences.

The computer doesn't care; it just wants some binary code to execute.

shaftway
14 replies
19h25m

I don't know Ruby at all, and maybe some familiarity with the language would help, but the biggest example code makes absolutely zero sense to me:

    RSpec.describe Ticket do
      context 'when the ticket is closed' do
        it 'emails the requestor with a confirmation' do
          ...
        end
      end
    end
I have no idea what's going on here.

I get that there are some blocks of code, though it was the indentation that told me that; "do" and "end" feel super verbose and bleed into the important parts of the code for me.

Why is Ticket capitalized? Is this a variable? An object that we're about to work on that's coming into scope?

`context `when the ticket is closed'` feels like it's setting me up. Is this an if block? Or is it some fancy way to set a listener on a property? Is this setting up a callback that'll persist across runs of the program? Or is this just a method named with spaces that could do anything?

`it 'emails the requestor with a confirmation'` has got to just be a method name. But what is "it"? What was "context" in the previous one? And why does "emails the requestor with a confirmation" need to be a block? What happens in there? Is this just setting up some kind of call stack like thing that provides context all the way down?

None of this is intuitive. And the impression that I get is that the author is calling methods with spaces in their names and unclear block semantics "expressiveness".

filleduchaos
3 replies
16h16m

I have no idea what's going on here.

...

None of this is intuitive.

Why would anyone expect that a highly-context-dependent code snippet (in this case, a test suite written in the testing framework's DSL in a language that they both don't know and is different from the languages they usually write) would be "intuitive"?

Frankly I feel like many programming language discussions are tainted by the participants tying their own intelligence to whether or not they can understand something at first glance (and if they can't, it must "obviously" be the thing that is wrong). This makes about as much sense to me as concluding that my utter confusion when glancing at a page of Portuguese poetry is somehow a problem with the language itself.

shaftway
2 replies
13h12m

Oh yeah, that's easy. I don't expect to be able to follow "highly-context-dependent" code snippets.

The codebase I work on has a bunch of Ruby scripts with "highly-context-dependent" bits of code in them that I have to occasionally dive into to find out why they're failing.

Elsewhere in this thread people are complaining about how few Ruby jobs there are. I'm eliminating one of those jobs.

I replace each script with Python, or Java / Kotlin. I don't have the time to learn about all of these contexts. And I can't afford to hire people who want to specialize in Ruby. And typical engineers can't intuit about them, so nobody can properly support them. But those engineers can typically intuit between Java and Python just fine.

I understand that there is Portuguese poetry and that I may not understand it. But I don't mix it into a book of English poetry.

djur
1 replies
11h53m

You're replacing Ruby scripts at work but you couldn't understand the syntax of the Ruby excerpt above?

oezi
0 replies
5h49m

I think he just re-writes the scripts from scratch thinking they are more easily understood afterwards. This is usually true but only for the developer who did the re-writing.

rdoherty
2 replies
16h44m

Yeah tbh after working with Ruby for nearly 2 decades now and with a handful of other languages I think Ruby could use some parentheses and other common symbols. It really is too easy to create what are DSLs which requires learning another language and layer of abstraction.

vidarh
0 replies
9h13m

Every method or function you create in any language creates a DSL. It's an odd objection.

djur
0 replies
11h52m

You can always use parentheses for method calls. I've worked on codebases that mandated it. It feels a little weird in some contexts but it's fine.

phaedryx
1 replies
11h42m

RSpec is a domain-specific language for testing written in Ruby. It isn't a great example of vanilla Ruby, in my opinion.

TomK32
0 replies
7h26m

Yet RSpec is one the best and easiest software to learn the idea of domain-specific languages.

liveoneggs
0 replies
5h28m

I think it does a very good job of expressing its intent?

  > 'emails the requestor with a confirmation' .. 'when the ticket is closed'
The compiler can figure out the other bits. do .. end is { .. }

jabbawookiees
0 replies
19h9m

Ticket is a class

do ... end is how you create no-argument functions similar to () => { ... } in JavaScript. There's some technical nuance but that's the spirit of it.

In Ruby you can call methods without needing to place parentheses.

So this roughly translates to the JavaScript code:

RSpec.describe(Ticket, () => {

  context('when...', () => {
    ...
  });
});

This specific code describes a test that uses the RSpec testing framework. In RSpec, "context" and "it" are just functions that you call to describe chunks of tests and individual tests respectively.

Some Rubyists would say that the combination of these syntax rules (do-end and optional parentheses for function calls) allow you to make "domain specific languages" (DSLs as they're known in the community) without needing to write your own parser.

I think it's pretty plain to see the impact in expressiveness if you look at the equivalent Python unittest suite. The Python equivalent would have classes that inherit unittest.TestCase and methods named like test_when_ticket_is_closed.

In Python land, classes and method declarations are repurposed because the syntax is what it is. In Ruby, you can practically make your own faux keywords by abusing do-end to accept nested blocks.

felixarba
0 replies
8h16m

I think you might be reading into it a bit too much.

The author is saying that this code

reads exactly like how a person might talk about what they want to test

A person WOULDN'T talk about testing a Ticket like what you're describing with implementation details

"Ticket is a class, which will have a method of _this_ and I will call that method, which will then do _that_, and I will take the return of that method and call put it in a variable, that will be a constant..."

A person WOULD talk about testing a Ticket high level like this

"Let's describe a Ticket. When the ticket is closed, it emails the requestor with a confirmation."

Now listen, obviously not being familiar with the syntax makes reading code harder, but a programming language isn't designed so that people can just look at the code and learn the syntax from looking at the code. That wouldn't make sense.

With that said, I struggle to see some of your points listed as non-intuitive. All of your comments are related to not understanding the implementation details of this code. And that's just not what's being talked about here.

I often see complaints about this when people are uncomfortable accepting _syntax_ that clearly tells them _what_ will happen, but if they don't understand HOW that happens, they don't like it.

Here's another Rails example, for validating a model ``` class Person < ApplicationRecord validates :name, presence: true, uniqueness: true end ```

Can you seriously say that you don't understand that the name of the Person will be validated if it is present, and if it is unique? I doubt that very much.

Can you say that you have no idea how it's implemented? Yes. You don't know how something might be implemented in a language you don't know. But, does that really matter when talking about expresiveness?

drdaeman
0 replies
16h40m

The syntax never bothers me (I wrote a lot of Perl code in my youth, after all), but the semantics sometimes does.

I can mentally parse this (Ticket is a class name, context and it are methods that accept blocks, etc etc), but I have real hard time finding where this stuff is actually defined to see how it works underneath. And I always peek under the hood for the implementation nuances - documentation is always incomplete, so frameworks' and libraries' source code is my go-to documentation.

In other languages, imports are explicit and are local to file (and people outside of ML and quick-and-dirty one-off scripting tend to recommend breaking one's fingers for a heresy of `from foo import *` - with some obvious exceptions, of course), so I always can see where exactly stuff comes from.

In Ruby world there's this weird love for autoloaders, or some sort helper.rb with tons of require/include directives and so on, so very rarely I see a Ruby code that links stuff explicitly. Paired with extreme commonality of metaprogramming, reopening classes to extend them, all paired with the dynamic nature of the language, this kind of irks me as ideologically "wrong" (as in "not to my liking").

Surely, modern IDEs sort of figure out most of the stuff, but I was trying out Ruby quite a long time ago, before language servers and stuff became mainstream and widespread, and still can't shake off this impression.

binary132
0 replies
19h20m

It’s a unit testing DSL for setting up a tree of preconditions / setup.

jupp0r
14 replies
13h1m

I hate Ruby with a passion (it's also the language I mostly use in my day job currently).

It's not necessarily the language itself, which is a reasonable language, it's the patterns that are common in the ecosystem:

1. Use of inheritance for code sharing. It makes it extremely hard to reason about any piece of code I am looking at. Where does the `param` variable come from? Is it injected by any ancestors of the class I'm looking at? Who knows, I have to use the debugger to find out. I cannot reason about the code without it. Of course you can use Ruby while preferring composition over inheritance, it's just rarely done by the community. Other modern languages like Go and Rust wisely leave out inheritance for code sharing in their object model and arguably have much more readable (albeit verbose) code.

2. Global mutable state is everywhere. Not sure if it's Rails architecture that encouraged using global state as request local state (until they found out that this makes concurrency hard), but Ruby codebases are full of global mutable state. It's everywhere and again makes it hard to reason about dependencies between objects and how they interact with each other. Again, this is nothing that the language forces people to do, it's conventions.

3. Overuse of meta programming. Ruby's metaprogramming is really well done in my opinion. The problem is that lots of people want to use it and do so in places where it doesn't provide enough value to justify the costs. It's an authentication library. It doesn't need it's own DSL.

IshKebab
3 replies
7h12m

Ruby code seems to be designed to be hard to follow. Not only is it dynamically typed, but it seems like identifiers are dynamically generated, which makes it impossible to search for them.

Here's a challenge: in the Gitlab source code, tell me where `external_file_project_job_artifacts_path` is defined. It's referenced in a few places but it isn't defined anywhere.

And yes I know in other languages you can use codegen to construct unsearchable identifiers in the same way, but Ruby seems to actively encourage it.

zemptime
1 replies
5h45m

This made me curious. Having never read the gitlab code before, and on mobile, took all of about 30 seconds to find https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/ro...

Those are some pretty clean routes!

IshKebab
0 replies
3h44m

Perfectly illustrating the problem! Now try to imagine finding that if you are unfamiliar with Ruby routing.

ilrwbwrkhv
0 replies
4h40m

I think another major problem which people do not mention too much is that the ruby community went pretty deep in the whole solid principles, uncle Bob refactoring rabbit hole.

Because of that a lot of people still have major bad practices set in their heads such as a method shouldn't be longer than 5 lines etc.

Most rails code bases that I have seen usually has had a senior ruby lover refactor things in such a way that one thing is always calling another thing and even though the actual working business logic might be 12 lines which should have been linearly written, is spread across 5 files with objects being new'd up everywhere making it really hard to follow.

emmelaich
1 replies
5h8m

I really like some bits of Ruby but I kept hitting really annoying parts. e.g.

    salary = 100
    bonus = 10
    total = (bonus 
       + salary)
    => 100
Argh. The real example was more complex but you get the idea.

jb3689
0 replies
3h32m

Wow, I've been using Ruby for a decade and have never run into this. If you are dealing with a codebase written by someone else, then Rubocop probably has a rule for detecting these gotchas. I'd run it across the whole thing and burn down the flags.

38
1 replies
12h32m

Go and Rust wisely leave out inheritance for code sharing in their object model

Bad news buddy:

https://gobyexample.com/struct-embedding

At first I loved it, then quickly realized as you did that it makes code essentially unreadable.

masklinn
0 replies
12h7m

That is very much not inheritance. It’s literally just sugar for delegation: calls which delegate to embedded structs execute in the embedded struct’s context.

And the embedded struct has to be part of the struct definition, it can’t be snuck in by reopening the class and include-ing new bits.

1letterunixname
1 replies
8h25m

[insert my own personal bitching about the pains of procedural configuration management using Ruby at scale and the lost causes of rubocop and rbs]

a. Yes, global mutable state is anti-functional style, side-effect-oriented, god function/object programming and it sucks.

b. The lack of an ability to seal objects, classes, and modules from further modification is a problem.

c. Ruby 3 should've broken compatibility by adding gradual typing.

d. Nonorthogonality - Too many ways to do the same thing.

e. Dying community - Too much broken code out there.

f. Ruby was "Perl5 2.0" in most senses.

For type-safer things that look like Ruby, Crystal is an almost viable, interesting alternative.

Otherwise, I have evolved past Ruby because of the learning curve for others, too many people hate it, too many maintainers have attitude/professionalism problems, and there are more supportable alternatives for most use-cases such as rust, elixir, and bash. Sometimes, it's still useful to use ruby for some quick text formatting or a quick CLI utility in the space of awk, perl, or sed. The world mostly uses js and python. One can either be a hipster with obscure tools or get things done with the lowest TCO/highest ROI.

vidarh
0 replies
7h18m

b. The lack of an ability to seal objects, classes, and modules from further modification is a problem.

"freeze" has been there from the very start". You can freeze objects, or individual classes and modules (because, hey, they're objects) just fine. I'm all for freezing more stuff, and the migration towards freezing string literals was good, and you can freeze very aggressively in your own code, including system classes.

c. Ruby 3 should've broken compatibility by adding gradual typing.

If they had, it would've split the community. Some of us would've forked it. Any degree of gradual typing in Ruby will need to be extremely cautiously approached and/or mostly optional, as it strikes at the heart of what makes Ruby what it is. There are places it would work and be fine, and there are places where it would massively hamper productivity.

For type-safer things that look like Ruby, Crystal is an almost viable, interesting alternative.

Crystal has a fraction of the community and too many pointless differences to Ruby for many of us to consider.

The world mostly uses js and python. One can either be a hipster with obscure tools or get things done with the lowest TCO/highest ROI.

Funny. My career has spanned multiple "the world mostly uses $language" phases, and it's never affected my TCO/ROI whether what I've happened to use matches the current $language. What has mattered is picking a language the right libraries are available for and that I'm comfortable in. Sometimes I only get one of those, and sometimes that means picking a different language the Ruby, but writing composable tools means it's quite rare, and each time makes it rarer.

whalesalad
0 replies
4h47m

Great points. I also admire Ruby as a language (Eloquent Ruby is probably my fav programming book at this point in my life) but have had absolute nightmare scenarios thanks to terrible engineers who are not good at software architecture. Rails is a blessing and a curse in this regard.

99% of the time when I get air dropped on a big piece of non-rails ruby software it's going to 1. be a headache and 2. earn me a tremendous number of billable hours trying to fix it.

A lot of dev/consulting shops that popped up after the advent of Rails began using it for absolutely everything and none of them knew what they were doing architecturally.

vidarh
0 replies
8h41m

"param" isn't a variable unless you defined it in the current method - it lacks a sigil so if it's a variable it must be a local one. So it's more likely to be a method, and so you can usually find where it was defined with self.method(:param).source_location (or use pry or irb, or rdbg, and drop to a debugger session and you have easy access to nicer methods). If you don't want to run a tool like pry or rdbg, then sure, Ruby will be painful for you, just the same way as refusing the use the best available tooling will make working with most languages.

As for disliking Rails, join the club, plenty of Ruby users dislike Rails too.

rails_defector
0 replies
1h50m

Global mutable state is everywhere

Agreed 100%. This practice pushed me out into Rust/Go and I don't see myself returning unless corrections are made.

I strongly believe Shopify, Stripe, Rails need to come together and eradicate this blight from the ecosystem if they wish to see new adoption. No other ecosystem finds this acceptable behavior and is actively discouraged.

ajmurmann
0 replies
10h28m

Other modern languages like Go and Rust

Ruby's first release was in 1995. Go in 2009.

nickysielicki
9 replies
19h24m

I had to write some ruby at work recently and wasted a few hours on a bug caused by the following footgun:

    irb(main):028:0> value = false or true
    => true
    irb(main):029:0> value
    => false
That really makes me want to write it off entirely. It’s hard to think of a situation where this is the right behavior.

matthewowen
3 replies
15h47m

In python empty string is false. In ruby 0 is true. And yes, ruby has both or and || but they mean different things.

I’m not saying that it isnt valid to criticize these things: first time use of a language matters, people work in multiple languages, it is good to be intuitive.

But in practice, these things aren’t problems for people who work regularly in these languages, so I personally find them to be quite low salience.

I recognize that this is sort of similar to the claims the hypothetical user of php makes in “php is a fractal of bad design”, but personally I find think the issues are of a different nature.

jes5199
2 replies
15h0m

that’s not the bug here. they got caught by precedence rules

sinkwool
0 replies
39m

I believe what GP is saying is: coming from python, which uses `and` and `not` and `or` you expect those to be the binary operators in ruby as well. You are then surprised when they behave unexpectedly. Who is then to blame for your frustration? Is ruby a bad language for having both `and` and `&&`, or are you at fault for not doing enough research? (I don't see why someone coming from python would look any further after trying `and` and seeing that it seems to work just fine). I think this is an unfortunate situation, but one that doesn't really happen to someone that does ruby day-to-day; so it shouldn't really factor in as an argument to write ruby off.

But then is being surprised by `["0","1","10"].map(parseInt) // => [0, NaN, 2]` in JavaScript a sign of bad language design or does it just mean that you don't have enough experience with the language yet?

matthewowen
0 replies
5h2m

I suppose “|| and or” mean different things was a little too loose or broad a way of expressing that, but I agree what the big is and you see how it fits in with my overall point I’m sure

sinkwool
1 replies
16h17m

`and`, `or`, `not` have much lower precedence than `&&`, `||` and `!` . I would just avoid `and` and `or` in general.

For some more explanation see https://graceful.dev/courses/the-freebies/modules/ruby-langu...

djur
0 replies
11h43m

Rubocop forbids the use of `and` and `or` in a value expression for this reason, and I believe several style guides used with Rubocop ban them entirely. I like them but have come to accept that they're more trouble than they're worth (in a shared codebase with lots of contributors, at least).

mberning
0 replies
15h48m

If that is enough to turn you off it’s probably for the best.

jameskilton
0 replies
19h10m

You want to use "||" like most languages, not "or". They have different precedence rules.

avg_dev
0 replies
3h15m

yes, that does seem pretty annoying.

however,

  irb(main):001:0> value = false or true
  => true
  irb(main):002:0> value
  => false
  irb(main):003:0> value = false || true
  => true
  irb(main):004:0> value
  => true
  irb(main):005:0> 
I believe if you use the `||` operator instead of `or`, then things just work out fine. I agree it is really annoying. But I am pretty sure if you use a tool like RuboCop https://github.com/rubocop/rubocop (a static code analysis tool) then it will catch bugs like this. Note that I am not recommending Ruby. But in my experience if I want to work with a language and it has a community style guide and a linter that enforces it, it will save me some heartache.

Just editing to add this reference: https://rubystyle.guide/#and-or-flow

chihuahua
8 replies
20h0m

It is mind-boggling to me to see all the low-value features that Ruby has, but no enums. So every time an enum is needed, there's some ugly code that tries to emulate an enum.

The guiding theme for Ruby appears to be "let's give people a huge number of ways to write unreadable code" and it reminds me of JWZ's classic rant about PHP, "a fractal of bad design."

jjgreen
3 replies
19h46m

I disagree, but thanks for reminding me of that article, just splendid https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/

You couldn't really find that many quirks, edge-cases and foot-guns in Ruby, could you?

chihuahua
2 replies
19h33m

For me, it's not so much that there are quirks and edge-cases, but rather that Ruby seems to have a lot of clutter (e.g. "unless", punctuation as part of function names, etc) while useful features are missing.

sensanaty
0 replies
18h25m

I always find talking about Ruby fascinating, because it's so divisive and for good reason.

It's one of those things where you either love it or hate it. The first moment I saw a question mark denoting a boolean, I fell in love with Ruby right then and there, but I also perfectly understand why people hate that. Same with stuff like `unless`, whenever I use a different language I'm always tempted to make a small utility class with all the Ruby niceties like `unless`, and that's another thing I can completely understand not liking.

jjgreen
0 replies
19h27m

Fair enough, a matter of taste. Personally I'm a fan of "then" which I guess would give you the horrors :-)

jes5199
1 replies
14h59m

I think the ruby answer is “just use symbols”

oezi
0 replies
5h21m

An array of symbols, yeah. What else do you need?

pvg
0 replies
16h51m

That wasn't written by jwz.

hu3
0 replies
19h39m

Even PHP has enums now and they are pretty cool:

https://stitcher.io/blog/php-enums

woodruffw
7 replies
20h7m

The blog post (and Ruby's) emphasis on programmer happiness really resonates with me: other than Rust (which induces programmer happiness for fairly different reasons), I've seldom run into a programming language and ecosystem that tries so hard to make programming mirthful.

(Does that make Ruby a good programming language? That's unclear to me; what's clear is that I have fun writing it.)

drewcoo
4 replies
17h5m

I've seldom run into a programming language and ecosystem that tries so hard to make programming mirthful.

Perl felt like that in the 90s. Ruby (not Rails) seemed like it was trying to do a better Perl - better OO, better functional style, better syntax, etc. Both of them inspired a lot of things in other languages. And lots of people groan and complain about both of them today.

From what I can tell, a lot of complaints are from people who don't really like to code. Expressiveness means choice and that means thinking about coding instead of just following a "one way to do it" pattern over and over. Thoughtful coding, making something unique and making it easier than other examples, is also the kind of coding that LLMs can't do - they only munge together mediocrity out of what exists.

jes5199
2 replies
15h1m

when Ruby was up and coming, people compared it to Perl a lot, but I never saw the similarities. I guess they both have first-class regexp. But ruby has very standard semantics, almost interchangeable with Python and Javascript in most cases. Perl… like, I would have to look up “how to access a nested array” because its sigils, arrows, and types form such an alien system

vidarh
0 replies
9h7m

Ruby shares command-line options with Perl, the use of sigils, many of the single character globals. Besides Smalltalk Perl is probably the biggest influence on Ruby, but the Perl influence is more superficial.

mech422
0 replies
14h38m

IIRC, the comparisons were because Ruby was supposed to be a fully object oriented 'perl-like' language. Even the name was a nod to its Perl based inspiration.

lmm
0 replies
13h50m

From what I can tell, a lot of complaints are from people who don't really like to code. Expressiveness means choice and that means thinking about coding instead of just following a "one way to do it" pattern over and over. Thoughtful coding, making something unique and making it easier than other examples...

The complaints are from the poor suckers who had to maintain that "mirthful" code after it was written. Writing greenfield code is already fun in most languages; understanding existing code is already the hard part, and having to decode the "unique" thoughts of whoever came before you makes it worse.

imnotreallynew
1 replies
15h8m

There’s a lot of praise for Rust in these comments.

I always understood Rust to be for low level “close to the metal” sort of software. Is it at a point where it’s suitable for writing web applications?

I know it’s “possible” with frameworks like Rocket, but I’d like to know if Rust is at a point where it can compete in the web app space with Rails, Go, Node/Express, etc.

drdaeman
0 replies
11h24m

It sure can, but you can't be as sloppy as you can be with Ruby, Python or JavaScript or Go.

It's a high-level language, it just has its own rules that encourage correctness and prohibit sloppiness (which is a de-facto standard in the webdev industry, especially when prototyping rapidly by throwing shit at the wall and then letting whatever stuck live in production until it's no longer manageable).

For better or worse, Rust simply doesn't forgive a lot of things that are easy to do elsewhere, like not caring about less probable scenarios.

And, again, for better or worse, you also have to satisfy the borrow checker, where in other languages there's simply no such thing. Which is sometimes easy as calling clone() (not always a good idea), but sometimes can be quite a headache thinking about value lifetimes and how you just can't have something somewhere else (which can be super subtle so you wouldn't normally think about it in other languages with GC).

impulser_
5 replies
19h47m

Maybe this is just my experience, but the thing that sucks a lot about programming to me it that the most enjoyable programming languages are often the ones with the smallest job market.

My job as a programmer would be infinitely better if I could spend it programming Elixir all day, but there is basically no Elixir jobs compared to Typescript, Python, and Java.

But instead I hate my job working in Typescript all day solving problems that I wouldn't have to if I could just use Elixir.

Ruby use to an exception to this, but almost no one is building on Rails anymore compared to how many people build on React, and NextJS.

I'm talking about full stack application market, this is probably different for Rust users for systems, and Python for Data/AI.

briantakita
2 replies
15h29m

But instead I hate my job working in Typescript all day solving problems that I wouldn't have to if I could just use Elixir.

Before I focused on iso js, I worked with EventMachine & even a little bit of Erlang. Would love to hear more about an alternate timeline if I stuck with Ruby & went down the Elixir route.

---

I used to work with Ruby & switched to js before TS to build isomorphic libraries & apps. TS has been beneficial imo though figuring out type inference for library code is a steep & time consuming learning curve & takes experience to figure out the edge cases. In the end though, having type inference work in library code is worthwhile for quickly developing apps. Re: expressiveness, the js/ts ecosystem suffers from mostly using camelCase, which has variable casing depending on the position of the name segment...which makes project wide searches for composed abstractions less reliable. I distilled the "tag vector" name convention to address this issue. Granted, Ruby having `?` & `!` available is as a terse & explicit expression of intent is nice.

almost no one is building on Rails anymore compared to how many people build on React, and NextJS.

I got burnt out on Rails after the 3rd consecutive upgrade project for large codebases. I think the dominance of React has been detrimental to the js ecosystem as its bloated with the api being complex & unintuitive. It also took the JS framework guys a decade to figure out the MPAs are the way to go. I hoped people would have figured that out sooner. I got tired of the complexity & size of the reactive state management & ui libraries & recently wrote my own (rmemo & relementjs). I working on a vite alternative called rebuildjs with an Elysia/bun based app library called relysjs.

I loved how many Ruby community (other than Rails) had a commitment to create simple libraries. It seems like js framework communities have this drive to lock developers into their complex manifestations.

Sorry about the long comment. I have to get back to a major version update to ctx-core (general purpose contexts & utility functions) addressing type inference...which will make developing apps with these libraries more reliable & effective.

https://www.briantakita.me/posts/tag-vector-1-tag-vector-con...

https://github.com/ctx-core/rmemo

https://github.com/relementjs/relementjs

https://github.com/rebuildjs/rebuildjs

https://github.com/relysjs/relysjs

https://github.com/ctx-core/ctx-core

whalesalad
1 replies
14h34m

The power of Elixir is not in the syntax, it’s the BEAM, OTP, and the fact that you can launch a million processes on a single node that all have their own soft realtime behavior with their own state. Supervision trees, processes that can crash and be restarted without taking the app down, first class messaging across nodes/networks/continents, rolling deploys without restarts… if you are a true systems engineer thinker there is no better runtime.

anonyfox
0 replies
8h33m

I think most people simply don't get or dismiss how exceptionally awesome working on the BEAM is, including many that "just build phoenix apps" already. So many people never actually are in the position to deal with the kind of problems the BEAM solves so nicely, and also keep themselves in the JS hamsterwheel of neverending relearning cycles without actual progress being made.

The point is that working in the elixir ecosystem gives any sohpisticated engineer _multiple_ superpowers.

- for architecture/system engineers, its the BEAM/OTP

- for frontend/fullstack devs LiveView is the best thing in our industry for like 95% of all use cases out there

- for data engineers/... having Livebook is like Jupyter on steroids, even better when linked to the production systems and Ecto is just outstanding as an ORM take, especially when comparing to much weaker options in the JS ecosystem, and don't get me started on orchestration or data pipelines with broadway

- for AI enthusiasts all the machine learning stuff is at your fingertips already, with bindings to the native libs also used by python but more ergonomic and a lot of QoL over python because of the strictly better BEAM capabilities + toolings

- ...

There are a few areas I can highlight above where the tech absolutely excels so its the best or one of the best options in general. The magic then is that Elixir is also like 80-90% in nearly everything else with the only 2 shortcomings being raw computation speed (native libs can help as usual, easy with rust) and deployment being more complex than Ruby/Python since you should link the server nodes (no-brainer with hosters like fly)

jes5199
0 replies
15h14m

I used Ruby professionally in the early 2010s and that sucked all the joy out of it. Gigantic Rails monoliths in that era were just unmaintainable brambles. I probably would rather write Ruby again for side-projects but the ecosystem just isn’t there

anonyfox
0 replies
8h50m

By default this is because the skill bell curve in programmers including their managers. Most developers simply don't really care too much about their profession. They use what they've been taught at university or whats already used at $CORP job, fulfil some requirements given to them, and collect their paycheck. They usuallt can't be bothered to pick up more interesting tools on the side.

Ontop of that there is fluctuation and risk-avoidance, so using anything that is not absolutely mainstream is seen risky, because replacements might be a bit harder to get. Combine that with the usual mediocre preexisting employee base, and its obvious why by default the dumbest/broadest thing is everywhere in use, even though most people involved in the decisions aren't idiots.

There are roughly 2 types of places where you can encounter Elixir or other exotic tech:

1. The decision maker / CTO / tech lead actually has the autonomy and the personal interest in this tech so he is the driving force to level up and stand out. Only works in tandem with enough dev motivation in the team or it will backfire.

2. Startups/new tech insourcing departments, where a small circle of actually competent/motivated people got to choose the foundation and are by some miracle not blindsided already with "pick the cheapest and least risky" option but understand that tech can be the critical advantage needed.

Joker slot: be a solopreneur and use whatever you feel comfortable with. Thats the general escape hatch that is becoming increasingly popular it seems.

eliseshaffer
5 replies
4h38m

Hello everyone. I'm Elise, the author of the post. This is just wild. I mostly write for myself and never imagined I'd make it onto Hacker News.

I think an overlooked part of my point in this post is that the language felt intuitive to me from the beginning. It really matches the way my brain was already thinking about code. Think in messages, focus on small objects and what messages they can receive. There's a lot of comments about not understanding Ruby or finding it hard to maintain, but we're all different. I know people who feel the same way I do, but about Javascript, or Kotlin, or even Objective-C(which I find impossible to follow).

I get that Ruby isn't everyone's cup of tea, but for me it's pure joy. And when I'm working with other Rubyists, it feels like we're flying along effortlessly.

I wasn't really trying to comment on other languages. And everything we choose is based on our own design sensibilities, our constraints, and our experience. I really just wanted to put down in writing, what sparks joy for me about Ruby.

brightball
3 replies
4h12m

I can speak from both sides of it now.

When I first took on a project that was written in Ruby I was extremely annoyed. Once I learned my way around and really understood it better, I loved it. It's still my go-to for just about everything just because of how productive and readable it is.

The performance optimizer in me fights a constant inner battle about the fastest way to do things vs the most productive way to do them. With more time and experience, productivity wins just about every time.

I'm also a huge fan of Elixir and it's always interesting to watch the language discussions because there are people who are absolute "static typing is the only way" zealots out there. I don't use zealots lightly either. Preference is one thing. "Any other way is wrong" is entirely another. Elixir gives you a different way of achieving the same thing with strong typing, pattern matching, guard clauses and type inference via symbols...but it's still not enough for the static typing crowd, no matter how perfect the balance of concerns.

When you find your language, enjoy it. There's always going to be people who find a reason to dislike your choice because it wasn't their choice.

eliseshaffer
1 replies
4h8m

I totally agree about productivity. It's one of those things where focusing on it really improves your outcomes.

brightball
0 replies
4h6m

Exactly. There's no language that comes close to Ruby on the productivity front. At least none that I've found yet.

vidarh
0 replies
3h29m

I used to be firmly towards the zealot side of that. Until I tried Ruby and my first experience was cutting down a 7k line piece of code to 10% of that while adding functionality, and it just turned out the typing was much less of an issue.

I'd love to see some improved typing support in Ruby, but it's gone from a "the world will fall without it" to something that'd be a minor nice to have and which doesn't need to be complete.

vertis
0 replies
3h44m

I've been through lots of languages at this point over 20+ years, everything from C/C++ and (early) Java onwards. Ruby was one of the first languages that felt like it was designed to try and make life enjoyable for a programmer, at the time, circa 2007, that was in short supply.

I've moved on to other languages now, but I treasure the time I spent doing Ruby, and I've carried many valuable things onwards with me.

Things might change for you too, over time, but that won't lessen the positive impact that Ruby has had being so close to the way you naturally think about programming.

cryptos
5 replies
10h26m

I agree with the author that "developer experience" is underrated in many programming languages or frameworks. But at least for me Ruby is by far not the number one in this area. While the syntax looks nice at a first sight, lack of type information and meta-programming can make working with this language tough. And there are other factors to pick a programming language, runtime performance for example. I guess that this and the absence of static typing are the reasons why Ruby fell out of fashion.

For me Kotlin is the sweet spot in programming language. You get a concise, readable language with world class tool support, static typing and the excellent performance of JVM + everything available in the Java ecosystem.

jstummbillig
4 replies
10h13m

The hours I have sunk into making vscode a rails ide are substantial.

JelteF
2 replies
10h11m

Were you successful? I spent a lot of time too, but never got "go to definition" to actually work well.

felipeccastro
0 replies
5h31m

Yes, with Solargraph. It uses type inference most of the time, and when it can’t guess the type, you can add YARD comments. Intellisense also works well (autocomplete).

ansonhoyt
0 replies
2h21m

Check out VSCode's "Ruby in Visual Studio Code" page [1].

Ruby LSP already does quite a bit and started gaining go-to method abilities last month [2], though it isn't complete quite yet [3]. It's build on Prism, so promises to be more robust than past attempts. Shopify has been moving fast on improving things here.

The Rdbg integration works great too [4]. Just add a `launch.json` and VSCode can hook into the very nice capabilities Koichi Sasada has been adding to the official `debug` gem.

[1]: https://code.visualstudio.com/docs/languages/ruby

[2]: https://github.com/Shopify/ruby-lsp/releases/tag/v0.12.4

[3]: https://github.com/Shopify/ruby-lsp/issues/899

[4]: https://marketplace.visualstudio.com/items?itemName=KoichiSa...

alabhyajindal
0 replies
9h19m

Me too. Eventually I gave up and started using RubyMine. I don't use Ruby or Rails currently but when I do, I'll use either RubyMine or IntelliJ IDEA.

brink
5 replies
20h20m

After 10 years in Ruby, I moved onto Rust four years ago, and don't plan on really looking back. But with that said, I'm glad you love Ruby! There are certainly things to love.

Personally, I just can't do without a good type system anymore. I think Rust has spoiled me. I do miss Ruby's powerful reflection features though.

tlrobinson
1 replies
19h41m

Agreed, when Ruby became popular it was primarily competing against languages with verbose and rigid static type systems like Java. That is no longer the case, and the benefits of safety and developer experience provided by a good type system outweighs the cost.

cryptos
0 replies
4h55m

See also this talk: Why Static Typing Came Back, Richard Feldman, GOTO 2022

https://www.youtube.com/watch?v=Tml94je2edk&list=PLEx5khR4g7...

madeofpalk
0 replies
15h20m

I think Rust is actually pretty similar to Ruby is regards to expressiveness (given their own models)

graypegg
0 replies
20h4m

I think I have a few "most favourite" technologies that all max out some principle or idea that I like.

The author here really hits on exactly why Ruby is my favourite "get things done" language. Rust, Typescript, and Crystal are all things I've worked with, but nothing gets out of my way like Ruby. It feels like sketching? It's very expressive thanks to it's prose-y syntax, but also metaprogramming + reflection like you mentioned really makes forming an idea while developing possible, at least much more possible than most other careful correctness-ensuring paradigms.

There's nuance to these things, and nothing is the best really. But I think satisfying a borrow handler or a type checker does slow down that flow for me. I'd pick up a brush if I know what I'm making for sure, but a piece of chalk if I'm just wanting to get something working. Personal taste of course!

TOGoS
0 replies
20h8m

Same. I used to love Ruby because it just matched the way I thought, and the standard library was layed out in a way that was consistent and easy to remember (one reason I never got into Python was that, while batteries may be included, the naming conventions are all over the place and I found every step of using them surprising). I fell out of love with it when 1.9 broke all my string manipulation code. The Rails crowd pushed the 'magic' stuff way farther than I was every comfortable with. I rarely made use of reflection, but even so find my old programs buggy enough due to mishandling of edge cases that I just don't really trust it anymore. TypeScript/Deno has mostly taken its place for me, though I don't find it quite as ergonomic for little system admin tasks as Ruby was.

kreutz
4 replies
20h16m

I love Ruby too. I wish they fully embraced types. Sorbet is not fun to use.

revscat
2 replies
19h56m

Good lord, no, it is not. I tried Sorbet on a small personal project and rather quickly abandoned it. It made the code ugly and was a pain to maintain.

The fact that Sorbet has not seen adoption outside of Shopify is also somewhat telling.

It’s disappointing, because Ruby needs this. Modern tooling has moved in the direction of typed languages, and Ruby’s tooling has suffered comparatively. Outside of RubyMine it’s still difficult to get “jump to definition” to work consistently, and in 2023 this is a rather embarrassing strike against the language.

rattray
0 replies
4h43m

OOC, what was painful about maintaining Sorbet compared to, say, TypeScript?

froydnj
0 replies
16h25m

Stripe is a huge Sorbet user.

xutopia
0 replies
2h17m

Sorbet is the worse part of using Ruby professionally. It's actually so far removed from developer happiness if feels completely foreign to long time rubyists. I wished there was types build-in the language though... I see the value in that.

oglop
3 replies
11h2m

Maintaining Ruby is a nightmare. Trying to escape that hell now.

I do like Ruby for my own projects. But I hate working on Ruby with others. It becomes more messy faster and then all that supposed “getting out of your way” goes out the window and you have to know about 9 objects, one of which is an iceberg which will need to quack at some point.

Overall, it obliterates a programmers ability at local reasoning in code, which is where I really want speed.

Cthulhu_
1 replies
7h21m

Is that due to Ruby the language or the developers and/or their culture?

I mean I personally believe maintainability is a combination of the language itself and the culture around it; Go is a great example of a language and culture aimed for readability and maintainability, eschewing cleverness. That is, the language is limited in how much cleverness you can write, and the culture is opposed to people trying.

jwestbury
0 replies
6h2m

It's both, really. Even if we limit this to dynamically-typed, interpreted languages, Python is far more maintainable that Ruby both because the language and the culture take a stance of "there is one correct way to do something." In many cases, you can do things multiple ways in Python, but the language design is intended to make one approach preferable for a specific problem.

Ruby is heavily influenced by Perl, with a focus on being enjoyable to write. And let me be clear: I loved writing Perl, back in the day. If I still used Perl, I'd still love writing it. But part of why Perl is so fun -- and why Ruby is fun! -- is that it's expressive and flexible, and you can do a lot of things you really shouldn't. This leads to people writing code that was fun to write, but will be difficult to maintain -- and the language's foundation rests on this concept, so the culture is (subtly?) encouraged to embrace it.

jwestbury
0 replies
6h7m

Maintaining Ruby is a nightmare. Trying to escape that hell now.

The problem with maintaining Ruby is that Ruby is heavily influenced by Perl.

musicale
3 replies
13h16m

I liked Ruby when I first encountered it because it felt like a scriptable Smalltalk that plays nicely with friends.

Then I accidentally learned Python one afternoon and never thought about Ruby again. I'm sure Ruby is better than Python in dozens of ways, much as alternate keyboard layouts are better than QWERTY (and Rails is probably better than Django.) And I'm still mad at Python for setting fire to billions of lines of 2.7 code that people had written. But I'm still using Python.

vidarh
2 replies
9h12m

Personally, the Python syntax is a sufficient reason why I will never switch to it over Ruby.

hurtbird
1 replies
6h26m

Why? Can you give a few examples?

vidarh
0 replies
6h25m

Significant indentation alone is sufficient. I loathe it.

mattgreenrocks
3 replies
19h55m

Ruby’s a great language, but the cult of personality is really strong there, especially in Rails. And that ultimately led me away from the ecosystem.

I’m not looking for heroes to worship, just good tech.

andrei_says_
2 replies
16h4m

What are some symptoms of a cult of personality? I use Ruby and Rails and I know that DHH and Aaron Patterson are somewhat famous but don’t know much about them and certainly don’t make any decisions based on their existence or fame.

mattgreenrocks
1 replies
15h9m

Both of those individuals have made fantastic contributions. My beef isn’t with them.

It’s with the community that insists that DHH’s software design edicts are The One True Way. Instead of software design being a thing you can use to make your life better, we are to believe that Rails Is All You Need. And think at the time it was the framework to use, so it attracted a lot of people who believed software dev should be “do what the thought leader says.”

No idea what it’s like now, but it truly felt like people saying those things out of tribal affiliation more than technical acumen. And that is a recipe for stagnation.

That said, I still respect the tech and the creators a lot. I just don’t share the values at all.

vidarh
0 replies
9h2m

There's plenty to Ruby outside of Rails. Many of us hardly touch Rails - even in the web space there is a wide range of other frameworks.

I tend to agree there's much cruft in the Rails space, but I also hardly ever interact with the Rails crowd.

marcrosoft
3 replies
19h32m

Take ruby vs go. Ruby can write expressions that resemble a sentence so you can skip commenting and it looks nice. Go is verbose and less English like. Which is easier to understand what the code actually does? Go may take a little extra time to digest but it is infinitely more clear what is going on. If you don’t need to debug the ruby code or optimize it ruby wins because it is easier to digest and reads like English. It is a trade off like many things in software.

PH95VuimJjqBqy
1 replies
19h16m

This is actually one of the reasons I dislike cucumber so much. They try so hard to make it read like English for non-tech people but to really understand it you need to understand the underlying regex being used.

eliseshaffer
0 replies
12h21m

Hello! I'm Elise, the author of the post. Figured I'd jump in and say that in addition to Ruby, I really like Cucumber. But I think the non-technical people focus really cuts a lot out. For me, Cucumber gives the whole team(tech and non-tech) a shared language for what the software does.

I don't use it much anymore, because most companies seem to have moved away from it. But, I do miss it and wish we had something similar that could encouraged that level of shared understanding.

djur
0 replies
11h48m

I spent several years working on production Go code and I never found it particularly clear or intuitive to read or debug compared to Ruby. This seems like a "your mileage may vary" situation.

sodapopcan
2 replies
4h36m

Even though I don't really ever write it anymore, I still have a HUGE softspot for Ruby. It's a great language though definitely one you have to understand and follow its idioms to not be annoyed by it. Unfortunately, all your coworkers will need to do the same, which is where it can start to fall apart.

One thing I don't miss that a significant part of this short article, is RSpec. I was into it at first but it just becomes a burden. When you're writing test descriptions in English, there is very little value gain to gain from the ceremony RSpec has. As for assertions, it turns out that if you're a programmer, `assert a == b` is just as readable as `expect(a).to eq(b)`. Yes, the latter does make it easier to get the arguments in the right order for the output, but that's about it. Otherwise, it's just "neat." You end up thinking a bit too much if you are doing things "the rspec way" which is not something I want in my brain when writing tests. It's also more to learn for onboarding people. Stuff like `expect(a).to be_present` really means `assert a.present?` are head scratchers that I just don't see any value in other than being neat.

RSpec is definitely a cool idea and a very well-designed project, but un-necessary by me. It's been 3 years since I've used it daily and haven't found the tests I'm writing these days to be any less readable.

altdataseller
1 replies
4h31m

Is Test Unit or whatever the alternative is called better?

sodapopcan
0 replies
4h1m

I'm not sure, all I ever used in my 8 years of writing Ruby every day was RSpec. I was very bought into it but just expressing that once it was gone, I didn't miss it.

narven
2 replies
20h14m

try Crystal lang (https://crystal-lang.org/)

mathverse
1 replies
20h12m

This. I dont really need true essence of metaprogramming craziness of Ruby. I need Ruby-like, dev happiness, readability and performance. Wish Crystal would catch up and get some attention.

sinkwool
0 replies
16h10m

Kotlin is very ruby-like and performant, check it out. If you don't mind using JetBrains IDEs, I'd give kotlin a try.

kazinator
2 replies
19h16m

supports_feature? contains gratuitous punctuation.

A question mark is useful on predicates when they are nouns. For instance type tests. Here is why: widget(x) looks like a constructor: it's making a widget out of x. If we add a question mark: widget?(x) then we know it's a test whether x is a widget. We have other choices there like is_widget(x).

"Supports feature" has a verb and object. The verb is not in imperative form; it's in a statement form. A question mark is not required.

skgough
0 replies
11h19m

I always understood the question mark to mean that the method returns a boolean value, eg. the include? method on Arrays returns a bool.

graypegg
0 replies
15h11m

I think this is a normal ruby pattern though. A ? prefix is just a best-practice habit to indicate a method returns a real TrueClass or FalseClass instance.

You’re always running Ruby statements in some scope, so there’s always an object you’re running methods from. That makes your constructor and reflection examples a bit odd for Ruby.

Constructors would be a method on a class, normally the Class instance method #new: Widget.new(x)

Checking if y is a Widget would mean calling a method on that instance, normally the Object instance method #is_a?: y.is_a?(Widget)

I think that’s adequately distinct.

xal
1 replies
20h23m

same

aato
0 replies
9h48m

Came here curious to see if you'd post; was not disappointed.

vinc
1 replies
9h30m

I started with PHP many years ago for my side projects while at the university, then I switched to Python, but when I graduated there were only PHP jobs available so I took one because I had to. I was not happy with PHP, it was a pain to use it. I never want to hear again about WordPress or Drupal.

I discovered the Ruby community at its peak around that time and fell in love with it! I started a new project at work with Rails and all my next jobs were Ruby jobs.

I experimented with Node when it came out but I think I'm burn out with everything related to JavaScript at this point. And the Ruby community, while still great, seems to be dying out locally. Meanwhile I've been doing some Rust side projects for almost a decade, and it looks like this will be my next language. Time will tell.

I still love Ruby though, I wish it was more popular, it's such a nice language.

verelo
0 replies
8h54m

Very similar experience here. I started in .net but ended up Working in php, although only recently did i switch to ruby for a personal project. I’m loving ruby, and paired with nextjs / react for a front end this has to be the best working environment I’ve ever had the opportunity to use. I wish I’d been doing this for work prior but I’m glad to be finally doing it at the ripe old age of 37.

hschne
1 replies
10h23m

Interesting that the discussion here focuses so much on the actual language.

I think the language is fine, but the thing that really makes me stick with Ruby is the ecosystem and the culture it fosters. The article also makes that point.

I have yet to see a programming community (around a language) that is as encouraging and nice as the one around Ruby.

dcchambers
0 replies
3h14m

I have yet to see a programming community (around a language) that is as encouraging and nice as the one around Ruby.

Agreed 100%. It's like the opposite of the javascript community where I feel like the leaders of various camps are constantly trying to tear each other down about the best way to do things as they fight for developer mindshare/marketshare. Maybe I just see too much JS drama on twitter. Anyway, the Ruby community is so wholesome and a breadth of fresh air in the modern tech world.

germandiago
1 replies
8h38m

I want to like Ruby but what I found annoying about it and Rails is that many things were magic and implicit (in Rails) and consistent style is difficult to maintain.

Python looks much more uniform in this sense and it is very powerful. Maybe not as good for DSLs, yes, but for general coding it keeps itself very understandable.

claudiug
0 replies
4h40m

Im doing a lot of python now, and I found the python code abs mess. it should be only one way, that is a joke. ruby is way more consistent here .

check fastapi, sqlalchemy, or any ML library, what a mess...

claudiug
1 replies
20h24m

same

zakshay
0 replies
20h19m

same!

akprasad
1 replies
20h9m

I'm glad that the author enjoys Ruby! As someone with limited Ruby exposure, these quotes stood out to me:

The language is meant be joyful to use. [...] Everything else that Ruby is stems from this value.

This is important and underrated. I think many programmers have a bias that working on a difficult problem entails using a "real" programming language with sharp edges. I had some version of this bias for a long time until I started exploring the most recent generation of systems languages.

Well written ruby code can often read like natural language.

I see where the author is coming from, but I find a healthy dollop of symbols to be very helpful for reading and understanding code at a glance.

Feeling recognition in the language you’re programming is so powerful.

This is the feeling I had the first time I used Python, and later Rust. It's a wonderful feeling!

[As] Kent Beck said at RailsConf in 2020, “Software design is an exercise in human relationships.”

Especially true given all of the components involved in supporting a language: compiler, docs, standard library, third-party libraries, package managers, frameworks, formatters, profilers, ...

rapsey
0 replies
8h19m

This is important and underrated. I think many programmers have a bias that working on a difficult problem entails using a "real" programming language with sharp edges. I had some version of this bias for a long time until I started exploring the most recent generation of systems languages.

All languages have some mantra that everyone repeats and that is the Ruby mantra. Personally I find Rust to be joyful because the type system, project and package management is so good and the end result is efficient without any extra effort. What I find joyful is getting things done well.

RagnarD
1 replies
14h32m

I've programmed in both Ruby and Python. I like both, but ...

It should never be forgotten that the ultimate purpose of programming languages is to make specific usable programs. It's sort of fashionable to ignore performance but in reality it's always an issue of some kind. And the fact remains that the price paid for Ruby and Python's features is severe performance degradation. That's improved over time but as far as I know it remains a real problem. One shouldn't let admiration for language features supersede user experience and resource utilization.

eropple
0 replies
13h20m

The vast majority of web code is waiting on a database, written in something eye-poppingly optimized, to push a string back to the client that asked for it. It's "pick things up and put them down" plumbing and the delta between a Fast Language and a Slow Language will usually be swamped by connection latency.

There are of course places where it isn't appropriate to use a Ruby or a Python, sure. So don't. There are plenty of others where sniffing at them on the grounds of performance is making up a guy to get mad at.

thegabez
0 replies
20h2m

No language is more fun to write in than Ruby.

samsquire
0 replies
20h11m

It's positive and uplifting post and it is that too when a language works with how you think and is expressive and productive. It's unsatisfying to work against a learning curve if you are hitting obstacles.

A language is one possible notation of thought.

I like to be productive with my thoughts. I tend to do proof of concepts in Python then port to C or in Java directly.

I remember learning about Ruby when posted on digg and there was a new tool coming out all the time.

rochak
0 replies
12h27m

I don't.

robertlagrant
0 replies
20h10m

I've no opinion on Ruby, but I don't really understand this article. People like familiar tools, and get good at them - agree. But a lot of languages can be written in fluent ways, and I didn't really find the test example that easy to read. I wouldn't say "end end end" at the end of describing the test out loud, for example.

mgz
0 replies
11h43m

Ruby one love

mberning
0 replies
15h44m

It’s a shame that Ruby doesn’t have the cachet it once had. People are missing out. It’s still a fantastic language and Rails is still the goat web framework. Perhaps we’ll see a renaissance in the future. I still prefer to do all my tinkering and playing in Ruby first.

manicennui
0 replies
16h24m

Ruby is still very popular in Chicago.

makeramen
0 replies
19h59m

I actually dislike that Ruby reads like natural language. The complex logic in large systems would take many paragraphs to describe in english but is often much clearer and more succinct in code.

globular-toast
0 replies
6h21m

Everything I read about Ruby I feel can be done with Common Lisp. I wish more people would learn Lisp just to see what's really possible in a programming language.

donmb
0 replies
7h52m

We love it too and so far we could solve any problem with it.

devoutsalsa
0 replies
7h11m

I like my Ruby code. I usually hate other people’s Ruby cuz too much magic.

desireco42
0 replies
20h12m

I for one appreciate this post. I love Ruby too and it brought a lot of joy and pleasure in my life. I am mostly not using it today but it is OK, I still love it.

cies
0 replies
8h21m

I always wonder what languages authors of such articles had exposure to.

aidog
0 replies
7h12m

I really love ruby too. I hope I can find a job writing a lot of ruby every day.

UncleOxidant
0 replies
15h37m

I really fell for Ruby around 2001 after liking Perl for about 5 years but then deciding that OO Perl was just seemed like a hack. Ruby was my favorite language from about 2001 till about 2010 or so. Then I found strongly typed functional languages like OCaml and F# to be more to my liking. And Python not Ruby was used in most of the jobs I had during the 2010s.

It seems like Rails really caused Ruby to fall out of favor around 2010 so it's interesting to see some positive Ruby articles here lately. Looks like there's been a good amount of performance improvements as well as new language features added over the last decade - perhaps we're seeing a bit of a Ruby revival?

Ilikeruby
0 replies
9h0m

I mean, I like ruby.