6 ms·
Well, types are essentially sets of values. So if you can capture the values that you expect in a type, then the type system _does_ give you a guarantee.
by solarexplorer 12y ago
Well, types are essentially sets of values. So if you can capture the values that you expect in a type, then the type system _does_ give you a guarantee.
- mpweiher 12y agoBut tests test for specific values. Example: testThatAddWorks result = add( 3, 4 ) EXPECT( result , 7)
- solarexplorer 12y agoOK, I see your point. Of course, the type system will not substitute this kind of tests. But it allows you to check the whole range of values. This is helpful if you e.g. wanted to handle overflows, wanted to limit the operands to positive numbers, etc.
- mpweiher 12y agoNot only will the type-system not substitute these types of tests, but also the reverse: you just don't write tests for types, as they are subsumed by the value tests, which is why I object to the canard of "the type system saves you from having to write trivial tests for types". And yes, a type-system can do certain types of "forall" analyses that are difficult or impossible with tests, but that's a different topic.
- NickPollard 12y agoIt's also more important. Generally with tests, you're less concerned about having some particular examples succeed, than you are with finding if there are possible values that fail.
- pjmlp 12y agoThe fallacy is assuming people write tests. Regardless of what gets preached at agile conferences and such, the reality is that in most enterprise projects, the amount of tests is close to zero.
- the_af 12y ago> you just don't write tests for types, as they are subsumed by the value tests I think this is false.
- the_af 12y agoI know that's just an example and that you probably don't actually write tests like that in your day job, but it's a terrible unit test. For example, it fails to tell apart addition from the constant function 7. Even if you add more data points, you're still not testing addition. In a way, "testing for specific values" is very misleading. Consider that it'd be the wrong if you were actually trying to prove something. Now, tests aren't proofs, but we still should write them to be as strong as it's practical. Strong static typing with property testing (a la quickcheck) whenever possible are preferrable in my opinion.
- zvrba 12y ago> For example, it fails to tell apart addition from the constant function 7. Right. But how would you test for the addition function without exhaustive O(N^2) search over the whole input space? (You need to test for commutativity; if you're going to test for associativity, it grows to O(N^3)).
- the_af 12y agoMy comment was in the context of the "unit tests vs type systems" debate. It was meant to illustrate my opinion that "more general" is better than "specific values" when testing, as much as is practically possible. I'm aware that addition is a toy example, but suppose we want to test our implementation: Except for very simple verification, to exclude obviously broken implementations, I'd rule out testing specific values such as 3+4=7. And, like you said, performing an exhaustive exploration of all values is out of the question. So I'd try property testing instead. Relevant properties in this case are associativity, commutativity, etc. As an example, I'd try writing properties such as: for all X, Y: add(X, Y) = add(Y, X) I'm not arguing that everything can be tested like this, or that the properties are always easy to formulate; but when they are, I think this is the superior approach. The tools that I'm aware of that can do this (such as QuickCheck or ScalaCheck) come from statically typed languages, though I don't see why they couldn't be used with dynamically typed languages. The point is that this starts to look a lot closer to static typing and "testing generalities", philosophically, than what proponents of dynamic typing + unit testing propose. Testing generalities is better than testing specifics, because it's at least a step closer to a proof of correctness.