the blog for developers

Explicit Static Types are not for the Compiler, but for the Developer – Duh

Lots and lots of people lament the explicit type system in Java, either they are dynamic ducks or inference intellectuals. Taken from the Boo manifesto:

“Nothing more tiresome than writing the same type name over and over just to make the compiler happy. I’m not talking against static typing in general (boo is statically typed), I’m talking against being coerced by a tyrannical compiler to say things it should already know.”

Beside the fact that my IDE does the typing with auto completion – of course the compiler knows – DUH. But the developer does not know. The developer who wrote the code does know, for about a month. When not working with the code for some time or another developer taking over – then is where the problem rises it’s head. Explicit Static Types are not for the compiler, but for the developer.

def person = Factory.getPerson()

Is person of class Person? Or perhaps Student or Employee? I’m wading through legacy code and the first thing that gets out is correct naming. What once was a person soon gets a Human. How should I know? Explicit typing is writing documentation. Not helping the compiler.

Some people claim explicit types increase lines of code. I can’t see how:

def person = new Person()

versus

Person person = new Person()

There are other things in Java that increase lines of code. Not explicit types. If I had some whishes free, I’d opt for properties and getting rid of unnecessary getter and setters, I’d like to have constructors with named parameters like in Groovy, I want syntactic sugar like [] and [:] for list and map creation, I want all attributes public unless declared private, all methods public unless declared otherwise, I want to drop the “;”, remove unneeded (cast)s where I declared the type explicitly and I wish for closures. But drop explicit types? NO!

My style of programming uses lots of interfaces. A class usually has several small ones and I try to narrow down a class to the interface I use. Narrowing down an object reduces coupling and increases reusability.

public class Person implements Nameable {
  private String name;
  public String getName() {
    return this.name;
  };
}
...
Nameable nameable = new Person();
printName( nameable );

Can I do this with type inference? What about

List persons = new ArrayList();

I guess type inference doesn’t help you here, coding against an interface and coding against more abstract entities as proposed by Robert C. Martin is out of the window. With type inference and without explicit types your code will depend on the concrete implementations, not the abstract definitions (or not depend on anything, which depends on your view ;-) Explicit typing is about reducing scope, knowledge and coupling.

Conclusion: Explicit types help the developer and create better, more understandable, more readable and more reusable code.

Sidenote to ducks: People claim that while they need 95% test coverage for dynamic code to find typo bugs, with explicit types the compiler gets the bugs for them:

“We discovered that anything shy of 95% code coverage with Rails means that type-os turn into runtime failures. We do not have any code coverage metrics for the lift code, but we have seen only 1 defect that’s been checked in in the 2 weeks since we started using lift.”

Thanks for listening.

Update: Jari wrote something about types inference, scala and IDE annotations on his blog.

You can leave a Reply here. Of course, you should follow me on twitter here.

You can share this post!
Do you want to tell others about this article? Use the social bookmark icons to submit this artice to the service of your choice. Thanks.

About the author: Stephan Schmidt is head of development at brands4friends. He has more than 15 years of internet technology experience and 10 years experience in agile. He was head of development, consultant and CTO and is a speaker, author and blog writer. He specializes in organizing and optimizing software development helping companies by increasing productivity with lean software development and agile methodologies. Want to know more? All views are only his own.
Leave a reply.

Comments

“Beside the fact that my IDE does the typing with auto completion”

Having completion doesn’t make the extra code worth having, it just reduces the number of finger presses to make it appear.

“When not working with the code for some time or another developer taking over – then is where the problem rises it’s head.”

The same IDE-using developer is certainly able to glance at the original method to see what types it has, and maybe just hover over the variable declaration to see what type the inference has given it.

“def person = Factory.getPerson()
Is person of class Person? Or perhaps Student or Employee? I’m wading through legacy code and the first thing that gets out is correct naming.”

person is a fairly meaningless variable name. You’re actually duplicating the type in the name, when you probably would be better off picking a better name, or getting rid of the name. Any time you rename a class, even in Java, you can end up with this kind of variable name becoming out of sync (IDEs can help in simple cases).

“remove unneeded (cast)s where I declared the type explicitly”

Where do you need such a cast? I’d guess most of those are misuse or lack of use of generics.

“Nameable nameable = new Person();
printName( nameable );
Can I do this with type inference?”

Yes. There’s no logic that says that type inference must always pick the most concrete type. However, as there’s no difference in functionality in your above code between you using Nameable or Person, it doesn’t matter much which is picked.

About your ArrayList example in particular, ArrayList is an example of bad API, as it exposes a List implementation by name, instead of just providing a method that gives you a List (and the actual implementation would be private/anonymous). In fact, as I’ve never adapted any code from using ArrayList to using some other implementation, I’d go so far as to say for that example, using ArrayList as the variable type isn’t insane.

“Explicit typing is about reducing scope, knowledge and coupling”

Explicit typing increases coupling by name, simply by making you repeat names. IDEs or other language-aware tools can give you everything that explicit typing has, but in a type-inferred environment.

The usual case in inference is that you can override the compiler’s choices if you like, so languages with inference only *allow* you to elide types, they don’t force you to. A step up on the ladder.

Greg M

Static types are documentation, yes. That’s still no reason to write them yourself. Your IDE could also tell you the types of things inline. On the other hand, I think declaring the type at the top of a function is good practice, so your compiler can better pinpoint _where_ your type error is when you get something wrong.

stephan

“The same IDE-using developer is certainly able to glance at the original method to see what types it has, and maybe just hover over the variable declaration to see what type the inference has given it.”

public String createIdentifiier(id);

Could you tell me the type of id?

