> types were not remotely the most common type of problem I ever ran into, and certainly not "every" bug.
If you took that away from what I wrote, I apologize. I meant that without a compiler and type-checker, you would only find bugs at runtime. In my experience, the vast majority of these would be easily discovered by a compiler. Presumably that experience is shared by Ruby devs since they're now adding type-checking.
> This hasn't been a serious problem in a decade.
That may be true. I haven't had any need to revisit Ruby or Rails since I moved to Go. But it was a serious problem with no workaround, and I've never encountered any scenario like that since switching to Go.
While I do like static typing, I find more bugs because people have no clue about security and they think they can do it better by just tying together a few libraries and storing a jwt in local storage or they forget to handle Prisma exceptions or they didn't know what session fixation is or because they forgot to consider a corner case of foreign key exceptions from the database library, etc, etc than because somebody passed a string where an integer was needed.
Giving up frameworks with 10+ years of hardening and documentation and libraries and support etc just because of coroutines or static types or nice syntax or because that's what google does then I should do it too makes absolute no sense to me.
> (aside from the JavaScript hell still plaguing rails)
It's not too bad now, set up a Node environment and there's first class support for using vanilla esbuild or if you want to go without Node entirely there's import maps and lots of goodies at the Rails level to help you manage your JS dependencies. Technically Webpack is still supported too but it's vanilla Webpack instead of Webpacker, that's all part of the new https://github.com/rails/jsbundling-rails abstraction for using a number of different JS bundling tools with their stock set ups.
If you're finding bugs in production that a compiler or typechecker could have found then there's something seriously wrong with your test suite. That's how Rails works, if you don't have 90%+ statement coverage it will be hell.
IME, adding that 90% statement coverage is much of the tedium and frustration of the job in Ruby-land--in particular for things that you just get solved for free with something like TypeScript.
It might have improved somewhat, but I find myself pretty comfortable with a much more pared-down test suite that focuses on correctness tests at logical module boundaries in TypeScript, rather than verifying things the computer can just do. I do look forward to seeing Ruby's gradual typing become more entrenched in the ecosystem, though, because I like the language--I just don't like using the language professionally because of the additional manual work I find myself doing.
> IME, adding that 90% statement coverage is much of the tedium and frustration of the job in Ruby-land--in particular for things that you just get solved for free with something like TypeScript.
I would argue that if your unit test is only testing things which would have been shown by the type system of another language, you are testing at too low of a level. In addition to being tedious, such tests are often very brittle.
Those tests are brittle, and they're also the thing that protects you at module boundaries when those boundaries are being hammered on by different groups of people.
On the other hand, if you have a compiler/typechecker that finds things that your test suite could find I will always reach for the compiler/typechecker. No sense in writting tests against something a standard tool will find aside from sanitizing data from your inputs.
My experience with ruby is often documenting the expected argument and return types with comments and then writing code and/or tests to enforce the types.
Having also used Go a fair amount, I very much prefer the real type system which both documents and enforces.
I’ve worked on many large rails apps at scale and large Java apps at scale. There has been no significant difference in the big count between them despite Java having static types.
Java has a bad type system that makes it awkward to express many well-typedness guarantees (too much boilerplate to create new types (classes or interfaces), no sum types (tagged unions), no null safety, exceptions are a mess especially with lambdas, and don't get me started about all the reflection madness of popular frameworks that throws type-safety out of the window, etc.). As a result you don't get much safety in exchange for all the boilerplate. Still, I find Java massively easier to refactor. You can remove a field from a class and verify that you've changed all the places that were using it (barring reflection, of course). In Rails, that requires at least running the whole testsuite which could be very slow (because Rails tests are often very slow). And even then, you have no guarantee you didn't miss a particular case.
Languages with better type systems do exist (Rust, Swift, Kotlin, from what I hear even typescript?, and all ML type languages including Haskell, ...). They are much better at preventing bugs. My life became better when I had to stop worrying about NPEs, for example.
If you took that away from what I wrote, I apologize. I meant that without a compiler and type-checker, you would only find bugs at runtime. In my experience, the vast majority of these would be easily discovered by a compiler. Presumably that experience is shared by Ruby devs since they're now adding type-checking.
> This hasn't been a serious problem in a decade.
That may be true. I haven't had any need to revisit Ruby or Rails since I moved to Go. But it was a serious problem with no workaround, and I've never encountered any scenario like that since switching to Go.