I love an expressive programming language, it’s why Go makes me feel like I’m brushing my teeth with sandpaper…
But there’s such a thing as too much flexibility, expressiveness and flexibility often go hand in hand as flexible language lets you make things as expressive as you want… but things can be expressive without the same level of flexibility if they are well designed.
I find Rust strikes a good balance for low level language work, it feels more expressive than C because of higher level language features but it’s not necessarily as flexible as C with things like the borrow checker nagging you to be safe unless you turn it off.
Lisp… too flexible, too expressive. Lisp code reminds me of the phrase “that depends on what the definition of is, is”.
Scheme and scheme likes including weird step cousins like JavaScript share the unfortunate result of this and your drowning in custom DSLs and no one quite codes the same way unless you have rigorous tooling to enforce a team style.
Ruby falls foul of this for me too. It’s too flexible, it’s very expressive and I enjoyed reading the tutorials and learning the basics. But the moment I discovered real code I was immediately recoiling in horror …. It was a disaster… a spaghetti mess of overrides redefining and meta-programming in general. It made it impossible for me to ever trust the environment I coded it since I had to constantly inspect everything to make sure someone hadn’t done something crazy like enhanced the “+” sign to transform numbers to strings for avoiding something like a sql injection risk in a specific context and whoopsie, leaked the behaviour globally so now any time you added integers you got concatenated strings… but only after the library was dynamically loaded on first query … maddening stuff…
Stuff like this is why ruby is too flexible.