Sunday, July 13, 2008

Dynamic Languages - The FUD Continues...

Cedric Beust has been spreading his anti-dynamic language propaganda in a presentation that he made at JAZOON. I really find it strange that someone who is respected in the Java community would spend so much effort trying to discredit alternative languages. In an attempt to set the record straight for the "busy" Java developer I tried to enter the comment below. Unfortunately Cedrics blog wouldn't accept what it felt to be "questionable content" so I have posted my comment here instead:

Hi Cedric,

I didn't mention why I believe there is so much Fear Uncertainty and Doubt when it comes to dynamic languages. Two reasons: Politics and Fear.

Dynamic languages have been hugely successful dating back to the 1950's so whether they are viable or not should be beyond debate.

So why are we debating?

The real issue is the right tool for the right job. The problem is that lots of programmers only know how to use one type of tool so aren't in a position to make an informed choice.

This inability to choose based on ignorance leads to fear. The politics comes from proprietary languages (Java, C#) where the proponents have a vested self interest in keeping us all fearful of alternatives.

I have been using dynamic languages (Smalltalk) since 1993 and Java since 1996, and I started out programming with Modula-2 and C in 1987. They all have their strengths and weaknesses and none of them are a silver bullet.

The simple truth is that for web applications dynamic approaches are massively more productive. Take a look at Seaside (Smalltalk), Grails (groovy) or Rails (Ruby) and its clear that Java has nothing to compare. The DSLs provided by these languages make web development a cinch. Productivity improvements of 2-3 times is not uncommon. This translates to a reduced time to market, and better response to business needs.

So the real question is why are these languages excelling in this way? You seem never to address this issue, assuming that the people that choose to use these languages are some how misguided or confused. Well they've been misguided since 1956 and the advent of Lisp :) They choose dynamic languages because they value an higher level of expression, allowing them to achieve more with less. This doesn't only apply to the web, it applies to any scenario where a high level, domain specific language is applicable.

You advertise your talk as a guide for the busy Java developer, yet you do very little to educate him and alleviate him of his fears.

Let me:

1. Programming is hard and there are no Silver Bullets.

2. The biggest determining factor for success are the skills of the programmers.

3. Dynamic languages are different, requiring different skills and a different programming style.

4. If you take the time to master these skills then you are in a position to choose the right tool for the job: Either static or dynamic, or perhaps both.

5. With the right skills and the right tools you have a built in competitive advantage. Human centric computing applications call for higher level languages. Dynamic languages allow for the creation of higher level domain specific languages in a way that static languages don't.

The last point deserves to be backed up. Take a look at the Groovy HTML builder as an example and compare it with Java JSP. An even better (all though more esoteric) example is Seaside in Smalltalk.

The domains where Java makes sense are shrinking. Given the performance of dynamic languages nowadays and the ability to inter-operate with lower level, high performance system languages like C/C++, I see Java and C# being squeezed.

If you want productivity and a higher level domain specific language then Ruby, Groovy, Python etc is a natural choice. If you are on the JVM or CLR then you can always fall back to Java or C# when you have to. If you are on a native VM then you can fall back to C/C++.

The right tool for the job, which may mean splitting the job in two (front-end, back-end) and using different tools for different parts. With messaging systems and SOA "splitting-the-job" is easy.

Dynamic languages will only get better, incorporating better Foreign Function Interfaces and better tooling support, in the same way Java did back in the late 90's. BTW adding type annotations is always an option if people think they are really needed, but like I say a sizeable community have thrived very well without them since the 1950's :)

Cedric. You do your self no service by dressing up your prejudices as scientific fact. How about a balanced expose?

Go on surprise me :)

Paul.

26 comments:

Curt Cox said...

For me, the "right tool for the job" argument is over-stressed. I find that I am almost always more productive in strongly typed languages. Modern IDEs have only widened this gap. Judging by the posts of others, there are people who are the exact opposite. The craftsman makes as much difference as the tool.

infixum said...

I agree with curt cox (and the blog author) that programmer quality is what really counts.
Still, the main point of the blog post was that the arguments against dynamic languages are FUD driven by politics (and, although not stated explicitly, by money). I agree there too.
There are a lot of folks who can program better in C than I can in Python. They have my total respect and admiration. I would hope to reach that skill level someday.
But if you can do a job quicker and just as well using a dynamic language, why not?
It reminds me of the whole (old) Visual Basic debates of the 90's. It wasn't the greatest language ever designed, but for people working with Excel spreadsheets (most folks who spent their day in an office), it allowed them to accomplish critical business functions.
Anyway, my two cents.

