Peter Bex wrote:
On Thu, Dec 14, 2006 at 04:45:11AM -0800, Brandon J. Van Every wrote:
  Some tests need additional code for support (setting
things up in a particular way etc).  Why would one want to put all that
code (which may be twice as big as the code itself, or even bigger, if done
properly) in one huge file?
You do it if you want your code to actually work, and you think it's
   better  to  run  the  automated  tests  than  to  pay someone $XX/hour
   after-the-fact to show you your bugs.

I know and understand why to use tests.  I'm not opposed to tests,
but I am opposed to lumping the tests in with the main code.
I'd much rather just keep the code clean and put the tests in
another file.

Well, I question why we have files. We have historical reasons for it; all of our text editors are built in terms of them. But a program is really just one big database of stuff, and it might make more sense to have it all uniformly accessed and searched, rather than being cobbled across a filesystem.

Thus I am saying, "why should it appear together" vs. "why should it appear apart," is pretty arbitrary and historical. If one regarded the program as a database, then either is just a view of the database.


Inline documentation is useful to the reader,

Agreed.

and so are contracts since
they describe the specification a function should adhere to.

Only if those specifications are terse, legible, and universal enough to describe nearly any class of problem that needs specification. I have my doubts, but I haven't tried this paradigm. I suspect my eyes will glaze over, and that deciphering contracts isn't much better than deciphering simple tests.


  Tests
don't say shit.  They're a very low-level and nonsemantic way of
groping around to ensure your corner cases are covered.

Depends on the test. I think the comments are what help. I don't care what kind of code someone writes, it's gonna make my eyes glaze over.

  Contracts
are more semantic and declarative, so they tell you more about
what type of input is expected.

Declarative styles are not panacea. Some problems are better specified imperatively. Sometimes you really want to know that "A happens, then B happens, then C happens" and it's easier to debug.


What would you prefer?

(define/contract (+ a b)
  ((is-natnum a)
   (is-natnum b)
   (result-natnum))
  (if (= 0 a) b (+ (sub1 a) (add1 b))))

(define/test (+ a b)
  ((throws negativeerror (+ -1 1))
   (throws negativeerror (+ 1 -1))
   (= 1 (+ 0 1))
   (= 1 (+ 1 0))
   (= 2 (+ 1 1))
   (= 0 (+ 0 0))
  (if (= 0 a) b (+ (sub1 a) (add1 b)))))

The latter. Because I'm probably implementing a bit twiddling optimization algorithm, and I need to know exactly what's happening as the code converts to machine instructions. When you state a preference for declarative interfaces, you are implicitly stating you don't want to be bothered with the implementation details. That you prefer abstract problems. Now that may have its place in various problem domains, but not typically in mine.

As you can see, proper testing often results in bigger code.

Bigger is fine. I'm interested in *clearer*. Declarative may be more terse, but that doesn't make it more clear. And for some problems, declarative makes it verbose, if you actually want A --> B --> C.

Cheer,
Brandon Van Every

_______________________________________________
Chicken-users mailing list
Chicken-users@nongnu.org
http://lists.nongnu.org/mailman/listinfo/chicken-users

Reply via email to