4 ms·
Interesting analysis, but yup, that's what tests are for! If you've got a sporadically failing test somewhere, that's probably sign of a bug.
by elsurudo 13y ago
Interesting analysis, but yup, that's what tests are for! If you've got a sporadically failing test somewhere, that's probably sign of a bug.
- lmm 13y agoThe question is what's the cost/benefit on fixing such things? Not everyone is in a position to stop working on features for two days to track down something like this. This particular bug is also a strong argument for using more advanced type systems, even if you have good test coverage.
- jgrahamc 13y agoThis particular bug is also a strong argument for using more advanced type systems, even if you have good test coverage. Yes, it's a great pity that the compiler didn't say "You're multiplying a time.Duration by a time.Duration and expecting it to be a time.Duration".
- dllthomas 13y agoI'm not sure whether you're serious or not (and I see a few different jokes you could be getting at otherwise), but multiplying time by time should give you time squared, not time again. Unfortunately, even Haskell doesn't catch errors of that type if you want to use the ordinary mathematical operators, because (*) :: Num a => a -> a -> a. In this case, that's not what's going on, though. It's multiplying time by unitless scaling factor, which doesn't present the same problem. However, there's a few ways you can get at the issue with the help of the language, you just have to distinguish between the different units you might be using to represent time - this doesn't really take an advanced type system: the example of having a .milliseconds method is along these lines.
- njs12345 13y agoHave you seen the dimensional library? It's a slightly abusive use of the type system, but will check units at compile time. See e.g. http://code.google.com/p/dimensional/wiki/GMExample http://code.google.com/p/dimensional/wiki/GMExample
- dllthomas 13y agoI think so; I've seen similar things, for sure. Obviously Haskell does have the ability to make this distinction; just (unfortunately) it's somewhat incompatible with the standard prelude, and thus common practice.
- straight_talk 13y agoThe F# compiler does that.
- ghswa 13y agoFor those that are interested, here's a link to the docs: http://msdn.microsoft.com/en-us/library/dd233243.aspx http://msdn.microsoft.com/en-us/library/dd233243.aspx
- mooism2 13y agoFor something like this, you don't need an advanced type system. Even C can do struct duration { int in_nanoseconds; }; struct duration seconds_duration (int in_seconds) { struct duration dt; dt.in_nanoseconds = in_seconds * 1000000000; return dt; } /*TODO: milliseconds_duration(), microseconds_duration(), etc */
- dllthomas 13y agoI highly recommend doing this kind of thing, incidentally. Just because two things have the same backing representation does not mean they're of the same type, and wrapping in a struct tells the compiler to keep them separate. It doesn't have any impact on performance; C structs don't carry anything more than their member and you've only got the one member. I do this with indexes and ids as well.
- gohrt 13y agoOne would hope that 'typedef' would define a type in C, protecting the programmer from silent incorrect casts, but of course it doesn't, because C hates programmers.
- dllthomas 13y agoWell, typedef "defines a type", but (unfortunately) in a purely syntactic sense. If you're using typedef for something that's not wrapped in a struct or union, think hard about whether you mightn't want to also do that.
- bryanlarsen 13y agoThe problem is that 95% of the time, such failures are a bug in the test or test environment, not in the code. Spending two days chasing down a bug in your test feels a lot like wasted effort. Once you've done it 19 times you're very tempted to just disable the test and stop wasting time. This blog post is a good reminder that sometimes the bug is actually in the code: persevere.
- twistedpair 13y agoOr an indicator of a non-deterministic test. Testing date manipulations with any "now" values can lead to fun like this. Add in timezones and the tests will pass in the US and fail in Japan.
- bitsai 13y agoAfter using jaycfields' "expectations" Clojure testing library, I've become very very appreciative of libraries that expose an easy way to freeze time, for exactly the issues you described.