I don't think complexity comes just from the number of tools, but the disparate things you "need" them to do. Redis, Vite, large CSS toolkits -- you're learning a bunch of large components.
I mean complexity comes from many places, but compared to the 'Unix philosophy' most of these tools are quite large. Obviously, there's quite a bit to learn about the way a *nix OS works, but if you treat tools as small and composable for simpler interfaces it helps a lot.
The web dev example of pub/sub is funny, because chances are if you're using Rails your primary DB (probably Postgres) already has a pub/sub system in or. Or you can just use any RDBMS for your job management system.
I mean, I think the problem with SPA-like client-side approaches are that there aren't any that have felt _good_ with Rails, let alone great.
Absolutely true that not every app needs to be a SPA from day one, but I do with there were a few more common solutions for "hybrid" apps, which use some pages as a SPA. That said, it's not that bad once you've got it setup. I like that Rails offers a solution like import maps, but I do also wish there were better core functionality for using some kind of package manager.
Like the redis analogy: Whether or not you need Redis, there are good defaults and very good 'third party' solutions for background jobs (or caching). You don't even need Redis is many cases, but it's easy to grow into.
Lapis is very cool, but I really struggle with a lack of examples and pre-built solutions for some things.
Leafo's itch.io is built with it and I maintain snap.berkeley.edu. A great tool, but I'm also many times more productive in Rails. (It's an unfair comparison, to be sure!) and Openresty + Lapis is quite performant and low overhead which is great.
I love JS and Ruby, and I spent a bit of time maintaining a web app in Lua.
There are parts about the language I really enjoy. I like dynamic languages; I don't run into type issues so often it bothers me, but the tooling around Lua still leaves me wishing for me.
Part of this is really my own ability, or lack thereof, but I feel slow and constrained in lua. I have a hard time debugging, but I don't feel these things in other languages.
I have a close friend, who's an Azure dev -- uses his MS laptop for work, his phone for everything else. And I do mean everything - taxes, trip planning, etc.
It's not just crazy kids who "know nothing but phones". Even engineers.
That said, phones operate too much like appliances. I will not give up my Mac.
It makes me very sad that this is true, simply due to the crippling limitations imposed by a cell phone and the implications of this trend gaining so much traction. I feel so claustrophobic and handicapped doing anything remotely complex on my iPhone. I would always rather wait until I can sit and pull my MacBook out of my backpack.
I've been wondering about this... It definitely doesn't feel great to be on the receiving end of something auto-generated. But a "unique" message is at least more interesting to read, and doesn't feel quite as frustrating.
A yet if P(someone unknown is a robot) gets too large, it's going to be a weird adjustment period.
There's a bunch of things to pay attention to in Ruby. I wouldn't say these get too hairy, but they trip students up for very understandable reasons.
* `a ||= b` is not just `a = a || b`, but `a || a = b`
* The distinction between defaults arguments and hash arguments in functional signatures has many edge cases -- but it's much much better in Ruby 3.
* There are still 2 pieces of syntax for hashes (`{a: 1}` and `{:a => 1}`) They are the same.
* Curly bases show up a fair bit for a language that's not a braces language. :) They're in hashes, blocks, and % strings. e.g. `%w{a b c}` is the same as `%w|a b c|`. They're also used in string interpolation, e.g. `"Hello, #{name}"`.
* There are sometimes many ways to do the same thing. There's Procs, blocks, and lambdas. % strings work with many characters.
* `unless` for `if not...` and get wonky.
* Overusing "surprise if" e.g. `do_thing if other_thing` can be hard to read.
* It's so easy to monkey-patch and extend primitive classes, you might not realize when libraries do it.
All of these are features that I actually find nice to use in the right contexts. But they can pop up when you don't expect, and they can definitely make Ruby a challenge to learn. That said with a little discipline (or just a linter ;)), I find a lot of Ruby code a joy to read and write.
Yeah I don't get why you would deliberately make the flow control confusing and backwards like that. Python list comprehensions are the same. They make the information flow backwards.
This also has the effect of making nesting really confusing.
I’ve written both professionally and personally found Python makes it harder to see the early out, which makes it less valuable/explicit as a guard.
The Ruby pattern is clear up front on what it is rather than being a bag of conditions that you have to get to the end of to discover what they trigger.
It's even worse when you combine the two complaints:
do_thing unless other_thing
Which of course you find in many Ruby codebases.
Python list comprehensions seem less painful to me because they read almost like the WHERE clause in SQL simple SELECTs. Definitely not the most straightforward thing one encounters in Python though.
wow, thanks. I worked with ruby for more than 5 years, and `||=` never surprised me.
TLDR On the distinction between `a = (a || b)` and `a || (a = b)`:
* There is no difference when `a` and `b` are local variables (unless `a` is undefined, but that's an edge case)
* The distinction manifests when `a=` is a method. (It could be a `[]=` or some attr_accessor). Then `a = (a || b)` always invokes `a=`, whereas `a || (a = b)` only invokes `a=` when `a` is falsey.
In essence however, `a ||= b` respects the intuitive definition that it sets `a` to `b` if and only if `a` is falsey.
Yeah, it's not usually an issue in practice. But I do see students get confused trying things out...and it's likely because learning in an interpreter doesn't often look like "real" code does.
Costs a crap ton for what it is, but it is nice.