
Testing is not a Replacement for Static Typing - semmons
http://lovehateubuntu.blogspot.com/2010/03/testing-is-not-replacement-for-static.html
======
ozy
Let me argue the following standpoint: programming is hard, algorithms are
hard, and compile time type checks are not much more than spell correctors.

Any algoritm operates and creates state. It is nice your statically typed
language prevented you to add your socket file descriptor to an int. So you
fix your 'typo' and add the index of the file descriptor (assuming your open
sockets live in an array, or similar scenario). But what if your algoritm
requires you to do a subtraction? You still have a bug.

No type check can check runtime dependent data. You pass in a List but the
list requires to be at least of length 2? (Actually you some languages can
tackle this too, but these sort of requirements become arbitrary complex.) You
will deref the list out of bounds and you have a bug.

So now I just sketched two scenario's where you still need to actually run
your program to catch bugs. And your type system did nothing.

A very certain kind of bug -- mostly typo's or slightly higher level mistake
-- are caught by a static type systems. The question is, is this worth the
restricted semantics of the language?

The advantage of a static type system is clear; these mistakes are caught
where and when they are introduced, not where their result is used.

The disadvantage is also clear: restricted semantics. How would macro's look
for lisp if it had type checks?

Without types, your language is better at creating macro-like abstractions.
You can capture patterns with these, and prevent a lot of typos that way. (And
a write a lot more concise code.)

And even more, think about Java's performance hit on ArrayStoreException ...
So even such statically typed languages need to do runtime type checking more
often then you would like.

------
Zak
Most arguments of this type focus on the end result and not on the process of
writing a program. Static typing and (in many cases) writing tests before code
work well if you have a well-defined idea of what you're trying to create.
They don't work as well in a situation that's very experimental or very
iterative.

In the real world, static and dynamic typing both have their place. Different
problems have different tool requirements. There is no One True Language and
there never will be. For most of the things I do, I can make do with four.

------
Deestan
Just to address a depressingly common misunderstanding whenever testing and
static typing is brought up:

 _Static Typing vs Testing: Which is better?_ No! Stop that! There is no "vs"!

To take Haskell as an example, it is a completely statically typed language
which, if not abused cleverly, guarantees that you don't have code trying to
add inches to centimeters, or divide a hangar by a sorted apple. It _also_ has
a very powerful unit test generation and execution library (+), code coverage
tools, and test statistics tools. These libraries and tools are frequently
used by Haskell programmers. Creating any large project without unit tests is
just as silly in Haskell as it would be in Python.

Nobody has ever (or possibly, only nobodies have) argued that static typing
eliminates the need for tests. The author of this post didn't argue that
either.