Chris Smith said...

I wish there'd been some deeper thoughts here, but there couldn't be for several reasons. One is that both sides of this argument seem to be obsessed with the distinction between "dynamic" languages and otherwise. The quality of discussion on programming languages would be far improved if we all just forgot those distinctions.

We should all ask ourselves what we really mean when we say dynamic languages. If it's the static or dynamic type system, then we should take the time to point out how the point applies to a variety of static type systems, such as those in Scala, Haskell, Agda, etc., all of which are undoubtedly far more static than the type system of Java or C#. If it's the wordiness, then "dynamic" seems like a strange word for "concise", and it's not worth propogating the myth that statically typed languages are always wordy. Other people (obviously not the author here) could understand dynamic as referring to powerful macro expansion facilities a la Lisp. Or one could see them as meaning prevalent late binding, which is certainly an older meaning of the term, and one that would include Java as a moderately dynamic language.

Just wish people would take the time to say what they mean. This god-word nonsense (after all, who could argue against "dynamic"-ness, when "dynamic" is quickly becoming the programmer's word for "good"?) is a waste of everyone's mental resources.

Paul said...

Hi All,

Its no surprise that I agree with the general consensus that the most significant factor is the programmer him/herself.

As for Chris Smiths point, I agree dynamic/static is a false dichotomy. For example Java performs a number of dynamic type checks, also Strongtalk allows for manifest type annotations and static analysis. So neither language is either fully static or solely dynamic.

What people generally mean when they say static versus dynamic is a vtable virtual function call (static) versus polymorphic message sends (dynamic). But for the "busy" Java developer this more important distinction doesn't mean much :)

I would love to raise the level of the debate too, but whilst theres FUD being disseminated I feel obliged to point out the real issues for the uninitiated in terms that they will understand :)

Paul.

Rainer said...

Check the Wikipedia article on Dynamic Programming Languages.

A dynamic language is one that allows certain amounts of flexibility at runtime.

'Dynamic Typing' is a different issue. Usually Dynamic Typing makes it easier to implement dynamic languages.

Typical dynamic languages are Lisp, Smalltalk, Erlang, ...

With those you develop and change the running program. There is tons of dynamism in Common Lisp for example. Objects can change its class to a different class. Classes can change the inheritance hierarchy - and so on. While the program is running and the existing objects will be changed automatically. So there is no need to stop a program while you change it. This makes two important things possible: a) incremental development of running programs and b) updates of running software that needs 0 downtime (telco switches developed with Erlang are a good example).

Paul said...

Hi Chris,

I would love to rewrite my post replacing all instances of "static' with "early-bound" and "dynamic" with "late bound", but I fear that for most this distinction would be meaningless.

So please indulge me and make the apprproiate substitutions yourself. For those of you don't understand these more meaningful terms then wikipedia is a good source.

I'd hate to think that I'm spreading mis-information, but our industry isn't very precise with its terminology and like I said I felt obliged to use the accepted colloquial terms just to get my point across.

Paul.

Paul said...

H All,

Even wikipedia gets it wrong (IMO). Using Java as an example of "late-binding". We are generalising and the link Rainer supplies clearly states that the general term "dynamic language" is ambiguous.

There are degrees of dynamic behaviour. The languages that I have identified as dynamic and the DSL examples I have shown rely on the ability to completely substitute any method or object at runtime. This is much more then the limited form of "later" binding represented by fixed pre-determined offsets in a vtable (virtual function calls). So Java doesn't qualify in my definition of late binding.

Alan Kay speaks about the differences eloquently. A good source is his 1997 keynote speech to OOPSLA where he makes his famous quote: "I coined the term OO and I didn't have C++ in mind".

I have a link to this on my blog under OO videos.

Paul said...

