So SmallCheck works exhaustively to find a minimal counterexample within some depth bound. This makes sense - when trying to characterize a structure for failure (or anything) you can rarely do better than the simplest explanation. However, when the problem lies in larger examples SmallCheck fails where QuickCheck catches a result so something like Type Check -> SmallCheck -> QuickCheck -> probably ok.
[] http://www.cs.york.ac.uk/fp/smallcheck/ documentation
http://permalink.gmane.org/gmane.comp.lang.haskell.general/1...
[1]: http://lambda-the-ultimate.org/node/1178
Happily, there are practical programs that take advantage of the types' expressiveness. My favorite example: Hoogle[2]. It's brilliant: a search engine that given a type signature gives you a list of functions either with that type (modulo renaming) or a similar type. The beauty is that it can work even if the function is more general than what you're looking for and has a weird name (so a normal search would not be very helpful).
[2]: http://www.haskell.org/hoogle/
A perfect example: let's say you're looking for the equivalent of JavaScript's join method. It would have the type [String] -> String -> String. Now, this particular function does not actually exist in Haskell. Instead, there is a more general function called intercalate that works on any list. Moreover, intercalate's arguments are reversed: it's type is actually [a] -> [[a]] -> [a] (or String -> [String] -> String if made specific to String). And yet, if you search for [String] -> String -> String, the second result is intercalate! It's magical.
In short: types are basically a form of self-documenting code, so you get a lot of cool stuff for free given a good type system.
http://www.cis.upenn.edu/~sweirich/plmw12/Slides/plmw12-Pier...
http://www.haskell.org/haskellwiki/Phantom_type
http://stackoverflow.com/questions/8600692/datatype-promotio...
For scala:
http://groups.google.com/group/scala-internals/browse_frm/th...
http://www.chuusai.com/2012/01/27/type-level-sorting-in-shap...
-------------
SAT and SMT solvers, e.g. in OCaml
http://caml.inria.fr/cgi-bin/hump.cgi?contrib=706
-----------------
I could give a few dozen more examples in these 3 languages, incluindg Coq which is written in C and OCaml, and agda and idris and others, which are written in C and haskell, or compile down to some stage of haskell compilation.
(+),(-), (*) all have the type (Num a) a -> a -> a
abs, signum both have the type (Num a) a-> a
In the first case it works as documentation because I already know what they do. In the second case I read signum as sig num instead of sign num, and was left scratching my head as to what a signature number was, until I read the actual documentation.
So I would say types make a good reference documentation but not a good learning documentation. Contrast this with python doc strings which can be both a good reference and a decent source of learning.
Static types are implemented and available for use at the language level, which isn't true of all of those features in most environments.
However, static typing is enough for some sweet, sweet hit-dot-wtf-can-i-do-completion-refactoring-like-a-boss tooling goodness.
(any of the other stuff mentioned) .. ensure correctness
The post says that.Dot-completion in your IDE is not enough either, nor is it something particularly unique to static languages.
I really could give a shit about what people think is "enough" (IMO, keeping stuff simple, as in simplicity of implementation, as in worse-is-better, is the only answer) I just want to hit dot and have a pretty good idea what I'm allowed to do. And static typing, in practice, appears to help there.
But hey, man, I'm not advocating you use it.
But hey, man, I'm not advocating you use it.
I'd be crazy to give up dot completion. I like it as much as the next guy. ;-)I think the grandparent knew that, and was just repeating what you said to contrast it with his following statement about what static typing is good for.
And dot-completion is not completely unique to static languages, but I would say it is “particularly unique” – it is more common for static languages. And that’s not just coincidence – it is generally easier to write a tool like dot-completion for a static language than a dynamic language, because dot-completion involves static analysis of the code.
Dot-completion involves having a living model of the program loaded in memory. You can do this with any language--static languages just partition the program model such that you get a certain phase of interpretation (compilation) past which you have a completed model of all of the code, without yet having seen any of the data.
On the other hand, you can easily dot-complete method calls in a dynamic language's REPL--because there, at runtime, is when and where a dynamic language forms a complete model of the program it can use to do such things.
Now, the real question is why we're still programming dynamic languages in text-editors instead of treating them as congealments of transactionally-replayable interactive REPL transcripts. (Are there any modern examples of programming in this style, anyway? I can only think of ancient ones: Emacs Lisp, Squeak Smalltalk, and the "immediate-command-line" of some Telnet-based simulated-world MOOs.)
The paper makes a point of reporting that most unit tests could not be replaced by static types.
What of that looks like a claim that you only need types?
I believe the point is that there will always be something your current test strategy doesn't cover. At what point do you draw the line?
If unit tests and static types don't cover everything, what says that's enough? And can the justification for that, whatever it is, be applied to "unit tests are enough" also?
But that doesn't mean all bullets are created equal.
Unfortunately, this is not enough. You need a consistent and complete specification, too.
The second isn't so clear, but sometimes you can get a bit more confidence by showing that other good properties are implied by the specification alone.
Also: <3 Love Driven Development <3
Accidentially, almost everything that the author suggests, except luck and user testing, can be provided by static type systems - e.g. Haskell's type system is Turing-complete, so you can make up any kind of contracts/tests and embed them into the type system...
If you want to go that road, look up Agda or Coq.
In both theory and practice, this means you can't really use Haskell that way. It's a typed language with the ability to occasionally skirt the limits, ride the line, and dip into a bit of undecidability when useful (and with a real, in-practice risk of it blowing up in your face even so), not a language in which one routinely uses the type system in a "Turing complete manner", if I may be allowed to gloss over precisely what that means. Richer type systems is a topic of ongoing research, but is not a solved problem.
Haskell's type system is Turing-complete
So? What does that buy you in the face of attempting to prove that your system can run with two simultaneous users? How does the type system prove that it can withstand a DoS attack? Likewise, how can it prove that your system properly handles the case where the user types some garbage into a textbox? How does it help prove that your system keeps running if someone pulls the network cable out of the wall? How does it help prove that you wrote the system that your client wanted?