Anti-IDE Myths

10 Comments

Well, if you were wondering who my evangelist colleague was in my “Dynamic Languages: Rationalizations and Myths” blog, wonder no more. Please go read Steve Vinoski’s comments, they are a good read. One of my major points against dynamic languages was the inability for an IDE to provide reliable refactoring for them. Steve attacked this with a considerable amount of drivel. Here’s some good blurbs:

“The contrived Ruby example that Bill uses to “prove” [that dynamic languages can’t do reliable refactoring] is, well, contrived. Why would anyone write code like that or suddenly get the urge to rename init to init2? I’m no Ruby expert, but I’d probably rename the method and then stick a method_missing in there to catch any call instances I might have missed with my editor. “

Contrived my ass…Like I said in my previous blog. I write sucky code. I am constantly renaming methods, extracting methods, combining methods, renaming classes, deleting unneeded methods, fields, classes all the time. I never get things right the 1st time and rarely get them right the nth time. Steve, 99% of us are not the uber programmer you are. And, what Steve? Am I going to have to do a constant edit/test/edit/test continuously until I get my edits right? Sounds a lot less productive than having the IDE automatically and reliably do it for you with one click. Again Steve, I used to be in your world. Not as long as you, but still a considerable amount of time.

“I asked him if these magical modern IDEs that raise productivity and eliminate common errors also eliminate defects caused by missing or misunderstood requirements, missed use cases, or just plain ol’ bad programming. Again, no answer. The reason I asked this is that those are the bad bugs; syntactical errors are really the least of your worries. Even if the IDE spits out common idiom/pattern skeletons for you, it’s still quite possible to screw up the code logic, and neither the IDE nor the compiler is going to prevent that.”

Nice strawman Steve. When did I ever say or infer this? How is implementing in a dynamic language going to “eliminate defects caused by missing or misunderstood requirements”? It sure is going to be a hell of a lot easier to refactor your codebase to fix these problems, but eliminate? So Steve, are what you really saying is “IDE’s are not going to eliminate your bugs or poor design”? Thanks for stating the obvious. What I keep telling you is that I’m going to be 10 times more productive with a statically typed IDE when I try to fix these poor designs and logic.

“Considering how old Java is, it’s obvious that it’s taken quite a bit of time to get these IDEs to where they are today. I asked Bill if everyone should have to wait a long time, on the order of 10-15 years, before an IDE truly becomes valuable for a given language. No answer. Personally, I’d rather stick to my emacs and UNIX tools, with their infinite applicability and flexibility that can be used for development in pretty much any language, than wait around for someone else to give me a far less functional IDE that barely addresses only one language. But then again, if one language is all you got, then I guess you have no choice.”

Reality: One, I don’t remember him asking me this. Two, I think that IDEs (at least Intellij) are so well designed now that they can easily support a variety of languages fairly quickly. Add to this fact that their APIs are open (not OSS, but open) and have a great community. For instance, on a quick search I found plugins for Ruby, Python, AspectJ, XML, XML Schema, and Scala. The interesting thing about Intellij, is that it also has support for frameworks. For example, it has syntax checking and code completion for embedded Hibernate/JPA QL. Refactoring integration between Spring, JavaEE and Java. I haven’t looked at their RoR support, but I bet it is awesome. I continually find it AMAZING how these guys bang things out. They are either an army of people (doubtful) or just have an incredibly architected product (probable).

“I asked Bill if he’s ever considered that Java IDEs are the way they are due to issues with the Java language itself that must be compensated for. Consider its verbosity, for example, which is why IDEs spit out those skeletons.”

Reality: Let me go through the list of Code Gen and Refactoring items and see what is not useful in, let’s say, Ruby. There are 30 refactorings in IntelliJ + Java. Only 8 out of 30 are NOT useful to Ruby. For the “Generate..” code generation tab. 2 out of 5 are not useful for Ruby. I think the “Surround With..” tab is useful. The thing is, out of these 35 things, I *DO* use one of them *at least* every 10 minutes. This is of course assuming you believe that the unuseful things are because Ruby is a better language (I don’t beyond the closure stuff). I will admit that only 5 of the refactorings require a statically typed language to be *reliable*, but, at least for me, I do use these particular ones very very often, especially after the first prototype. (rename, move, safe delete, change method signature, inline). At least with Intellij, parameter types are also extremely useful with code completion. Good code is self documenting and with IDE code completion, I don’t have to look at a manual or source code comments to find out how to execute a method on an object. BTW Steve, what “skeletons” are you talking about? MDA bullshit? Or the crap I rarely use?