The link to the videos is broken :( Here is another one:

Alan Kay OOPSLA 1997

If you want to know what OO is meant to be then definitely watch this.

kirk said...

As much as I respect Cedric, this is one point where I believe he's wrong. I've always been more productive in dynamic languages. Eclipse got it's start from a dynamic language, Smalltalk. Smalltalk is an incredibly productive language.

The primary argument that Cedric and other make is regarding safety and the ability of the compiler to find bugs early. I agree that this looks like a win. However it is my experience that these bugs are just as rare in Smalltalk (at least) as they are in Java.

Bigger point, adding type information to a piece of code that doesn't need it makes that code less useful. It also means you end up writing more code. There are plenty of examples of code that doesn't need to be typed. Sorting is an entire class of algorithms that don't need to be typed. This is because they don't need to understand the structure (type) of the data they are sorting. They just need to know if one element is considered greater than or equal to another. That behavior can be injected. This is a trivial example. There are plenty of others.

If anything, the IDE works better with a static language argument is now being weakened by NetBeans and IntelliJ. They can do many things with type inference. People are just starting to realize that just because a place holder may not be explicitly typed, it can be implicitly typed. This is because place holders serve a purpose and that purpose is often typed to a specific class or a class of classes which will implement the same functions. This will be visible to tools that bother to look for it.

Andrew Binstock said...

It's frustrating to see the accusation of FUD trotted out once again.

You disagree with some of Cedric's points. Other commentators disagree with you and agree with Cedric.

Surely, we can agree/disagree on various points without our motives being impugned and FUD being alleged, no?

The Narrator said...

I've used dynamic languages a lot and static languages and I would say if you are writing a greenfield project with less than 50,000 lines of code with a 6 months or less development timeline and then you never have to see that code again -- go for a dynamically typed language. If you work on a large dynamic code base for several years, with multiple developers, it will eventually turn into a mess.

If you have to write anything bigger or work on a large team you're going to really appreciate static typing. You can use the builder pattern if you want a DSL. Use an IDE. Do not use the IDE as a text editor. Read the whole Eclipse JDT manual and you will be super productive in Java. I do use XSL for gluing some stuff together in the service bus though.

Another thing -- In Java, learn how to use anonymous inner classes. They're not that hard and they provide almost all the benefits of closures with a little more typing that Eclipse does automatically for you once you have an interface definition.

I have written some pretty big system maintenance scripts in Ruby and Python because they are much nicer then shell scripting and my opinion is is that some people must think these languages are great because they demand to use vi as their text editor and have never had to maintain a large application over several years.

Zos said...

"If you work on a large dynamic code base for several years, with multiple developers, it will eventually turn into a mess."

I think you have no idea whatsoever
about dynamic languages and your
conjectures are ill-formed and misguided.

There are projects implemented in Common Lisp that consist of millions of lines of code yet they haven't turned into a mess. I think that programmer quality is the deciding factor here and not the language (a few exceptions aside, PERL).

Any project can turn into a mess given a bunch of average developers and bad organisation, static or dynamic does not make a difference.

Parrots like yourself who keep propagating false views should be unemployed (in an ideal world that is).

The Narrator said...

Wow Zos. Outside of hot-button political topics I've rarely seen such vitriolic ad-hominem flaming and heck, we're only comparing programming languages here.

Dave Doyle said...

@zos: It's Perl, not PERL by the way.

And I love me my Perl with Python a second. Discipline, as with any language, works in Perl too when creating a large system. ;)

Greg said...

So dynamic language = good, dynamic typing = bad? But there are bad static type systems too. Java seems to have the worst of everything. ;)

According to the wikipedia link, the language with higher-order functions and a good static type system wins. Probably why all types of languages seem to be trending towards functional programming.

atidiopolis said...

I'm watching Doctor Zhivago right now and the dynamic language guys sound like the upstart bolshevik party, ready to free everyone from the decadence and corruptness of the statically typed languages.

It's not FUD BTW, a lot of these points. I want to know (really, I'm doing a Ruby project now), how do you do refactoring? How about code completion? These are great features. I used to global find replaces before the IDEs improved and that was extremely painful (especially for my boss).

I think it's obvious people can be successful with both types of languages. I've used enough of them to know this. It's an interesting question how well dynamic languages will scale(in terms of developers, not throughput...I don't doubt they are able to, or at least will be able to, handle high volumes), but there seem to be plenty of people trying it, and though I expect most will at least initially report how easy it is (not saying its propaganda, but I'm a little too cynical to just believe what the speaking-engagement-buy-my-book industry tells me, especially since a lot of them seem to be the same EJB-XML-Web Service architects I knew a few years ago, for whom nothing could be too bloated....I'm glad to see they've all slimmed down so :-)). The lack of typing information does seem to be a challenge for IDEs but I'd love to hear not so.

Also, what about the intermediate languages, like objective-c (though in practice objective-c is horribly verbose) where there is typed information but still a great deal of runtime flexibility. I was looking at something called Scala that seemed to handle this nicely.

Anyway, my thoughts. And those insulting others and being so emotional really should grow up.

-John

Paul said...

Hi John,


t's not FUD BTW, a lot of these points. I want to know (really, I'm doing a Ruby project now), how do you do refactoring? How about code completion? These are great features. I used to global find replaces before the IDEs improved and that was extremely painful (especially for my boss).


Refactoring was invented in Smalltalk, with The Refactoring Browser by Robert & Brant. This browser has features that still aren't available in Eclipse even today.

Dynamic languages lend themselves to certain types of refeactors better then others. Changing method signatures (method names) is difficult but this can be achieved too with a little extra work.

Type inference helps. NetBeans already has auto completion for Rails. I'm not sure how they have done this, but it proves that it is possible. Squeak Smalltalk supports message completion (it seems to use type inference as it recognises the class the message is for).

We need to remember that Python, Ruby etc are open source tools put together by private individuals in their spare time. We can't expect these languages to ship with the kind of tool support we have with Java today. I remember using vi with Java 0.9. So Java never use to have good IDE support either even with the backing of a major vendor.

The last time vendors invested in IDE support for a dynamic language was with Smalltalk, which lead to VW Smalltalk and IBM Smalltalk (personally I really like Dolphin Smalltalk). Anyone who has used these IDEs would say that they compare well Java IDEs like Eclipse. The fact that Eclipse was derived from a Smalltalk IDE speaks volumes.

atidiopolis said...

Thanks for the reply, Paul.

Your points are valid. These languages will mature. But part of your point I believe steers directly into what the Java guys say is a weakness in these languages: they don't have the robust tool market around them. This is a relevant concern. Now, it starts to make one's head hurt to consider how a language is ever supposed to grow up, if we aren't supposed to use them until their tools are ready from primetime, but luckily I don't have to solve those problems.

Anyway, I think these dynamic languages are fine. I mean, for a small project, almost anything is fine. For larger projects, no, I wouldn't use Ruby. Why?

1) Not enough tool support
2) Not enough community support
3) Not enough developers knowledgeable in it
4) Not enough proven implementations

Now I fully believe that all these things can be addressed and may very well be(its about getting momentum right?) but in the near term, I am conservative about these things and I don't feel bad about it. I don't think these technologies are going to change the world overnight; Ruby needs grow, mature, and then it will be a platform that can be recommended without hesitation. I think a lot of the guys being accused of FUD have the same perspective: they are afraid, but not for no reason. They are excited about these new technologies, but they want things to proceed at an orderly pace. This isn't diabolical, its just cautious.

-John

Paul said...

Hi John,

I agree. Tool support is one criteria you should consider before adopting any language. I also agree with the point made by Infuxnum earlier. The right tool for the job is a language that your team is competent with and are happy using.

With regards to labeling Cedrics words as FUD. I don't want to make this personal, but I suggest you read his presentation yourself and come to your own conclusion.

The wider issue is when is it right to adopt a new (perhaps non mainstream) language. This type of decision calls for a number of things to be considered, most of which are non-technical.

Misrepresenting a whole programming paradigm as intrinsically dangerous though and not fit for "large scale projects" is unsupportable mis-information IMO.

Like I say we have had over 50 years experience with dynamic languages so the question of viability has been tested and proven :)

Paul.

atidiopolis said...

I think he makes some interesting points. It's a little glib, obviously, but I think that was implied by the nature of the presentation.

I'd like to see some performance stats on Ruby and the like.

And his proposed solution - inferenced typing - to me sounds pretty good.

-John

Paul said...

Hi John,

I agree that type inference can help with tooling, but this is diferent from compulsory static typing though.

I quite like the idea of an optional pluggable type system as advocated by Gilad Bracha.

Paul.

Paul said...

Hi John,
One last point. Saying that type inference is "not applicable" to Ruby (as Cedric claims in his presentation) is nonsense. Type inference can be applied to any dynamic language. The issue is not whether you use a type system as a programming aid, but whether you bury fixed nominal type constraints into your byte code, restricting dynamic method and object substitution at runtime.

You could create a Java implementation that is fully dynamic. The issue is how method dispatch is currently implemented (the vtable). So a dynamic Java would not be backwards compatible. A type system (nominal, structural etc) can be added to any dynamic language either as part of the IDE or as part of the compiler (manifestly or inferenced). It is just another tool, as long as it doesn't constrain the computational model at runtime.


About performance. There are other ways to achieve high performance other then using a vtable and fixed offsets in your byte code. Again Smalltalk leads the way here. By using a polymorphic inline cache and dynamic just-in-time compilation (a technique which was invented in Self), you can achieve around 50-70% the speed of Java whilst still retaining message sends (See www.strongtalk.org).

