I am the founder and lead developer of Hibernate Envers, a Hibernate core module, which provides entity versioning/auditing capabilities. I am also one of the co-founders of SoftwareMill, a company specializing in delivering customized software solutions (http://softwaremill.com, "Extraordinary software as a standard"), based on Java and JBoss technologies. After work, apart from being involved in development of Envers, I work on several small open source projects, like ElasticMQ (simple message queue written in Scala with an SQS interface), projects around static analysis (using JSR 308 - Typestate Annotations/ Checkers Framework and FindBugs), and some CDI/Weld (not always portable) extensions, like autofactories or stackable security interceptors. I am also interested in new JVM-based languages, especially with functional elements (like Scala, JRuby) and frameworks built using them (like Lift), as well as improving the ways we use Dependency Injection. Adam is a DZone MVB and is not an employee of DZone and has posted 52 posts at DZone. You can read more from them at their website. View Full User Profile

Static typing is a great static analysis tool

06.27.2011
| 3909 views |
  • submit to reddit

Statically-typed languages are great because, well, they have static typing. However very often developing using a dynamically-typed language is much more convenient. Take writing a webapp in Ruby On Rails – change some code, hit reload and you can see the new code in action. JavaScript – same thing. On the other hand change a bean in a JSF app: first redeploy (*), wait, and only then go and see the changes. Or even, run a very simple Scala unit test in IntelliJ – I don’t know why, but the compilation always takes a long time, even if the change is very minor. The total run time of the unit test far exceeds the milliseconds in which a unit test should run.

I know it’s in fact a compiled vs interpreted thing, but somehow statically-typed languages most often come in the “compiled” flavor, while dynamically typed in the interpreted one (**). I’m a huge fan of static typing, and I think static typing is the best static-analysis tool out there, but why shouldn’t it be left just at that: as a static analysis tool.

Moreover, the code is usually type-checked twice: first by the IDE (e.g. IntelliJ won’t let you run anything as long as there are errors, Eclipse I suppose does the same), then again by the compiler. Isn’t this a waste of time? If the modern virtual machines are so great at run-time optimization, is the compiler still needed, especially during development?

Adam

(*) Or just use e.g. JRebel; I think that JRebel is great, but I still view it as a huge hack on the JVM making our lives easier, rather than a “proper” solution to the redeployments problem.

(**) Scala takes a step in the “right” direction providing the REPL.

 

From http://www.warski.org/blog/?p=442

Published at DZone with permission of Adam Warski, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Andreas Haufler replied on Tue, 2011/06/28 - 2:58am

Dear Adam,

 I really like your article and totally agree with your point. Static typing seems to be one of the most underestimated things these days.

Still I think JSF+Java as an example of static typed languages get a raw deal in your example. With an IDE like Eclipse or Netbeans attached, JSF pages as well as Java code can be changed on the fly, without restarting the servlet-container. As long as you don't add/remove methods or fields, the hotcode replacement will immediatelly reflect your changes in the running system.There are 3rd party libraries which are even more powerful and permit almost all kinds of changes in a running developement system.

best regards
Andy

Adam Warski replied on Tue, 2011/06/28 - 10:18am

True, tools like Eclipse/Netbeans or JRebel, which I was writing about, make writing JSF or other Java/Scala-framework much more feasible, however the amount of tooling needed for that (and that's tooling with quite important limitations, e.g. as you write: hot swap works as long as you don't add/remove methods or fields) indicate to me that something is wrong. I'd like a statically typed language, with the ease-of-use of a dynamic language :) Adam

Cloves Almeida replied on Tue, 2011/06/28 - 10:43pm in response to: Adam Warski

The problem is not compilation or typing. It's the container (either pure servlet or full-fledged Java EE). You can use the change-refresh pattern in the pure Java Play Framework.

For some kind of applications (enterprisey ones) the container is decent tradeover. JAX, JMS, JTA, JPA and lot of other Js are life-savers sometimes.

Adam Warski replied on Wed, 2011/06/29 - 1:33am in response to: Cloves Almeida

But JAX, JMS, JTA, JPA can also be used in e.g. a JRuby app deployed on an app server (see Torquebox for example). It doesn't require compilation to work. As for Play, I think it uses similar hacks as JRebel ;) Adam

Fab Mars replied on Wed, 2011/06/29 - 1:15pm

Satatic typing saves your day in so many ways, especially when several people work simultaneously on one project, that I sometimes wonder why this dynamic/static debate even exists.

Now the redeployment time is something else that really needed to be addressed with Java. With modern computers, the compilation/jar/war/ear'ing takes a couple of seconds. But most containers are sluggish to redeploy. With Glassfish3, you can now reload your app in seconds, no longer in minutes (or hours for Weblogic).

Well with nowadays' computer power, I don't care the IDE compiles and checks. It helps finding many mistakes in advance. And sometimes it's good to have compiled .class too, because you don't want your customer to see some little secrets...or youldn't want anyone to see some resources hidden in the code.

I've programmed in many languages and on NO account would I switch back to a language that's not strongly typed. Yes, sorry, I use php(cli) for my backups, that's the only exception :) Now I respect other's points of view which also greatly depend on the type of project, the size of the team, and some requirements...

Cloves Almeida replied on Wed, 2011/06/29 - 6:37pm in response to: Adam Warski

If it works well, it's not a hack, it's a feature! JRebel is so fast and transparent that first time users (me at least) barely believe it.

IMO, someone should buy the JRebel guys and integrate the technology into an server to promote their use.

But you're right. The container promotes the redeployment model by providing a number of application lifecycle callbacks, but it does not forbid one to ignore them all.

Adam Warski replied on Thu, 2011/06/30 - 1:05am in response to: Fab Mars

Well compilation doesn't hide anything apart from variable and parameter names, you can easily decompile everything ;) And for a larger project, compilation takes much more than a couple of seconds ... But I'm with you of course on the static types front :) Adam

