Wednesday, April 13, 2011

Find errors in compile-time with static typing

I've just read interesting article of upcomming (wishful thinking) Java replacement: http://blog.talawah.net/2011/04/gavin-king-unviels-red-hats-top-secret.html

One of core points was:
Static Typing (find errors at compile time, not run time)

What is strong and static typing

Strong typing
is when a variable once assigned cannot be assigned objects of other type. Compiler checks it at compile-time and later runtime errors are thrown when types mismatch
Static typing
is when you declare type of variable at it's creation and it cannot change. This enables full compile-time checks. No need to check type at runtime.

Static typing is a major feature of language that makes code written in it run faster than ever possible with dynamicaly typed languages. But this comes at price of extreme difficulties with doing real-time evaluation/interpretation. Yes, staticaly typed languages typicaly use some binary (intermediate or direct) format (.class, .obj, .com) for running.

What types of errors only staticaly typed compilator can find and rule out?

  • Missassigment (assigning something awkward) of variables due to simple glitch or more serious code or documentation (API) misunderstanding.
  • Missusing a variable (for example very annoying runtime exceptions in Clojure when you use normal variable but list was expected (rest/cons and so on))

What is a common mistake is that some importand types of errors are affiliated with compilator, but not with static typing. For example compiler (linker to be exact) is able to catch a problem with using non-existand method as methods are symbols in libraries. Staticaly typed language would also enforce properly using that method (parameters).

Ruby makes a use of lack of compiler by providing method_not_found() method. It is requested if someone used a .methodThatDoesNotExist(). For one interesting application see Ruby chapter in '7 languages in 7 weeks' by Bruce Tate (already a must-have classic book).

What types of errors cannot be eliminated with static typing alone?

  • Off by one, buffer overflow, integer overflow, list out of range, invalid map key
  • SQL Injection, not coding for security
  • Bad logic, edge cases, not fulfilling the contract
  • I/O and concurrency problems
  • Lack of resources (db connections closed, out of memmory error, firewall)
  • Typical bugs like missing button or something not working in Internet Explorer.

Let's see.. Some serious and very common problems on this list. Somehow using a Map instead of List become less importand in face of SQL Injection... ain't it?

Testing to catch errors

As professionals, we test our software before our clients test it. We employ alot of cool and efficient techniques to protect our reputation:

  • Manual or automated iMacros,Selenium testing of requirements/contracts fullfillment
  • Testing while building - JUnit/Mockito
  • Code review, coding standards (variable naming), API documentation in-code, javadoc/pydoc/Clojure:doc..

These are not tied to languages, but to profesional attitude towards programming craft.

Static typing promises are lies

  1. Static typing prevents only minor set of problems of little relative importance (type error is many times less serious than 'Buy' button or PayPal integration not working.
  2. Static typing is actually much less usefull than strong typing. Scala language is strongly but not staticaly typed. Programmer doesn't have to waste time on type declaration (and comming up with a type name to begin with)
  3. Typicaly compiling takes so much time while developing software, that no runtime speedup is going to make up for it. I work with java framework that takes 90 seconds to fully rebuild (class reloading problems: IBM WAS restart required). Doing that few times an hour distracts me and my colegues so much, that after few hours we are frustrated and error prone (yes, programmer can also be error prone :).
  4. Staticaly typing to speedup runtime is premature optimization. One should code so that software works, apply test suites and if there are throughtput problems, find solutions then. Typical solutions orders of magnitude more efficient than static typing are: memcached, squid reverse proxy, load balancing that works (and another one), or fully featured accelerators like Varnish. Oh, web only solutions you say? Who cares about the rest? =D>

Summary

Happy developers with power at their hands are precious resources. Do not waste it in staticaly typed environment. Do not confuse static typing with compiler or linker. Do not confuse static typing with strong typing.

When choosing next languge for your project, start with interpreted languages considering frameworks maturity. If JVM (and J2EE deployment) is a must, take a look at Scala, Clojure, Jython or JRuby.