Confessions of a Static Typing Bigot

by coatta 4/22/2012 12:11:00 AM
I've been a strong typing bigot most of my (programming) life. Pehaps not too suprising for a guy whose favourite saying is "Every thing has it's place, and every place has it's thing." But, like some self-righteous character on a bad TV show whose comeuppance is thoroughly telegraphed, late at night I would sneak off, open up my text editor, and do some JavaScript programming. Sure, I felt guilty, but it was fun, and it didn't seem quite so much like work.

But its not like I was ready to abandon strong typing either. There truly were situations in which is seemed helpful not only to me, but to the developers I worked with as well. So, I thought to myself, maybe dynamic languages are for fun, and statically styped langauges are for "real" work. Of course, I look around me, and people seem to be accomplishing a lot of "real" work with these "fun" languages.

For a number of years, I have eschewed any particular development methodology. It seemed to me that the needs of a given organization and development team could vary substantially from one company or even one project to the next. Simply adopting one methodology and trying to force fit it into every context clearly didn't make sense. You should build up your methodology from elements that matched the needs of the particular team and project.

I'm coming to realize that this seems to apply more broadly. The choice of platform, programming language, architectural patterns, infrastructure components, etc. are all highly context dependent. So, where do dynamic languages work well? My sense, is that they are great when you have small teams with great communication. They work well with what I think of as great developers; those who care about design and are willing to take the time to ensure that it is adhered to. They definitely let you build things more quickly and sometimes with better clarity in the code. And some of my friends on the Queue board made the very convincing argument that they are the best tool for programming against the internet; when you are dealing with various different services that don't adhere to any single well-defined model.

I still find static typing useful. There are situations in which it let's me express my intent in the code more clearly. I think it's helpful to be able to say that the argument to a function I am writing is a List<Integer> rather than just a List. It tells you about the semantics that I am presupposing for the elements of that list, and the compiler will helpfully point out mistakes. I find interfaces incredibly useful for expressing abstractions and helping make sure that the encapsulation boundaries associated with those abstractions are not violated.

So, I'm going to try and avoid being a strong typing bigot from now on. I'll try to stay out of the methodology/platform/language/etc wars, and just choose things that meet the needs I am faced with.

Addicted to Interfaces

by coatta 3/30/2009 7:37:00 PM

I've read a lot recently about the advantages that people perceive in using dynamic languages. I understand some of the enthusiasm -- in fact, JavaScript is my language of choice for building little utilities both at work and home. But the idea of actually using a dynamic language for a major project at work gives me the willies. Since many people are using dyanmic languages for significant projects, I started wondering whether this was an unjustified predjudice on my part. I needed to get beyond simple fear and figure out what it was that really made a difference to me.

In the end, there was one feature of strongly typed languages that stood out for me -- and is significant enough that I am still inclined to avoid using dynamic languages in large projects. That one thing is interfaces.

So why the fixation on interfaces? I find that I use interfaces in a number of ways: for modeling, for awareness of important changes, to increase decoupling, to help enforce architectural patterns, amongst others. And I really do think that interfaces -- and strong typing -- are critical to each of these. When I start thinking about how to approach a new problem, one of the first things that I do is to consider what components will be needed and how they will interact. In effect, I come up with a model of the system. Writing down a series of interfaces is an easy way to make such a model concrete. It quickly captures significant boundaries in the system and, through the types of parameters and return values, at least suggests the interactions which will occur. In more complex situations, I might use a UML sequence diagram or a class diagram to capture and express elements of the model, but the nice thing about a set of interface declarations is that they cross the boundary from model to implementation. In effect, the model is embedded directly in the implementation. Futhermore, by separating interface declarations into their own library/module, although part of the implementation, they remain distinct within it.

This type of structure is very useful when you've got a group of developers working on a project. It emphasizes the importance and the independence of the model. Developers know that if they change interfaces they are changing a more fundamental part of the system. Changes to the interfaces will be scrutizined more closely in code reviews and will raise questions about the downstream impact of those changes. Also, it becomes very easy to spot unwanted coupling in the implementation. The implementation of one component should never directly reference the implementation of another -- only interfaces. So, as soon as you see code which refers to a concrete implementation rather than an interface, you know something is wrong. Similarly, you can create interfaces and even implementations for common design patterns to help ensure consistency throughout a project. The projects that I am working on at the moment have standard interfaces for the visitor pattern, the factory pattern, etc.

Of course, to some extent this is all possible in dynamic languages too. You can adopt conventions with regard to all of the techniques that I've mentioned above and derive most of the benefits noted. I still think its useful to have the compiler tell you about type errors, but I can understand the value that the quick turn-around that dyanmic languages bring. But in every project that I've ever been involved in one of the biggest enemies of well-structured code is entropy. Given the ongoing demands of getting releases out the door, corners get cut. Test cases that should be written, aren't. Refactoring that should be done gets postponed. With a dynamic language I think its much easier for this sort of decay to creep into the fundamental aspects of the system. Because interfaces aren't checked by the compiler, its easier for the code to decay in small increments. With interfaces and strong typing there is a barrier. And even if the barrier is half psychology and half technology, in my experience its enough to help keep entropy at bay. 


<<  April 2024  >>

View posts in large calendar


My opinions are my own, but you can borrow them if you like.

© Copyright 2024

Sign in