Ciprian Mustiata replied on Fri, 2011/07/01 - 12:43pm

I gonna half-disagree. Static type does not avoid a lot of crashes that are because your framework give to you the wrong type, but mostly cause of bad programming patterns. I was used with design-by-contract + TDD to make a good quality code. The use of static types will marginally increase the code robustness. Not all compilers will give to you the hint: variable may be null on this access, or this conversion from your interface type to that specific type may fail.

I also agree that some frameworks do enforce types so reduce the changes to get ugly errors and you don't know why your code is still running (and break it badly your data-records) when you would expect to better stop with an exception. I don't know any reason why dependency injection would not work with any reflective language, but some extra type checking may make the code easier to read.

At the end I think that mistakes as static analysis are not in types, cause I mostly found that exceptions are mostly: null pointer exception, invalid conversion (so no difference between types), automatic conversion (which may be ugly from the standpoint of dynamic/static context), other reasons (invalid db connection, and such, which are out of the system) and static analysis can be made as part of the framework. In fact, some of the most complex systems I know work in a middleware based coding, and I don't know why a dynamic language could not give an automatic wrapping of the small components interfaces. Also a small description of the code and the concisness of that code can make it less prone to bugs.

So my understanding is that typing (as understood like classes, primitive types, references, and such) is both a "constraint enforcer" yet is too weak and give also the overhead when is needed to make conversions that make at the end the code fragile. I would took your comment like: "if you would not use a GC, you will understand how memory management works so less chances to have leaks". I do understand that a lot of people have leaks in GC, but the main issue is bad programming patterns, not bad abstractions.

Sirikant Noori replied on Sun, 2012/01/15 - 12:17pm

Regarding the SBT OOMs. Typically they are caused by PermGen being exhausted. Adding -XX:+CMSClassUnloadingEnabled to the startup flags of SBT improves it’s “lifespan” (as defined by the time you don’t get another OOM).

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.