
TDD in Clojure - fogus
http://blog.objectmentor.com/articles/2010/06/03/tdd-in-clojure
======
grogers
I find this kind of testing incredibly useless. All he did was take the
implementation of update-all and do the same thing again for the test!
Basically all he is doing is checking that clojure's map function works. When
your unit test says the same thing as the thing you are testing, I think it's
pretty obvious you've failed somewhere.

The most important thing to test here is that the accumulate-forces (and by
extension calculate-forces-on-all) function gives the right values, that is
what you need to be testing. There are even several ways to do that without
just plugging in magic numbers - for example you can generate random inputs
and verify that the vector sum of all forces is 0 (I think this would be
correct because gravity acts on two objects equal and opposite). You can
verify the higher level functions by checking that momentum and energy are
conserved.

~~~
technomancy
Yeah, I think this attitude is just a side-effect of being new to FP and
wanting to cling to familiar techniques.

I certainly felt the same way getting started. Then once you read the Out of
the Tarpit paper you get over it and start to trust referential transparency.

~~~
DanielBMarkham
Great paper -- I hadn't heard of it.

I read the abstract and a lot of feelings I've had about testing in FP
coalesced: I knew this intuitively but wasn't able to put it into words. Codd
can be your pair-testing buddy for a LOT of FP testing.

------
prospero
I think it's interesting that the proof he gives that TDD is still useful in
Clojure is that he had problems with Swing. Swing (and all the other Java GUI
libraries) have a huge impedance mismatch with Clojure. If the interface were
defined by an immutable s-expression schema, I wonder if he would have a
similar experience.

~~~
fogus
"have a huge impedance mismatch with Clojure"

Do you mind expanding on this?

~~~
prospero
Every widget in Swing, WinForms, and pretty much every other last-gen
interface framework is a big bundle of state. First you instantiate the
object, and then you make a series of function calls to set all the right
toggles.

So far, this doesn't seem like much of an obstacle. Clojure has (doto ...),
which lets us trim some fat, so at least we're beating Java, right? The
problem, though, is that Java has tools which autogenerate this boilerplate,
letting the programmer treat setup as an atomic step. When writing it out by
hand, you have to worry about the order of your calls, and that when you
copy/paste some code you change all instances of layoutPanel1 to layoutPanel2,
because otherwise you get the obscure NPE mentioned by the author.

The above problem is why the current-gen interface frameworks (WPF, GWT, and
Android) all rely on XML schemas for high-level layout. Schemas avoid a whole
class of programmatic error that can arise in this initial setup, and can be
sanity-checked in a number of ways thousands of lines of code cannot.

Unfortunately, this still doesn't solve the other problem: callbacks.
Callbacks are chock-full of side effects, and fragile for all the same reasons
mentioned above. There's no equivalent in a Swing scene graph to XPath or CSS
selectors, which means that your code is closely coupled to the current
hierarchy, and fragile if it changes.

What this all means is that it's hard to introduce very much abstraction into
the creation or modification of Swing interfaces. My theory, which I have not
tested, is that if you modeled the initial interface as a schema, and forced
callbacks to be purely functional modifications of that schema, it would be a
much less painful experience writing UIs in Clojure.