(+)
[http://www.haskell.org/haskellwiki/Introduction_to_QuickChec...](http://www.haskell.org/haskellwiki/Introduction_to_QuickCheck)

------
mquander
This argument sucks. All this guy has to say is that statically typed
languages will automatically detect some errors at compile-time. Yeah, no
shit. The question at hand (among other differences, like expressiveness,
compiler complexity and optimization) is whether those errors are common and
severe enough to warrant any programmer overhead dealing with static types.

------
regularfry
Static typing isn't a replacement for testing, either. You can get away
without static typing. You probably can't get away without testing.

~~~
runevault
You could argue static typing can replace testing for some subset of tests
when compared to dynamic languages, but for the most part yeah, you can't use
any type system I know of (not strongly conversant in Scala or Haskell's) to
replace the vast majority of unit/etc tests.

~~~
Zak
Haskell programmers are fond of claiming that their type system is more
expressive than some programming languages, and that an impressive number of
programs work correctly the first time they pass the type checker. I've been
using Haskell for a while and I've found quite a bit of truth in that claim.
I've found it to be more true when I actually _use_ the type system, creating
my own data types instead of just sticking values in to lists or tuples.

~~~
mnemonicsloth
_an impressive number of programs work correctly the first time they
[compile]._

Everybody says this about Haskell, and it's probably true.

But really, isn't it about as true of Lisp, Scheme, or Clojure? Once you can
call your program in a repl, it's probably mostly right. Maybe it's just my
inexperience with Haskell showing, but ISTM that the square-peg-round-hole
errors catchable by type checking are pretty rare.

Am I missing something?

~~~
Zak
I've found my Haskell code much more likely to do what I want the first time
it is accepted by the compiler than Clojure, CL or Scheme. On the other hand,
I find it easier to play around with things in a Lisp REPL than GHCi. Maybe
that's because I have more experience with Lisp than Haskell, but I suspect
there's something inherent. I don't think one approach is better than the
other, but each has strengths that help with certain kinds of development.

~~~
skew
For one, GHCi doesn't even provide the whole language. You can't define new
types, classes, or instances, and as a matter of syntax you have to use
explicit braces or semicolons for multi-line things. I haven't used it much,
but O'Caml's REPL is better on these counts.

As far as semantics, GHCi doesn't let you redefine a function and continue
working, largely, I suspect, because Haskell doesn't describe how that should
work.

Conversely, if you keep your source open in an editor and reload, then you can
change classes, macros, etc, but you lose your state across reloading
(declaring top-level values to set up your testing state can help, but it's
less fluid).

------
ssp
The test of whether static typing is useful is pretty simple: Do you ever get
type errors when you write code with static types?

If you do (and the errors are not spurious), then the static type system is
catching real bugs that would have survived for some length of time in a
dynamically typed language.

------
baguasquirrel
I don't know why we have to rehash this argument all the time. There are
certain problems where the current state of typing technology gets in the way.
These usually involve the UI and testing layers where, for example, you may
want to mix together different types that have a common protocol or trait (the
Java people call them interfaces). This is much easier to deal with in
languages that let you (or force you to) dynamically bind methods at runtime,
like Objective-C and Javascript.

Then there's the data-processing-heavy backends where you need to do a lot of
parsing, a lot of analytics, a lot of processing, etc... static typing helps a
lot here. You do not want to make silly stupid mistakes when you're parsing
one value to another, and types help make sure you're getting the right inputs
and outputs. When you're doing your metrics, you often don't even want to be
accidentally mixing your floats and ints. If you want to get real fancy about
it, monads and functors can help immensely for managing state and joining data
for a lot of these backend problems.

The folks who don't see this generally haven't had the good luck to work on
big problems throughout the stack to see where the strengths of each paradigm
come into play. There's plenty of functional programmers who don't know how to
exploit a dynamic language (stop trying to impose types on the system dammit!)
and vice versa.

------
maw
It looks like a great example of the all else equal fallacy: "let's take
language S which is statically typed and language D which is dynamically typed
[...]. Let's also say that these two languages are identical in all respects
except for this single fact [...]"

If all else were truly equal, Britton would be right -- static typing clearly
would be better. (I think. It's a question I wrestle with quite a bit.) But
all else isn't equal [ _], so the static vs dynamic distinction is just one of
many aspects to take into account when choosing a programming language.

_ Please correct me if I'm wrong: if there's a language that has the feel and
rapid turnaround of a dynamically typed language with type checking performed
early, I'd like to know about it! The closest I've used is probably Scala,
maybe OCaml (but I've only studied it briefly, and I've certainly never
mastered it, alas).

------
j_baker
Tests and static typing are alternative solutions to the same problem. I think
we're just going to have to admit that they both have strengths and weaknesses
in comparison to each other.

I say that static typing is like a game where you have to push square pegs
into various holes that aren't square. You say that dynamic typing is like
opening the flood gates on bugs.

Oddly enough, we're both right and both wrong at the same time.

~~~
texel
They don't solve the same problem though. All static typing does is make sure
you don't have any type mismatches. Sure, it helps enforce assertions about
your inputs and outputs, but there are a million ways your code can compile
without issue and then proceed to fail spectacularly. The fact that, as this
article states, tests are optional is another issue entirely, but it doesn't
change the fact that static typing is only useful up to a point.

~~~
j_baker
I don't know where you seem to be getting that I am for static typing. In
fact, what you say about static typing only being useful up to a point is
exactly what I was getting at. Neither way is perfect to remove bugs from your
programs.

~~~
texel
I don't think I made any assumptions about your feelings on static vs. dynamic
typing, I'm just pointing out that even though on the surface they can be both
used to solve similar superficial problems, static typing is woefully limited
with regard to the scope of problems it can actually detect. Tests can go way
farther to help verify the expected results of your code.

~~~
j_baker
"Tests can go way farther to help verify the expected results of your code."

This is definitely debatable, but I think we should agree to disagree at this
point.

------
javanix
Why on earth is he blocking links from Reddit and HN?

------
anonjon
Static typing and testing are not replacements for structuring your code so
that when you read it at each level of structure you know that it is right.