“Saying that “my buddy Jason was on a team that had to put type names in their Python function names” is certainly not even close to being solid evidence of your claim, Bill.”

Steve, I think Jason’s experience was a relevant experience.  I wrote about it because  I thought Jason’s experience was the funniest story I’ve heard. It sure isn’t the only horror story people have had with lack of static typing.

Other dynamic language propaganda

4 Comments

One of the commenters of my last blog reminded me of yet another myth:

If you learned to code in the XXX dynamic language way you’d need to rely a lot less on your IDE.

And Joe Johnson wasn’t the first to say that to me.  🙂  Another tactic I can’t stand with the zealots in the dynamic language community (and any other religious communities I might add.)  Attack your criticizer’s insecurities.  This comment translates to, “Java has made you a sucky programmer, if you program in Ruby, you will no longer be a sucky programmer” Or, simply:  “Ruby will make you an UBER programmer”  or, even simpler “You are a sinner, you must be saved”.  This is an awesome way to promote your language.  Why?  Well, because most of us programmers are geeks.  We were laughed at in school for wanting to spend our free time copying game code from magazines.  Even beat up.  So, we are inherently insecure and eager to be accepted by any crowd.

The problem with this argument is, for me personally, what happens when I switch to Ruby and miss the productivity I had with my Java IDE?  Does this mean I’m a horrible programmer and still a loser?  You readers know how insecure I am.  So, I just can’t switch to Ruby.  When I fail at becoming the uber programmer I always wanted to be after switching to Ruby, my insecurities and closet-Rod-Johnson-loving, fragile ego will just shatter me and I will end up  crying myself to sleep every night.  Sorry no thanks.  I already had enough heartache watching the biggest choke in NFL history yesterday.  I can’t take anymore.  The reality is that I know I am a horrible programmer and switching to Ruby won’t change that fact.  At least if I stay with Java, others will have the tools to productively clean up the messes I leave behind.

Ruby jobs have grown 500%!

Many are still scared by the dot.com bubble burst.  Many were laid off at least once.  So, its only natural to prey on these types of insecurities as well.  The reality is, if you read the fine print, Ruby is still only a tiny percentage of the Java market.  Even if it continues at this growth rate it will be at least 3 years before it overtakes Java.  Which is fine for me as, about that time, I have to start looking for another job as, obviously, SpringSource will have put JBoss out of business by then.  I’m fine with that.  3 years is enough time for me to collect the rest of my stock and get my wife back to work to take care of my ultimately unemployed ass.

The non-programmers of the world need a simple language to code in

Beautiful!  You mean my 94 year old grandma can help me code?  The problem with this is that this leaves a huge mess to clean up after the fact.  That’s great for the $100-200/hour consultant out there cuz they can bill thousands of hours.  Sucks for the company paying the bills.

Dynamic Languages: Rationalizations and Myths

61 Comments

The Patriots loss in the Superbowl has gotten me so depressed and down that I need to take it out on somebody. I need to rant about something, so why not about some things that have annoyed me over the past few months about the dynmaic language community.

I recently emailed the mandelbrot benchmark to a dynamic language evangelist colleague. Although benchmark results are usually pure propaganda, poor representations of how a language or framework is used in the real world, or even just plainly out of date with the latest versions of the technology, still, the performance of dynamic languages compared to Java in the example is quite embarrassing. Ruby, for example, is 500 times slower! Yeah, its hard to take seriously a benchmark that outputs to stdout, but still, if you look at the code you’re thinking, WTF is Ruby doing that causes so much overhead?

