3 ms·
If you’re stuck with dynamically typed languages, then tests like this can make a lot of sense. On statically typed languages this happens for free at compile
by jonathanlydall 1y ago
If you’re stuck with dynamically typed languages, then tests like this can make a lot of sense.
On statically typed languages this happens for free at compile time.
I’ve often heard proponents of dynamically typed languages say how all the typing and boiler plate required by statically typed languages feels like such a waste of time, and on a small enough system maybe they are right.
But on any significant sized code bases, they pay dividends over and over by saving you from having to make tests like this.
They also allow trivial refactoring that people using dynamically typed languages wouldn’t even consider due to the risk being so high.
So keep this all in mind when you next choose your language for a new project.
- ngruhn 1y agoI think at least some people who say this think of Java-esque type systems. And there I agree: it is a boilerplate nightmare.
- motorest 1y ago> But on any significant sized code bases, they pay dividends over and over by saving you from having to make tests like this. I firmly believe that the group of people who laud dynamically typed languages as efficient time-savers, that help shed drudge work involving typing, is tightly correlated with the group of people who fail to establish any form of quality assurance or testing, often using the same arguments to justify their motivation.
- gharzol 1y ago[dead]
- 0xDEAFBEAD 1y agoThe question I find interesting is whether type systems are an efficient way to buy reliability relative to other ways to purchase reliability, such as writing tests, doing code review, or enforcing immutability. Of course, some programmers just don't care about purchasing reliability. Those are the ones who eschew type systems, and tests, and produce unreliable software, about like you'd expect. But for my purposes, this is besides the point.
- bluGill 1y agoI find they are valuable. When you have a small program - 10k lines of code you don't really need them. However when you are at more than 10 million lines of code types find a lot of little errors that writing the correct test for would be hard. Most dynamically typed languages (all that I have worked with) cannot catch that you misspelled a function name until that function is called. If that misspelled function is in an error path it would be very easy to never test it until a customer hit the crash. Just having your function names as a strong type that is checked by static analysis (need not be a compiler though that is what everything uses) is a big win. Checking the other arguments as well is similarly helpful.
- 0xDEAFBEAD 1y agoThanks for the reply! Technically, I would say that you should just write a test for the error path. I also tend to think that finding bugs at compile time is not actually that much better than finding them at runtime. If you have good monitoring (which you should have), and a customer triggers the bug at runtime, you can fix the bug then. A customer triggering a rare bug once isn't the end of the world. My sense is that people are very keen to find bugs at compile time rather than run time, but I haven't been generally able to figure out why this matters, unless you're working on some sort of real-time embedded system. What matters to me is the probability of spotting the bug, not when it is spotted. I suppose perhaps data corruption could be a concern with runtime errors? I would argue you should work to be robust against that anyways, by using atomic transactions as necessary. I'm most interested in subtler bugs which don't trigger exceptions at runtime. Those are the sort of bugs which will get executed over and over in production if they aren't prevented. It seems to me that static analysis doesn't do much to prevent these bugs, but tests can be really helpful. I will grant that implicit type conversions can lead to subtle runtime bugs. I see that as a separate issue however. I've worked most with Python, which doesn't do static analysis, but also enforces types at runtime. That seems fairly ideal to me. Interested to hear your perspective!
- bluGill 1y agoI'm guessing you don't work on programs with millions of lines of code. What you say makes perfect sense for programs that are only a few thousand lines wrong. Nothing wrong with small programs, there are a lot of useful programs that only need to be that long. However when you start writing something more complex you need all the help you can get, and suddenly tests become a valueable way to ensure you don't break some working feature when you add the next.
- globular-toast 1y agoRubbish, in my experience. People who understand dynamic languages know they need to write tests because it's the only thing asserting correctness. I could just as easily say static people don't write tests because they think the type system is enough. A type system is laughably bad at asserting correct behaviour. Personally I do use type hinting and mypy for much of my Python code. But I'll most certainly omit it for throwaway scripts and trivial stuff. I'm still not convinced it's really worth the effort, though. I've had a few occasions where the type checker has caught something important, but most of the time it's an autist trap where you spend ages making it correct "just because".
- motorest 1y ago> Rubbish, in my experience. People who understand dynamic languages know they need to write tests because it's the only thing asserting correctness. Tests don't assert correctness. At best they verify specific invariants. Statically typed languages lean on the compiler to automatically verify some classes of invariants (i.e., can I call this method in this object?) With dynamically typed languages, you cannot lean on the compiler to verify these invariants. Developers must fill in this void by writing their own tests. It's true that they "need" to do it to avoid some classes of runtime errors that are only possible in dynamically typed languages. But that's not the point. The point is that those who complan that statically typed languages are too cumbersome because they require boilerplate code for things type compile-time type checking are also correlated with the set of developers who fail to invest any time adding or maintaining automated test suites, because of the same reasons. > I could just as easily say static people don't write tests because they think the type system is enough. A type system is laughably bad at asserting correct behaviour. No, you can't. Developers who use statically typed languages don't even think of type checking as a concern, let alone a quality assurance issue.
- bluGill 1y ago> Tests don't assert correctness. At best they verify specific invariants. Pedantically correct, but in practice those are close enough to the same thing. Even a formal proof cannot assert correctness - requirements are often wrong. However in practice requirements are close enough to correct that we can call a formal proof also close enough.
- 0xDEAFBEAD 1y agoDan Luu looked at the literature and concluded that the evidence for the benefit of types is underwhelming: https://danluu.com/empirical-pl/ https://danluu.com/empirical-pl/ >But on any significant sized code bases, they pay dividends over and over by saving you from having to make tests like this. OK, but if the alternative to tests is spending more time on a reliability method (type annotations) which buys you less reliability compared to writing tests... it's hardly a win. It fundamentally seems to me that there are plenty of bugs that types can simply never catch. For example, if I have a "divide" function and I accidentally swap the numerator and divisor arguments, I can't think of any realistic type system which will help me. Other methods for achieving reliability, like writing tests or doing code review, don't seem to have the same limitations.
- Smaug123 1y ago> swap the numerator and divisor Even Rust can express this; you don't need to get fancy. Morally speaking, division takes a Num and a std::num::NonZero<Num>.
- 0xDEAFBEAD 1y agoOK, I guess you got me for the particular case of division. Have your upvote.
- UncleEntity 1y ago> On statically typed languages this happens for free at compile time. If only that were true I wouldn't be a tiny bit as good at tracking down segfaults as I've become over the years...