def getPerson() {
return Factory.getPerson();
}

Could you tell me the return type? I can’t. And the call chain could be much more complex so it would take more and more time to just check the types. And decide for the correct subtype or interface of the return type.

“person is a fairly meaningless variable name. You’re actually duplicating the type in the name, when you probably would be better off picking a better name, or getting rid of the name”

So, what is a better name? Current? I can’t see how

def current = Factory.getPerson()

makes anything more clear.

Peace
-stephan

stephan

@Ricky: I thought about your comment for some time, perhaps you’re right and I should not car what getCurrent() returns, as long as it’s typed and the compiler (and my IDE) know what type it is.

And perhaps you’ve got me wrong, I’m not against type inference. I wish Java was more clever with types. But I’m against dropping explicit types. I often see this with dynamic code:

// List of <Order>
def calculate(orders)

or

// Returns List of <Order>
def orders = getOrders()

where people add the type in a comment to document their code.

@Greg: “Your IDE could also tell you the types of things inline.”

Nameable nameable = new Person()

The IDE can’t decide which type I want.

This is just some kind of design by contract, where I have a type contract for my code. The explicit declaration of what my code expects, in this case a Nameable.

def nameable = new Person()

does not declare such a contract for my code. The code following this line has no declared expectations about the nameable variable.

Well, in a language such as Scala, if you really need to narrow the type to Nameable, it’s not a problem:

def nameable: Nameable = new Person()

I for one *do* think that type declarations are redundant when they can be inferred. A smart IDE, working in conjunction with an incremental compiler (a la Eclipse), could just decorate the code view with the inferred type of the member you’re looking at, e.g.

[Person] def person = getPerson

i.e. show the type of the member without the developer having to type it down redundantly. WDYT?

stephan

@Jari: Good to know that I could do : Nameable in Scala, one of my side projects is looking into lift.

A smart IDE should know about the type, you’re right. But someone reading source outside an IDE, browsing through a repository with FishEye, using diff tools etc. will not benefit from the IDE knowledge. *Doc tools will also be much harder to write, which could lead to less documentation because the tool is not smart enough.

But I’m with you mostly, an IDE should hide or remove parts (existing things like generics, public modifiers come to mind) of code and just show them when you need them. On the other hand, when the IDE hides code and shows annotations, it’s not important anymore for the developer if the code is there or not (in real, in source). If I can hide the type, I do not care if I have added it with auto completion. Auto completion could just add the type for you without any typing just by type inference :-). And then I don’t care if the source has the type or not.

[...] Tagged compilers, java, scala, static-typing, type-inference Stephan Schmidt has a blog entry on how explicit static type declarations are for the benefit of the developer, and not the compiler. That is, when you have something like this: Person person = mysteriousCall() [...]

Matthias

“Is person of class Person? Or perhaps Student or Employee?”

In most cases the answer is: Who cares?
If I want to know it I move my mouse cursor above “person” and I’ll see a popup-window that tells me what exact type “person” has.

“Explicit typing is writing documentation.”

IMO documenting things I’m not interested in. Why should I care whether it’s a “Person” or a “Nameable” as long as I can call “printName” with it? If I can’t the compiler will tell me why I can’t.

When I see code like

def nameable = new Person();
printName(nameable);

I directly understand what it does.

I know that it fullfills the “contract” needed by “printName” as I wouldn’t be able to compile it otherwise.
If whatever nameable is does not fullfill the contract the compiler will tell me what’s wrong.

In my experience this works perfectly in other languages with type inference so I don’t see why it shouldn’t in Boo (with ‘I never used).

stephan

“If I want to know it I move my mouse cursor above “person” and I’ll see a popup-window that tells me what exact type “person” has.”

How is your IDE accomplishing that I wonder without knowing the type.

Leave a Reply

What people wrote somewhere else:

Additional comments powered by BackType

Guide to CodeMonkeyism

Over the last 4 years I wrote many articles on this blog. To make it easier for you to find the relevant ones, I've organized them into topics.

Top 10

6 reasons why my VC funded startup did fail

Go Ahead: Next Generation Java Programming Style

Java Interview questions: Write a String Reverser

The dark side of NoSQL

7 Bad Signs not to Work for a Software Company or Startup

Is Java dead?

Scala vs. Clojure

Never, never, never use String in Java

No future for functional programming in 2008 – Scala, F# and Nu

Clojure vs Scala, Part 2

Java Developer

Is Java Dead?

Go Ahead: Next Generation Java Programming Style

Be careful with magical code

All variables in Java must be final

Never, never, never use String in Java

Bending Java: More readable code with methods that do nothing?

NoSQL Guy

NoSQL: The Dawn of Polyglot Persistence

The dark side of NoSQL

Essential storage tradeoff: Simple Reads vs. Simple Writes

Sharding destroys the goals of your relational database

The unholy legacy of databases

Startup/CTO

Development Dream Teams

6 reasons why my VC funded startup did fail

American vs. European style of Software Development

12 Things to Reduce Your Lead Time and Time to Market

The high cost of overhead when working in parallel

Essential storage tradeoff: Simple Reads vs. Simple Writes

Job Seeker

Another Good (Java) Interview Question

7 Bad Signs not to Work for a Software Company or Startup

Java Interview questions: Write a String Reverser (and use Recursion!)

Java Interview questions: Multiple Inheritance

As a Manager: What I value in developers

Top 10 Tips (+1) to Get a Pay Raise

Agilist

What Developers Need to Know About Agile

5 Practices Better to Change in Your Scrum Implementation

Scrum is not about engineering practices

ScrumMaster and ZenMaster: The joke of certification

What is Trans-Scrum?