Now, when I forwarded this benchmark to my evangelist colleague, he immediately accused me of trying to put down or stamp out any challenge to the “One True Language” (Java). Its not about putting down or stamping out. Its about testing whether or not a language is a viable application platform. The thing is, if the dynamic language crowd is going to position itself as a replacement for Java in application development then they are going to have stop giving silly rationalizations for their shortcomings and promoting myths about their language and Java. This, and this alone is what irritates me about this crowd. Let me give you some examples about the rationalizations and myths they try to pull over on us:

RATIONALIZATIONS

Dynamic Language XXXX didn’t do well against Java in XXXX benchmark

Rationalization: “Benchmarks indicate very little practical information about the overall utility and performance of a given language or runtime.”

Reality: Although benchmarks are either propaganda, out-dated, or not a good representation of real-world usages, glaring differences must be recognized. A 5%, 10%, or even 100-200% difference is probably as a result of tuning or some simple undiscovered bug. In the grand scheme of things, those kind of numbers ain’t very relevant. But a 50000% difference? For such a simple benchmark? Something is seriously wrong here.

This reminds of 2002, when I first ran JBoss against the J2EE SpecJ benchmark. We had some pretty embarrassing numbers at first way back then. Although SpecJ is clearly a silly, non-real-world benchmark, it allowed us to identify many major and minor bottlenecks and helped our project to mature. For some dynamic languages like Ruby, I think what the mandelbrot benchmark showed was that the VMs/implementations of dynamic languages like Ruby are still very immature compared to Java. I don’t believe that it shows anything seriously wrong with the language syntax of these dynamic languages themselves though. Java received similar attacks in the mid 90s when it came out. Since then, the JVM has improved dramatically and according to the mandelbrot benchmark, only 10% slower than C. I expect the same out of the Ruby guys eventually. I’ll have to see how this benchmark improves under JRuby.

Ruby VM cannot support kernel threads

Rationalization: “Green threads are good enough.” OR: “Who cares, I can just run multiple processes.”

Reality: Even the basic laptop nowadays has parallel computing power. Green threads don’t take advantage of this. Blocking I/O also creates huge problems with Green Threads. Solving the problem by running many processes is a poor solution. A process is just too heavy weight compared to a thread which is why we have threads in the first place. It is very common for server-side Java applications to service hundreds of concurrent users. Besides, running multiple single-threaded processes starts to negate some of the benefits of simple design patterns like caching.

If dynamic languages like Ruby want to position themselves as a viable alternative to Java for an application platform, they are going to have to solve these issues. Many will say, “Its probably good enough for simple apps”, but it is not uncommon for project leaders to underestimate how much traffic they will get, or how much they have to scale.

Dynamic languages like Ruby, Python, etc… are not typesafe/statically typed

Rationalization: “Type-safety makes my code too verbose and makes me less productive.”

Reality: Why can’t these people learn how to type? Modern IDEs make this point totally moot with code completion and code generation. Besides, why can’t we have a dynamic statically typed language?

Lack of type safety doesn’t scale well to large teams

Rationalization: Anybody noticing the “Any software written by a large team will ultimately fail.” articles floating around in the community? Am I paranoid, or is this yet another attempt at brainwashing us into believing dynamic languages are the next fad in software development?

Reality: There are a lot of large applications in the industry being written. This reminds me of a story my colleague Jason Greene told me. He was working on a very large python project. Lack of static typing ending up being such a coordination and maintenance problem they ended up having a coding policy where everybody had to embed type information into the variable names of method parameters. Funny, eh?

Lack of static typing does not allow for reliable refactoring in modern IDEs

Rationalization: “The productivity of dynamic language XXXX makes refactoring irrelevant. Anyways, there are IDEs for Ruby out there that support refactoring”. OR, my favorite: “I don’t use an IDE, what do I care?”

Reality: I was a VI/Emacs user up until 2002 when Intellij came out with refactoring capabilities. Up until then, I was as productive with emacs, find, grep, and sed as I could be with any IDE out there. After finally becoming familiar with Intellij and its refactoring capabilities, I found that I was 5, 10 times more productive with my IDE than I was before. Now, Ruby fanboys will argue, “Intellij and Netbeans have refactoring capabilities for Ruby!” My answer is, it is not reliable refactoring. Take this example Cedric Beust gave on a recent TSS thread:

