4 ms·
Ruby isn't forcing you to use static types. That being said, I actually think something like Sorbet makes even solo/small teams more productive because it trade
by whakim 5y ago
Ruby isn't forcing you to use static types. That being said, I actually think something like Sorbet makes even solo/small teams more productive because it trades some additional time writing boilerplate for dramatically reducing the number of bugs you write.
- zomgwat 5y agoThis has been my experience using Sorbet. I sometimes get annoyed when I get stuck screwing around with the RBI files. Then I get in the flow and remember how fast Sorbet allows me to move.
- BurningFrog 5y agoA good test suite is better at keeping the code bug free. Not needing types is another benefit of good testing. That's my experience, at least.
- emodendroket 5y agoI think people remembering to test all the typing-related corner cases is never going to come close to being as effective as something enforced by static checking -- and even if it did, it seems like I've lost all the time I saved and then some, if that's the price of not having to write the declarations.
- abstract_put 5y agoDo you think it's possible for well used types to displace the need for some tests?
- JohnBooty 5y agoI'm not the person you're responding to, but I would say: "yeah, but it'd probably be bad practice." What would you be testing for, exactly? That `SomeClass#some_method` raises a `NoMethodError` when you pass it the wrong thing? You could test for that, but I don't think that would be a good use of code or your time. If A is passing the wrong things to B, your specs will fail anyway on that `NoMethodError` once B tries to actually do something with those improper argument(s). I suppose it could be useful in cases where you'd stubbed out B in your specs, but ehhhh.
- whakim 5y agoIn my experience this here (usually some method unexpectedly getting passed `nil`) is the single biggest class of bugs in production Ruby applications. Also, what happens when you don't get a NoMethodError? Duck typing is an extremely common practice in Ruby, which means that you can easily run into situations where code "runs" but the output is nonsensical.
- JohnBooty 5y agoIn my experience this here (usually some method unexpectedly getting passed `nil`) is the single biggest class of bugs in production Ruby applications. Right, but how do tests help you here? Your specs aren't passing those unexpected nils, and if they were, your specs would fail on the resulting NoMethodError. Static analysis can find these potential problems in a statically typed language - I miss the days when Resharper would let me know about potential nulls/nils. That's a strong argument for static typing. But, this particular comment thread is about addressing this class of bug in Ruby via tests, and my vote would be generally no. Duck typing is an extremely common practice in Ruby, which means that you can easily run into situations where code "runs" but the output is nonsensical. I've been working with Ruby full time for years (admittedly, mostly boring CRUD Rails apps) and I've just never found this to be a problem. It obviously can happen, but I just don't see those name collisions ever happening.
- whakim 5y ago> But, this particular comment thread is about addressing this class of bug in Ruby via tests, and my vote would be generally no. I'm pretty sure I started the comment thread ;). I think there's a couple of scenarios when a function gets some rogue input (e.g., a string instead of an integer) which then triggers a NoMethodError. I agree that tests don't really help you here - what are you testing, that your method correctly throws a NoMethodError? That being said, to combat this issue you often see dynamically typed codebases littered with scattershot validation, i.e. fail gracefully if you somehow wind up with an unexpected input. And then you often write tests for that. Static typing often obviates these tests, because presumably the rogue input has already been handled further up the call stack. Stubbing is the other issue; I think it happens much more frequently than you suggest that A is tested (stubbing B) and B is tested in isolation; or perhaps there's only one test of A which doesn't stub B, and that test doesn't happen to trigger the NoMethodError. So I think we're mostly agreeing, but I do think you get to write fewer tests overall. > It obviously can happen, but I just don't see those name collisions ever happening. It has happened to me (I think in the Rails context less often) but I agree it's not exactly common. It is deadly when it does, though.
- BurningFrog 5y agoI came the other way. As in, tests displaced types. Did Java for 13 years. Then moved to Ruby and lost the type system I had leaned so hard on. After an adjustment period I got into the new groove of just testing all code, and I don't miss my hard typed days at all.
- whakim 5y agoI don't think that static typing obviates the need for tests. However: * Static typing catches many kinds of bugs earlier by simply not allowing you to write incorrect code in the first place. * No matter how good your test suite is, you're still putting the burden on the human to always remember to write tests for corner cases. * Static typing allows you have to write many fewer tests by making invalid data unrepresentable. You don't have to write millions of unit tests of the type "what if this list is empty" if the function literally can't accept an empty list.
- joelbluminator 5y ago> Static typing allows you have to write many fewer tests by making invalid data unrepresentable. You don't have to write millions of unit tests of the type "what if this list is empty" if the function literally can't accept an empty list. We just don't write these kind of tests on our Rails codebases and we are fine. The world hasn't exploded yet anyway. If some piece of code is super tricky and sensitive then sure maybe then (though I have yet to see such a test case I think), but as a rule? No.
- whakim 5y agoI'm surprised that you never have bugs of the type "this thing is nil and I didn't expect it to be". This is by far the most common type of bug I see in production Ruby applications and it simply can't happen with something like Sorbet.
- joelbluminator 5y agoNull exceptions can even happen in Java. I wasnt refering to those.
- whakim 5y agoBut most types (besides primitives) in Java are nullable, right? Sorbet literally wouldn't let you write this code: https://sorbet.run/#%23%20typed%3A%20true%0Aextend%20T%3A%3ASig%0A%0Asig%20%7Bparams%28x%3A%20T.nilable%28String%29%29.void%7D%0Adef%20add_one%28x%29%0A%20%20return%20x%20%2B%20%22another%20string%22%0Aend https://sorbet.run/#%23%20typed%3A%20true%0Aextend%20T%3A%3A... Null is simply the most frequent example of this issue. Getting an integer rather than a string is super common, for example. Or a string instead of a date.
- Scarbutt 5y agodramatically reducing the number of bugs you write. I would say that's a big overstatement.
- whakim 5y agoHave you tried writing a Ruby app with Sorbet vs without? I have, within the last year, and that's been my experience.
- handrous 5y agoIt's not, because "bugs you write" includes bugs that don't make it to production. I doubt there's a programmer who's worked in a language without static types who's not familiar with the "write, run, read error, find silly bug, fix silly bug, repeat" development loop. Usually it becomes second nature.