Sunday, October 5, 2008

The Great Divide

What hasn't been said about static vs. dynamic types in programming languages? Read on at your own risk, because here I go again...

When you think of static types what comes to mind? Haskell? OCaml? Scala? Dear friend, you are better than most of us, but you have clicked the wrong URL. Peace. See you in another post...

Did you say Java? Still with me? Good. Listen, now when the others have gone, just between you and me, the guys from the previous paragraph - they're on to some good stuff. Check it out, you won't regret it. But don't quit your day job, not just yet. It's a bit complicated, but did you ever witness extreme programming methodology implemented in a big corporation? No? Then picture this: Elbonians take over Dilbert's firm and make everybody do XP. They even send pointy-haired boss to a Certified Scrum Master course. Get the outcome? It can only end like the implementation of Carl Marx's ideas in Russian countryside. I am trying to say - there are ideals, and there is reality. In reality, Haskell programs have bugs too.

So Java, you say. How do you feel about dynamic types? Cool? Get out of here. No really, it's no fun preaching to the converted. See you!

Oh no, heaven forbid, you won't touch them with a stick. You're my guy then. So let's rewind to Java 1.4 days, after all many Java developers still use 1.4 and many others look back at it with nostalgia. Are you one of them? Ok. So what about pre-generics collections, do you think they are statically typed? Hmmm... And what percentage of your code involves collections? So this code was not entirely statically checked. Now add all the reflection stuff...

But then of course came Generics. And suddenly Java is much more complex. How do I make my code compile, gee, wildcards, captures... ?! I am trying to get something done, hello!... It's easy of course to blame Generics implementation, but if we learn something from the folks whom I kindly asked to leave in the beginning, they'll tell you that finding correct static type for every element in your program is hard. They of course think that hard is good, they are noble men with ideals, they like overcoming challenges. But you and I, we're just trying to make a living. So we curse Sun and back off to an untyped collection. Hm, maybe we're just doing the right thing? Maybe sometimes we just know that our program is correct, but the compiler demands more and more typing and wastes our time?

Java 5 was all about improving type-checking. If pre-defined types were not enough, annotations came handy. Define your own and test it at compile-time or at run-time. Did it ever happen to you that there were so many annotations, that you couldn't see the code?

See, more types is not always a good thing. Unless you're very keen on intellectual challenges. James Gosling said this about Scala - functional programs will make your brain hurt, they are for calculus lovers. He's right. It's the kind of pain you feel in your muscles when you start working out, you know, that indicates they are still alive... So working out is good, but we can't afford doing it all day, ha?

Maybe the appeal of plain old Java was that it's a combination of static and dynamic checks? So it's not that all dynamic is evil, maybe it's a matter of how much and where?

Give dynamic types a break. Who knows, you may find eventually that they're good for some things.


P.S. I've done some role playing here, just for the record. I do love Generics, even though they were hard to master. Annotations are overall very useful. Right now I don't do as much Java as I used to, and I do other fascinating languages (static and dynamic) as I, for long time, wanted to.


Paul said...

And the answer is...? There is no answer :) Nicely put. I think a lot of people have had their curiosity pricked and are now well on the road to becoming polyglots.

I like your point about XP being applied out of context, its so true :) Its also true about functional languages making your head hurt :)

A lot of Java development is going offshore. The culture in many of these offshore companies make Spikey haired boss look positively enlightened. Soviet era Gulags come to mind...

For the thinkers amongst us, we now have choice which is great :)

Yardena said...

Hi Paul, thanks for stopping by and dropping a line :-)

This post is mainly against uneducated dogmatism. It raises its ugly head once in a while, unfortunately even respectable developer-community members are not immune. I don't mind people who have done their research and reached a firm position on the topic, this way or the other (or both ways: pluggable types, gradual types, etc.). But many other "defenders of static types", usually it's the ones who know only Java (and/or C++, it doesn't make much difference), IMO base their opinion on misconception, so I urge them to ask themselves questions.

Paul said...

Hi Yardena,

I got the humour and the wit :) Hopefully it will prompt people to think for themselves and get informed.

Interestingly I see programmers falling into a number of cultures:

1. Enterprisey Stalwart - This is the traditional enterprise guy. They are preoccupied with "industrial strength", which means getting the right acronyms on their CV :)

2. Smart upstarts - Small teams using Agile/lightweight approaches and trying out new languages and/or new ideas in an attempt to achieve more with less.

3. Offshore sweat shop - Rows of programmers chained to their desk for 14 hours a day somewhere in Mumbai.

I tend to find that which culture a person falls into is a good indicator of how open-minded they are likely to be to non-mainstream languages.

In some ways this emerging stratification is a good thing as it separates the wheat from the shaft. In the 90's a lot of people came into software that just shouldn't have.

With any luck these "me too" programmers will move on as their jobs go to India or will end up stuck as Enterprisey Stalwarts in the least attractive companies.

This leaves a core of smart thinkers using their brains to get stuff done. No prizes for guessing where I wanna be :)

Well done!


Yardena said...

Hi Paul,