def f1(o)
  o.init
end   

def f2(o)
  o.init
end   

class C
  def init
    ...
  end
end    

class D
   def init
     ...
   end
end

If you rename C.init to C.init2, how can the IDE know which o.init must be renamed in f1 and f2? The IDE could either do these refactorings automatically (dangerous) or prompt you to confirm at each replacement point (tedious). In either case, any productivity you’ve gained with the elegance of Ruby is lost 10 times over.

So, these are just some of the rationalizations the dynamic language crowd gives when confronted with criticism. Now let’s talk about some of the myths and propaganda that is being fostered.

MYTHS

Software Engineers should use the best language for the job

Reality: I don’t know about the rest of you, but throughout my career I’ve either been developing middleware or writing applications. What other job is there really out there? Or maybe they are saying, “XXX dynamic language is good enough to solve certain application requirements”? Good enough has never really been good enough for me.

Besides, its hard enough to find an expert in one language. Its a maintenance and integration nightmare to have a project written in multiple languages. This can be bridged, to a degree, with dynamic language implementations that run on the JVM: JRuby and Jython are good examples. But unless these implementations become mainstream, they can quickly become out of date, i.e. Jython.

More lines of code means more bugs, thus dynamic languages are better.

Reality: Modern IDEs fills this gap. TDD is viable in type-safe languages too! I’m probably doing my own rationalization here, yes… JBoss 5, for example, is the 3rd major refactoring of the JBoss Application Server that I’ve lived through. I just can’t imagine doing it without the reliable refactoring that modern Java IDEs provide.

I am more productive in XXX dynamic language because the syntax is cleaner, more elegant, and more powerful.

Reality: Because Modern IDEs with a statically typed language can do reliable refactoring, this productivity gain has diminishing returns as your project gets larger. Even with small, one man projects, this reliable refactoring offsets any productivity gain you get with the dynamic language. At least, that’s what I’ve experienced.

I’ve done a decent sized project in Python before. I did find I was more productive with the first implementation. The problem is, I’m not a very clean programmer, so I end up iterating and refactoring constantly. In my case, a powerful IDE has made me incredibly more productive. Something I just could not get with a dynamic language.

Am I just a Java fanboy?

Maybe, but I don’t think so. Throughout my career I’ve done projects in Pascal, assembly, C, C++, Fortran, Tcl, Perl, Python, Visual Basic, Java, and even hacked around a little bit with PHP. While I don’t believe that Java is the one langauge to RULE THEM ALL, I do believe it is vastly superior to anything out there to build applications with. I also do not believe that Java is the end all, be all of existence. It still needs elegant, typesafe closures to complement annotations as a way to implement DSL. It needs a standard, non-code generating way of adding behavior to annotations. It needs a structural syntax to make initialization easier. AOP support might be nice too, or at least JVM support to make it easier to implement AOP-like features. Better zero-turnaround development features in both the JVM and APIs like Java EE, Seam, Hibernate, Spring, and JBoss AS would help out tremendously as well. Really, I’d be fine to dump Java for a language that supports all these things but the new language must:

  • Be typesafe, statically typed
  • Have an IDE that supports the same features as modern Java IDEs
  • Have a rich set apis and libraries to build my applications from
  • Have a viable commercial ecosystem
  • Have a vibrant open source community

While current dynamic languages do have some of these attributes, none contain all, so until then Java is my choice and I will remain a boy who is a Java fan.

Finally, I hope you realize that I’m not trying to stamp out dynamic languages, but rather hoping, in vain, that the dynamic language community admits their faults. I do wish that a statically typed dynamic language would come of age, but until then, I’ll stick with Java. Really, I don’t know why somebody hasn’t done it it. Is static typing really that hard to implement well? For example, why not gut Groovy and have Dynamic Java? Or do the same with Scala? Or add static typing to Python and get Jython up-to-date?

Well thats it, expect more ranting in the next few weeks/months on a variety of subjects. Its gonna take a long long time to get the Pats loss out of my system….

Edited: 2/22/08

