Static Typing and Readable Code

Neal's post Static Typing is Communist Bureaucracy has drawn out the usual arguments on both sides of dynamic vs. static typing debate. I fielded many of the same kinds of questions at my Rails for Java Developers talk at Java University.

One of the most common questions asked by people moving from static to dynamic languages is "How can I tell what the code does without the type information?" This is a good point! Static typing makes code readable, just like training wheels make a bicycle ridable. But eventually you want more than not-falling. You want elegance and speed.

Here is a specific example from R4JD. Consider the following (old school) Struts+Spring code from a simple CRUD app.

  public ActionForward edit(ActionMapping mapping, ActionForm form,
                            HttpServletRequest request,
                            HttpServletResponse response)
      throws Exception {
    PersonForm personForm = (PersonForm) form;
    if (personForm.getId() != null) {
      PersonManager mgr = (PersonManager) getBean("personManager");
      Person person = mgr.getPerson(personForm.getId());
      personForm = (PersonForm) convert(person);
      updateFormBean(mapping, request, personForm);
    return mapping.findForward("edit");

There are nine static types in play here: one return type, four arguments, one exception type, and three local variables. An experienced Java developer should have no trouble reading this code. Here is the equivalent Ruby on Rails code:

  def edit
    @person = Person.find(params[:id])

There are only two dynamic types in play here: the params and the @person. A novice Rails programmer should have no trouble reading this code.

Why are the two examples so different?

  1. The Struts example uses four typed arguments where the Rails example uses none (equivalent objects are available as fields on the controller instance, but they are out of sight unless you need them).
  2. The Struts example introduces two types (Exception and PersonForm) for no other reason than to make the compiler happy. This is the obvious example of Neal's Communist Bureuacracy argument.
  3. The Struts example uses two different objects to represent the same person: personForm and person. In the Java world this approach is a good thing, and called separation of concerns. Compared to a more flexible language, this is another form of the Communist Bureaucracy. Because Java classes are closed at compile time, you must get the separation of concerns right at design time. In a language with open classes (Ruby, Groovy, Smalltalk, et al) you can separate the concerns only when and if they need to be separated.
  4. The Struts example introduces a manager layer. More Communist Bureaucracy. The manager layer anticipates a future that may or may not happen. Because the language is inflexible, future-proofing is often done during initial development.

Languages do not write readable code, programmers do. Trying to bake readability into a programming language is like trying to bake poetry into grammar. A better idea is to create a flexible language and let human creativity flow.

Get In Touch