Yeah, there's some truth in your classification of programmers, but I believe there are no hard boundaries. I've worked in start-ups, big enterprise and in consulting, and I met some smart and open-minded people in each of these environments (including offshore - well, dunno about Mumbai, but let's say Bangalore). I think the difference between the cultures is their tolerance to ignorance and stupidity. Enterprise is more tolerant than consulting and start-ups, and offshore IT is even more tolerant. So if you take an average - you are right, but when judging individual developers - they maybe very good regardless of the badge they wear, and I hope those are the ones who read my blog :-)

If you look at responses to recent posts by Ola Bini on one side and Tony Morris on the other, it is clear that people still don't get it. I mean Tony got the title right, but then he took it to a whole another extreme...

Java success does not mean success of static typing, and Java failure on some fronts does not mean static types failure. Java success means Java success. Now if someone had put dogmas aside and tried to analyze where Java success actually comes from, that'd be nice. My hunch is that it is to do with simple, some may say "limited" or "degenerate", nominal static type system that can be easily bypassed by the developer (arrays, pre-generic collections, reflection), combined with a safe-net of very solid dynamic type system on the byte-code level, plus good performance, cross-platform support and backing by industry big-names.

We just mentioned tolerance to ignorance and stupidity, which is a result of ... well, size. It was a very fertile soil for Java. Does success give Java a bad name? No. Java earned its place where C and C++ previously stood, which static checks could be also easily bypassed using pointers. So Java took a step forward with pointer safety and dynamic safety, but not too far away.

And this is where it will probably stay - since the bright minds responsible for that step have since gone back to Smalltalk, FP, or switched to Scala, Ruby, C# or even JavaScript. Will Enterprisey Stalwarts, as you call them, and all the 90's "me too"s follow them? I doubt it. There was a blog-post recently of some proud Smalltalker exclaiming "we're way smarter than the rest" and "Smalltalk is back, it's the next big thing". The sad truth is that it's an either or situation. To be the next big thing you need to set the bar low, and then you can't keep the intellectual elite culture.

So leave Java alone - it's the most popular four-letter programming language on Earth. If your language is any smarter, it may take a bite of the cake, but will probably never take over the world. Which is good enough for me :-)

Paul said...

I agree 100%. I was generalising, "taking the average" which is a dangerous thing :) There are good and bad programmers in every culture. The thing is that some cultures have a higher tolerance to ignorance then others. In fact there are cultures that positively encourage ignorance, less the programmers get besides themselves and decide they came make technology decisions for themselves :)

The culture of an organisation is determined by the leadership. Mary poppendiek has a very good piece on leadership, well worth watching:

As for your appraisal of Java and static typing, your analysis is spot on. There is a lot of hot air out there. Static versus dynamic was always a false dichotomy.

The real issue is binding. Alan Kay says a lot about the advantages of late binding. Meta-programming is one big advantage of a late bound approach, leading to DSLs.

If Java replaced its vtable with a method dictionary, it would be as late-bound as Smalltalk. This is an implementation detail. The language itself could stay the same. Of course you could then easily embellish it with a number of late-bound features like meta-classes or mirrors, closures, mixins etc in the future :)

So much hot air over an implementation detail. Bill Joy saw the problem and fell out with Gosling over his decision to take the "quick and dirty" approach. Gosling wanted to keep the language simple and was focused on getting it to market quickly. The vtable was a pragmatic choice.

The rest like they say is history :)

Yardena said...

Hi Paul,

I think that in terms of binding JVM is at least half way between C++ and Smalltalk. As far as I understand, the method table in JVM is symbolic - HotSpot can replace method implementation bytecode with the native code. Of course, that's internal to JVM and not open to the programmer, but JVMTI can also replace method implementation. Unlike Smalltalk though it's not really part of Java the language, there's no way to add methods to classes, there's no doesNotUnderstand. So certainly meta-programming is limited, but it's not quite that static. When Gilad talks about JVM over-static-ness, he usually mentions instruction types and verification. That's why he started the invokedynamic JSR (which, unfortunately, he does not get enough credit for, lately) and invested a lot in improving verification algorithms, since he couldn't convince others to get rid of verification altogether. So this once again shows Java is a hybrid.

My own theory, very wild and unproven, is that value and class types are just not enough to solve real life problems. But different languages make up for it in different ways: C++ has pointers, Smalltalk has meta-programming, Haskell has existential types and kinds. Note that this third level (pointers, meta-programming or kinds) is recursive, so it can go on forever. Which one of them is preferable? It's somewhat debatable. Pointers are unsafe, but very good when performance is crucial. Meta-programming is somewhat unsafe, but VERY powerful. Advanced types are relatively safe, but complex for the programmer and hard to implement by the compiler, hence they are usually limited in power. But I see all of those as reasonable choices, depending on the environment. Dogmatism and dragging Java into the picture - not! :-)

Paul said...

Hi Yardena,

Thanks for pointing out that Java uses another level of indirection (the runtime constant pool) when performing method lookup. I didn't know this.

Neat idea. As you say without this Hotspot wouldn't work. It is not part of the programming model though, so can play no part in metaprogramming.

All the same it is nice to learn something new and be forced to delve into the JVM spec. I am now less ignorant then I use to be :)

Now you just need to work your magic on them others :)

BTW. I think that there is something to your gut feel about type systems. Ever since stumbling onto category theory, I've had an uneasy feeling too.



custome writing essays said...

A very informative article and lots of really honest and forthright comments made! This certainly got me thinking about this issue, cheers all.