4 ms·
I agree that it's very bad they broke the exists() behaviour in a point release by changing the return value from a boolean to an integer. But I think strong ty
by speleding 2y ago
I agree that it's very bad they broke the exists() behaviour in a point release by changing the return value from a boolean to an integer. But I think strong typing is not the answer. It's a drag on productivity and I can think of several other ways they could have broken the user space API that would not have been picked up by strong typing. You really need good test coverage, and ruby/rails makes that easy.
If you have great test coverage then strong types are superflous, if strong types help you then your tests are not good enough.
- RUnconcerned 2y agoI totally disagree. I think not having static types is a drag on productivity and maintainability. I have to work with both Kotlin and Ruby codebases, and the Ruby ones are always a nightmare whenever you need to make a change deep within the application's core, even though the Ruby one has more extensive tests. The idea that test coverage is a replacement for static types is nonsensical. I won't insult your intelligence and say that by great test coverage you meant testing the shape of your inputs, because only an idiot would say that would serve as a replacement for something that is done automatically by a compiler, but sometimes minor naming mistakes (like `job` instead of `jobId` when you're passing an ID and not an instance of `Job`) will make it past code review and will place a totally unnecessary mental burden on the next programmer who has to look at the code and figure out what exactly he's looking at. With static types there is no need for that, it's right there in the code.
- speleding 2y agoGood tests do indeed not test the detailed shape of inputs and outputs, they test the system end to end. And they should be cheap to run, so you run them after every change. As soon as someone mistypes jobId the test will break and you will know where to look. If that would slip through then your tests simply aren't good enough. And because tests do not test the detailed shape of inputs and output it becomes easier to try out a quick refactor of your code later, without having to change a zillion signatures just to experiment a little. Agility matters.
- RUnconcerned 2y agoI'm very fond of end-to-end system tests, with any external dependencies mocked out using something like Wiremock for HTTP calls, and containers for databases or queues. If it were up to me, I'd only have that kind of test, and some unit tests for pure functions/methods that may have finicky logic. You misunderstood my point about the `job`/`jobId`, though. It would be correctly typed, and wouldn't break anything. But it would not be immediately clear for a developer working on that code in the future if it was an instance of Job or the ID of a job, and there would be no type information that immediately makes that clear. I don't feel like the point you are making with regards to changing the signatures is true, either. If you're changing the shape of some data structure, or adding/removing parameters, then you would also have to make those changes in a dynamically typed language, it's only when you're changing the types of the parameters that you have to make a change, but that's really not that big of a deal, since your development environment should helpfully point out the places you need to update as you change them. I value code that's easy to makes changes in, but I value code that someone else can quickly pick up more.
- maples37 2y agoI'm curious to hear why you don't like strong types, because I can't imagine not using types. My day job involves working on a PHP app that's been around since the 5.x days. So it's a mixture of "new code" which has typehints everywhere (PHP nomenclature for runtime type-checking, but static analyzers can also read the signatures and alert you before runtime, which is the real benefit IMO) and "old code" where everything is an array, but to figure out what's in the array you've been passed, you have to look at the 3 functions that call the function you're looking at, and even then sometimes you have to back up 2 or 3 steps up the stack to find where the array is created, and even then you're not 100% sure if that `userEmail` member is present all the time or only in certain circumstances. With strong types, we pass a UserModel object, and everyone immediately knows what they can and cannot do with it. I remember in college trying to write some Selenium scripts in Python to do some scraping, and my biggest frustration was not being able to identify the return type of anything. The language wouldn't tell me, the built-in python IDE (IDLE?) wouldn't tell me, so the best I could come up with was something like `print(typeof(x))` (or maybe it was a function to print the properties/methods? it's been a while, I forget) every time I called a new function and running the tool, which was a painful experience to say the least. A few months later I ended up doing something similar but in C# and the difference in productivity was night-and-day.
- speleding 2y agoIn rails or elsewhere in our code base, if I'm ever unsure what a function does or what it returns then I just jump to the function definition and read it, a single key stroke in my IDE. Now I need to fix a small bug in a library. Rather than wait for the library to be fixed I can monkey patch the fix into the library until it's fixed upstream. Trying to do that with a strongly typed language, you typically need to jump through all kind of hoops or end up fixing the problem outside your library or put some shim in between the broken library and your code. And then once the fixed library comes out you need to undo the code fixes on your side rather than just delete the monkey patch. Sure I understand the benefits you list, but for me the effort put into strong typing, typing the stuff, changing it each time, just doesn't seem a worthwhile trade off because it's very rare for me to encounter a problem caused by a wrong type. Perhaps I would feel differently if I had to work on a poor code base with many people, but I don't.