5 ms·
Testing is not a Replacement for Static Typing
- regularfry 17y agoStatic typing isn't a replacement for testing, either. You can get away without static typing. You probably can't get away without testing.
- runevault 17y agoYou 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 17y agoHaskell 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 17y agoan 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 17y agoI'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 17y agoFor 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).
- silentbicycle 17y agoDue to type checking, the compiler verifies that it still works as you refactor. People don't usually re-test everything exhaustively in a REPL after changes. Type checking is still in effect during long-term maintenance.
- j_baker 17y agoTo be fair, you probably could get away without either static typing or testing. I'm an advocate of testing, but there are some projects where testing doesn't make sense. For instance, I hardly ever write tests for tools I work with every day. This is because I'll know if something breaks before the tests will.
- mquander 17y agoThis 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.
- j_baker 17y agoTests 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 17y agoThey 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 17y agoI 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 17y agoI 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 17y ago"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.
- Zak 17y agoMost 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.
- ozy 17y agoLet 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.
- Deestan 17y agoJust 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_QuickCheck http://www.haskell.org/haskellwiki/Introduction_to_QuickChec...
- deleted 17y ago[deleted]
- ssp 17y agoThe 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 17y agoI 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.
- javanix 17y agoWhy on earth is he blocking links from Reddit and HN?
- anonjon 17y agoStatic 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.
- maw 17y agoIt 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).