Many people have been confused on what I meant by statically typed dynamic language.

1) Typesafe introductions/mixins to either an instance or a class

For example:

class Foo {}
class Mixin implements MixinInterface {}
Mixin.add(Foo.class, new Mixin(), MixinInterface.class);
Foo foo = new Foo();
 MixinInterface intf = (MixinInterface)foo;

Or:

Foo foo = new Foo();
Foo bar = new Foo();
Mixin.add(foo, new Mixin(), MixinInterface.class);
(foo instanceof MixinInterface) == true
(bar instanceof MixinInterface) == false

2) Ability to do AOP things like field/method/constructor interception without having to do bytecode magic
3) Ability to plug in at runtime annotation processing (not the Javac crap).
4) An instrument library that allows you to make schema changes to classes. (didn’t state this before)


JRuby and ActiveHibernate

1 Comment

No, I’m not changing my mind about Ruby just yet, I’m just building up debate ammo actually. 🙂

Anyways…I’ve been trying to read up on Ruby, Rails, and ActiveRecord lately and came across two different technologies I’d like to ask you readers about. The first is JRuby. JRuby is a Java implementation of Ruby, in the same mold as Jython. It allows you to run Ruby code with the JVM and also gives you the ability to use any Java API you have available in the classpath. The question:

If JRuby is stable, why would you ever want to use vanilla Ruby?

Ruby has traditionally had huge threading problems, from what I’ve read, that Java has pretty much nailed down since it improved its memory model in JDK 5.

The next piece of technology I came across was ActiveHibernate. The idea of this project is to allow Hibernate to generate Ruby rather than Java objects when you interact with your database. The project looks a little raw (there’s no downloads), but if you dive down into the code, you see that the implementation is very small. ActiveHibernate uses Hibernate’s dynamic-map entity mode along with a Ruby specific tuplizer, so there’s only a handul of things to implement. JRuby actually has done most of the work for you by providing nice utility methods to convert Java objects to Ruby. I haven’t tried ActiveHibernate out at all, but what you’d be doing is solely defining hbm.xml mapping files. The Hibernate Tools project allows you to point to a DB and generate hbm.xml files (as well as Java classes and even a small website scaffolding like Rails does), so you’d have the same productivity as active record.

Hibernate has caching (2nd level and query), optimistic locking, a rich query language, and rich mapping strategies. They have also thought about migration strategies as well. So the question is:

If ActiveHibernate is viable why would you ever want to use ActiveRecord?

There are so many great technologies in Java land beyond Hibernate that you are able to leverage with languages that run on top of the JVM. If you believe dynamic un-typesafe languages are the future (i’m not one of them BTW), then don’t you think we should be leveraging all this old technology?

Clueless, Unclear, or Both on Ruby?

10 Comments

In my previous blog, Go Away Ruby, Andy Oliver got a little upset with me in the comments section. In typical Andy style, he likes to strut the one thing he knows to show how much smarter he is than everybody else. His usual tactic is to state the one bug he found in an application to show how much the thing or the individual who wrote the thing sucks (to Andy, everything sucks) and how clever he was in finding this bug. Sounds like I dislike Andy, but I don’t. Andy is one of those rare people that know how to create an open source project, promote it successfully, and recruit talented volunteers to help him out. His mail project at Buni.org is a testament to this (cool stuff BTW, you should check it out).

Anyways, Andy had to go on a long rant on how clueless I was on Ruby. Maybe I am totally clueless, but I think he missed my point on what I disliked about Ruby and other languages like PHP, Perl, Tcl, VB, and Python. The last five of which I have written at least one project in. What I dislike is that these languages do not require type declaration in their syntax. Take this from the Ruby Language homepage:

 

# The Greeter class
class Greeter
  def initialize(name)
    @name = name.capitalize
  end

  def salute
    puts "Hello @name"
  end
end

# Create a new object
g =Greeter.new("world")

# Output "Hello World!"
g.salute