I can't stress how primitive the implementations of Ruby and Pyhton are today (home hobbyist stuff :)). The concepts are sound though and borrowed straight from Smalltalk, which means that the implementations can be massively improved without breaking language semantics. Maglev is a commercial Ruby implementation in the making which is likely to reach Smalltalk like performance.

I hope I have succeeded in raising the level of the debate :)

Paul.

atidiopolis said...

Hey Paul, this is very helpful information. Thanks for taking the time in explaining it all. Where would you point me to learn more about the internal architecture of smalltalk - books in particular, as well as inexpensive, high-quality implementations? I'm curious to explore it more based on what you have said.

-John

Paul said...

Hi John,

You've restored my faith in the programming community. I like your curiosity :)

If you are on windows then what I would suggest is Dolphin Smalltalk:

http://www.object-arts.com/content/navigation/home.html

Download the free version and follow the tutorial.

If this wets your appitite then the definitive guide to Smalltalk is "The Blue Book"

http://stephane.ducasse.free.fr/FreeBooks/BlueBook/

This book feels a bit dated, but you must remember that Smalltalk was created in the 1970's. It goes in depth to explain "windows" and "the mouse" because these things were new at the time and were invented with Smalltalk :)

It also goes into the implementation in great detail. Many people have implemented Smalltalk solely based on "The Blue Book"

If you want to get a feel of the phylosophy that underpins Smalltalk then take a look at the video link I supplied earlier of Alan kay. Smalltalk has a particular view of Objects and Object Orientation that wasn't carried through to C++, Java and C# which are essentially hybrid languages.

It is partially this lack of OO purity in "mainstream" languages that inspired the creators of Python and Ruby to go on and create file based languages based on the Smalltalk OO ideal.

Enjoy,

Paul.

Jason said...

Squeak Smalltalk isn't doing type inferance.

The trick is, in Smalltalk method names are symbols and symbols are unique across the image. That means if I make a symbol #mySymbol, and then later I say somewhere else in the code #mySymbol the compiler puts in the same address. That is #mySymbol always means the exact same object.

So once you have this then method completion is easy. You can only complete on methods that exist, since no IDE can provide completions for methods that haven't been written yet. So when the user starts typing just see what existing symbols could still apply and violla.

Fred Garvin said...

Ultimately, a developer's productivity is measured by his ability to:

- Discover -- what types, methods, properties, fields, or variables are available from a given use-site?

- Navigate -- can quickly jump to a type, method, property, field, or variable declarations from a use site.

- Understand -- how fast can code on the screen materialize in your mind?

- Express -- how fast can the model in your mind find it's way to the editor without errors?

- Change -- how fast can code be structurally changed, mapped, moved, extracted, folded, etc.

- Test -- given a change in code how fast can I determine whether or not the change broke something.

Great tools make a world of difference. But tools can't be great (or even exist) if the language is not able to provide necessary information. That is why static type systems have an enormous advantage. For instance, static typing facilitates nearly all of the productivity characteristics I've listed. Unfortunately, most static languages have shortcomings regarding expression i.e., poor grammar. That is where dynamic languages excel e.g., types don't get in the way.

Lately, however, there has been a lot of impressive work on the static language front to fill the void. By far the weapon of choice is Type Inference. At times type inference, done well, seems like magic to the static-minded. It is the equalizer of language features.

C# 3.x (and soon 4.0) are blazing an impressive trail. The type inferencing going on in that language is quite amazing. The language combines inferencing with closures, reified generics, and extensions. The Java language pales in comparison. Java IDEs and analysis tools, however, crush C#'s quirky Visual Studio. Take IntelliJ IDEA. Now this is one spectacular IDE. I would not bother with Java at all if it were not for this tool. My productivity with Java using IDEA is several multiples more than with any other tool I've used (netbeans, eclipse). The makers of IDEA, JetBrains, provide a plugin for Visual Studio that offers many of the features from IDEA, which makes a world of difference... but it's still not IDEA... and it's still Windows only.

In addition, the class libraries, or modules, available to a language also have a great impact on productivity. For instance, there are mountains of libraries and third party tools for both Java and C#. It will be interesting to see how these tools will evolve with type inference features -- think Rails for C#.

At the end of the day comparing languages in isolation is pointless; s language doesn't accomplish much on its own. The whole development environment has to be taken into consideration. The characteristics I've listed, while perhaps incomplete, are at least a reasonable approach in measuring real productivity.