> We are all fully aware that if you are doing “kind_of?” checks all over the place then you are doing it wrong.
I think the author missed the point of what Alex Payne wrote:
> There’s lots of calls to Ruby’s kind_of? method, which asks, “Is this a kind of User object? Because that’s what we’re expecting. If we don’t get that, this is going to explode.”
They aren't checking types because they don't understand how to write polymorphic code or something along those lines. They are checking types as runtime assertions against programming errors; precisely the set of programming errors that static types prevent.
I've done this myself, when I found that parts of our code dealing with finances was mixing exact and floating point arithmetic, leading to occasional rounding errors. I built a simple DbC system for Ruby, and added type checks going in and out of various methods. With the contracts in place, it was easy to track down the location of the errors, and they stay in place as documention / protection for the future.
So, do you use this "DbC" in all of your Ruby code nowadays, like 95% of it, or in just where you think it's really important? And with this "DbC" do you think you could grow the Ruby code to 500,000 lines of code or more?
It's easy to get cocky about this if you've only worked on relatively small projects in languages like Ruby, but being so cavalier with larger codebases will blow up in your face. Yes, code should be well-factored, but it isn't, so be careful.
I think type checks should absolutely remain in production code. (If you're considering removing them for efficiency purposes, measure if it matters.) The ambiguity that tends to creep in and cause nasty bugs isn't "is this a polygon or a string?" (I mean, duh), but rather, stuff like, "is this measurement currently in meters or millimeters?". Working in a dynamic language and putting checks in the few places where it really matters is good enough, but it really matters. It may help to think of type assertions as comments about expectations and intent that are automatically checked.
Also, languages with type inference can be a good compromise. You get the consistency checking of static typing without having to constantly remind the compiler that it's still dealing with an int or whatever. (I like OCaml, but it's not without its flaws. It takes a while to get the hang of working with, rather than against, its incredibly thorough type checking.)
I think the author missed the point of what Alex Payne wrote:
> There’s lots of calls to Ruby’s kind_of? method, which asks, “Is this a kind of User object? Because that’s what we’re expecting. If we don’t get that, this is going to explode.”
They aren't checking types because they don't understand how to write polymorphic code or something along those lines. They are checking types as runtime assertions against programming errors; precisely the set of programming errors that static types prevent.
I've done this myself, when I found that parts of our code dealing with finances was mixing exact and floating point arithmetic, leading to occasional rounding errors. I built a simple DbC system for Ruby, and added type checks going in and out of various methods. With the contracts in place, it was easy to track down the location of the errors, and they stay in place as documention / protection for the future.