Live data from Hacker News

Type Wars

blog.cleancoder.com

11–20 of 62 posts

Re: Type Wars

#11
Honestly, I feel like the current is going the opposite direction here. In the mid-to-late 2000s the most ascendent languages seemed to be dynamic ones. Ruby, Python, PHP, Javascript, etc. Perhaps that's web solipsism, but those are the languages I remember having the highest visibility from that time.

Currently, the tide seems to be changing to towards static typing (and stronger typing). Swift, rust, go, scala, etc. Already statically typed languages seem to be borrowing ideas from their stronger typed brethren. C++ gaining concepts (similar to typeclasses from haskell), Java encouraging the use of Optional (similar to Maybe sum types) for nullable values, etc. Many dynamic languages seem to be providing type checking as an option. Clojure, python with PEP 484, various javascript dialects and type system addons, etc.

Tests are important and should supplement a static type system, since there are many classes of bugs a static type system can't prevent. But the benefits of static typing as opposed to TDD for verifying the same thing are obvious to me:

1. Tests are not proofs. Unless a test is exhaustive on the set of inputs accepted, it cannot prove that a piece of code works correctly. Types can prove that certain inputs can never be received by a piece of code, which is a stronger guarantee.

2. Tests are more work. Why write tests to verify assertions that a compiler can prove for me? In practice I find this means that unit tests attempting to verify correct behavior for incorrect inputs have gaps or are imperfect because of lack of time or lack of foresight.

3. Tests are still code. Test assertions can have bugs in the same way that regular code can have bugs. True enough, a type system is also code and can also have bugs, but the code in a type system is more visible and more attended to. In practice, I have found many bugs from flawed test assertions and none from a broken type system (as far as I know).

Re: Type Wars

#12
> The language is very opinionated about type safety... For example, the fact that a variable of type X might also be nil means you must declare that variable to hold an "optional" value... The extreme nature of the type system in swift

Oh boy, if he thinks that's extreme...

> Why am I wasting time satisfying the type constraints of Java when my unit tests are already checking everything?

Oh really? Are the unit tests testing every single 2^64 possible values of an Int? Are they testing for the existence of null everywhere you have a pointer? Strong types aren't just a little bit more info about something; they're a precise refinement of the nature of all values in a program.

While very few type systems can test everything you can test with unit tests, a decent type system and good semantics can cover all causes of crash failures and many causes of logic errors. Seriously, folks; writing programs that crash is more or less optional these days. Writing correct programs is still hard, but you can make it a lot easier on yourself.

Re: Type Wars

#13
post #9

Without those pesky types, how does one do automated refactoring in a large codebase? By hand? Types are one of the hallmarks of large scale engineering. Any codebase of appreciable size without types is difficult to work in, at least in my own experience. It takes a little bit more effort writing the types, but doing so saves so much time in the long run that it's absolutely worth it.

> Without those pesky types, how does one

> do automated refactoring in a large codebase?

> By hand?

Dunno. One could use the RefactoringBrowser. The first automated refactoring tool. Ever. In Smalltalk. A dynamically typed programming language.

The authors even talked about the tradeoffs of using a dynamic language. They thought the problems would be bigger than they turned out to be.

http://dl.acm.org/citation.cfm?id=280610

http://www.refactory.com/tools/refactoring-browser

http://c2.com/cgi/wiki?RefactoringBrowser

Re: Type Wars

#14
post #4

I don't know about what the author's goals are, but I am in favor of offloading as much work to computer as possible. To err is to be human, but compilers never forget.

Good point, the author clearly misses the point that tests themselves are code and thus can have errors in them as well. Code coverage is just a vanity metric if you're tests don't actually test the correct thing.

Types are also code and can have errors in them...

Re: Type Wars

#15
post #3

> Why am I wasting time satisfying the type constraints of Java when my unit tests are already checking everything? Couldn't you invert the question for Java and instead ask, why am I wasting my time chasing 100% test coverage when the type constraints of the language guarantee a certain degree of correctness? I've always found that dynamic language projects require twice as many tests as a Java project to get a simi…

Exactly. Types are a class of tests, checked by the compiler at compile time.

Re: Type Wars

#16
post #12

> The language is very opinionated about type safety... For example, the fact that a variable of type X might also be nil means you must declare that variable to hold an "optional" value... The extreme nature of the type system in swift Oh boy, if he thinks that's extreme... > Why am I wasting time satisfying the type constraints of Java when my unit tests are already checking everything? Oh really? Are the unit test…

> Are the unit tests testing every single 2^64 possible values of an Int?

Hmm...your usual type checker is checking 0 possible values of an int. It is checking just the type. And of course if you are checking a value in a test, you ar coincidentally also checking its type.

That's not to say that types can't be useful (for example they have been shown to be quite useful as machine-checked documentation for getting around unfamiliar codebases), but please let's not oversell...

Re: Type Wars

#17

Honestly, I feel like the current is going the opposite direction here. In the mid-to-late 2000s the most ascendent languages seemed to be dynamic ones. Ruby, Python, PHP, Javascript, etc. Perhaps that's web solipsism, but those are the languages I remember having the highest visibility from that time. Currently, the tide seems to be changing to towards static typing (and stronger typing). Swift, rust, go, scala, etc…

>Tests are not proofs

Neither is static typing. It's a layer of protection, much like tests.

>Tests are more work

I don't think that's necessarily true. You still need to write tests with or without static typing. Those tests you need to write anyway will usually catch type errors in a dynamically typed language that a statically typed language picks up at compile time.

The question is whether you need to write more tests (probably you do...maybe 5% more), and whether the greater number of tests offsets the greater amount of code you need to write to statically type your code.

As far as I'm concerned, that's not an easily answered question.

>Tests are still code. Test assertions can have bugs in the same way that regular code can have bugs

Ditto for types.

Re: Type Wars

#18
> My own prediction is that TDD is the deciding factor.

If this turns out to be the case, then people would reach for statically typed languages to augment & cut-down on tests.

Like everyone here is saying, the pendulum is moving toward statically typed. The next generation will probably be in higher kinded types as we continue to attempt to write more generic code that cuts down on number of lines, but still preserves type guarantees.

Finally, I don't think it's appropriate to regard `Option[T]` as some mystical type. It's just a regular old generic class that wraps something. Scala programmers (and I'm sure others) have been doing this with `Either[A,B]` & `Option[A]` for awhile, but Swift was really clever in building it into the language with the `?` & `!` operators.

Re: Type Wars

#19
post #4

I don't know about what the author's goals are, but I am in favor of offloading as much work to computer as possible. To err is to be human, but compilers never forget.

>I don't know about what the author's goals are, but I am in favor of offloading as much work to computer as possible.

The problem is that both writing more tests and statically typing your code involve extra code you need to write. Neither one comes for free.

Re: Type Wars

#20
post #3

> Why am I wasting time satisfying the type constraints of Java when my unit tests are already checking everything? Couldn't you invert the question for Java and instead ask, why am I wasting my time chasing 100% test coverage when the type constraints of the language guarantee a certain degree of correctness? I've always found that dynamic language projects require twice as many tests as a Java project to get a simi…

Exactly. Types are a class of tests, checked by the compiler at compile time.

Right. They are one class of tests that happens to be checked at compile time. But what about all the other tests that you still have to do? Which typically also coincidentally check the types (if I check that a value is > 2, I am also checking that its type is number (or int or whatever your particular numeric tower or non-tower says).

And what is the value of "compile time", if the all this type checking makes the compiler so slow that just compiling is slower than compiling + running unit tests in a simpler language? What if it catches 10% of errors (optimistic estimate) but due to constraints in reusability makes my code 20% bigger (conservative estimate)? Likely around 10% more bugs.

Don't get me wrong: I like static typing (to some degree). I just get antsy when it gets oversold.

Post reply on HN