I dislike the fact that the initialize method does not require a return type and that the parameters of the method declaration don’t require a type either. Also, the ‘g’ variable has no syntactically assigned type either. I just don’t see how the refactoring and code analysis tools that Intellij and Eclipse have for Java could ever be mirrored in Rubyland, or even Python, Perl, Tcl, VB, or PHP for that matter. Maybe Andy is married to his VI editor, but I just can’t go back to the days of having grep and sed as my sole refactoring tools.

I am guilty though of using incorrect vocabulary to define my beef with Ruby or Andy. I should not have used typeless or dynamic typing and stuck purely to type-safety. Maybe things are clearer now?

If dynamic typing sucks, JBoss AS must suck

In the Go Away Ruby comments Andy state that if I think dynamic typing sucks (I don’t), then in turn I must also think JBoss AS sucks. In Andy’s world, java.lang.Proxy and JBoss’s Invocation object are just a workaround for the lack of dynamic typing in Java. Dynamic typing, in my mind at least, means that type is assigned at runtime and can even by augmented at runtime. JBoss is not trying to provide dynamic typing for the user, we’re trying to take a statically typed interface that the user defines and tunnel it over a generic construct. We are neither assigning type at runtime, nor are we augmenting types at runtime. The JBoss interceptors do not care or even interact with the arguments or return type of a method invocation. Yes, the transport layer need to use Java Serialization to marshal and unmarshal these objects, but, last I heard, reflection != dynamic typing. Even if JBoss’s use of proxies fell under the Andy Oliver definition of dynamic typing our use of it still does not fall under my beef with Ruby and other dynamically typed languages that don’t require type declarations. Our use of these constructs does not prevent me from using any of the powerful tools available in Intellij and Eclipse for refactoring or analyzing JBoss’s code base.

JBoss AOP and dynamic typing

JBoss AOP does try to mimic some of the features of dynamically typed languages. Or, as Andy would say, it tries to work around the fact that Java isn’t dynamically typed. Specifically, introductions and mixins. It would be cool if Java made it easier for JBoss AOP to provide this type of feature. BUT….not at the expense of relaxing type safety.

Could care less about performance Andy

And, yo Andy, when did I ever say in my blog I didn’t like languages like Ruby because they weren’t compiled? I don’t align myself to any performance debate when comparing interpretted or JITed dynamically typed languages. The debate sounds too similar to the C++/C vs. Java junk that flew around in the late 90’s. In any database or networked application, any overhead Ruby et al. have will probably be negligible compared to DB access. CPU power is cheap anyways.

Why Groovy is different

Now, in my last statement in Go Away Ruby blog, I talked about pushing Groovy over Ruby. Groovy is cool because you can write pure type-safe Java and get the zero turnaround. You get much of the nice syntax sugar that the Ruby guys have. Here’s an idea, what if we strip down Groovy and pull out all the untype-safe (vocab again 😉 ) things to get Dynamic Java?

Can I go back to my vacation?

Anyways, Andy now that you have proved how smart you are and what an idiot I am, can I go back to my vacation?

Go away Ruby

18 Comments

I’ve been reading the RESTful Web Services book. I like it a lot. The only thing I don’t like is that there is too much Ruby in it. Ruby, please, go away. Might be a good scripting language, I don’t know, but to push Ruby or any typeless language for that matter as the way to do things, is just plainly irresponsible. Hey, I’ve been there. Done projects in Perl, Tcl, and Python. The 1st few weeks of the projects are highly productive. You are loving life. Then you find that you need to refactor. You need to search for usages of an object, oh, guess what, you’re screwed. Its funny to me to see that the people pushing these things are usually book writers, or get-in-get-out consultants.

Using a scripting language is like going to McDonalds. The food is quick and tastes great, but the time you spend on the toilet after just isn’t worth the whole experience. Yes, scripting gives you zero turn around development. But, if the industry is going to move to scripting, let’s rally around something type safe. How about Groovy? Sure, it has its typeless aspects, but it doesn’t stop you from doing pure type safe code. The mass of Java programmers out there can easily switch between it and Java. Or even better, improve Java (and Java EE for that matter) to make it closer to zero turn around. For example, adding the ability for schema changes in java.lang.instrument or even silly things like simplifying the package structure in Java EE.

%d bloggers like this: