3 ms·
You're confusing "sophisticated" with "annoying or difficult to use". Boilerplate generators are annoying, and Valgrind is difficult to use, but they're unrefin
by catnaroek 11y ago
You're confusing "sophisticated" with "annoying or difficult to use". Boilerplate generators are annoying, and Valgrind is difficult to use, but they're unrefined: they solve problems that are best avoided than solved.
A better measure of sophistication is how much bang you get for the buck, and how much of this bang is made possible by the language itself.
In my opinion, the best example of this is GHCi: Using GHCi almost feels like asking the computer "Is what I'm doing right?". GHCi itself is made possible by Haskell's excellent balance between type system expressiveness and making inference feasible. To see why maximizing raw expressive power won't help, in most dependently typed languages, it's hard to construct nontrivial meaningful utterances, so you don't even get to the point where you can ask "Is what I'm doing right?" - the type checker will tell you "It isn't even wrong". That being said, I'm aware that the situation w.r.t. tooling is improving a lot.
Another example is Rust's borrow checker: It will tell you exactly at which point an equivalent C or C++ program would have had a dangling pointer. It doesn't quite have the same "fluid conversation" feel as using GHCi, but it saves the enormous amount of time that would've been otherwise spent chasing memory bugs in a debugger, especially in a concurrent program.
Ruby isn't defined by poor tools. Ruby is defined by a design that makes static analysis intractable. The lack of sophisticated tools is just a corollary.