Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Did it not occur to them to, I don't know, "test" the API when they make changes? A compiler or stricter type system may help prevent certain careless errors, but not all (or even most) of them, while a proper test scheme will catch all such errors.


The author is one of the world's most prolific publishers of TDD educational material.

You shouldn't be so quick to assume that everyone else is clueless.


My snarky tone was unwarranted but I'm not actually assuming cluelessness here, nor did I come there quickly. I find in practice that TDD and what I think of as "testing" are quite orthogonal.

> With the Ruby backend, we sometimes forgot that a particular API property held an array of strings, not a single string. ... These are normal dynamic language problems in any system whose tests don't have 100% test coverage.

TDD in general focuses on code-adjacent test strategies like unit tests. In the Ruby TDD world it's a popular strategy to test first, code second at the level of classes or even individual methods. In practice this"tests = code = tests" philosophy produces both more code and a focus on metrics like coverage that only measure "for how much of my code do I have other code that asserts that my code is doing what the other code says it should be doing" rather than ensuring "my code is actually doing what someone else needs it to do".

"Testing" as I intend the term means using the software to do whatever it is supposed to. For a server side API that probably means consume it via a client. Any client that relies on the type of a property being an array instead of a string will blow up (except perhaps Python, grr). Any reasonably complete smoke or integration testing regime should expose this problem, but more immediately I think developers should be actively testing the thing they are changing while they are changing it. Personally I dislike compilers and restrictive type systems in large part because they _inhibit_ this sort of rapid, iterative testing and fixing. Partially functional dynamically typed code is far more useful to me as I work through a series of related changes than statically typed code that requires I fix all the issues it perceives as important before I can keep going on what really matters.


> Any reasonably complete smoke or integration testing regime should expose this problem

But that's not without cost. At least in the Ruby world (and Bernhardt holds/held this view) integrated tests are to be avoided where possible because it creates a negative feedback loop of slow tests and an exponential number of tests that need to be written to achieve equivalent coverage.

> but more immediately I think developers should be actively testing the thing they are changing while they are changing it

This smells like the age-old discipline/rigour/professionalism platitude often trotted out by proponents of Software Craftsmanship. I'd rather embrace the fact that humans make mistakes and optimise for that, rather than hold people to unreasonable standards.

Furthermore, while I agree that people should be testing the thing they are changing while they are changing it, you appear to be implying that only one form of testing is acceptable here. Why not test the type signature? Why not a formal proof of correctness? Why not a property-based test? There are many ways to improve the chances of a piece of software to work. Restricting ourselves to only one of those ways is, quite frankly, dumb.

> Personally I dislike compilers and restrictive type systems in large part because they _inhibit_ this sort of rapid, iterative testing and fixing.

That's a fine opinion to have, but that's all it is. I've worked professionally with dynamic languages, and I hold the opposite view. I work with a few projects totalling about 60,000 lines of Haskell, and I feel the language enables rapid, iterative testing much more than Ruby ever did for me. Of course I can't prove this empirically, which is why my opinion will only ever be as good as yours, and vice versa.

> Partially functional dynamically typed code is far more useful to me as I work through a series of related changes than statically typed code that requires I fix all the issues it perceives as important before I can keep going on what really matters.

I'm sorry, but this is plainly incorrect. The ability to defer type errors to runtime certainly exists in Haskell, and I expect not exclusively.


If you can come up with a formal proof of correctness for an evolving API then you are clearly operating on a higher plane of software development than us mere craftspeople, and I certainly wouldn't presume to talk you out of trying.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: