Sponsored Link •
Developer productivity is as much a factor of productive frameworks as it is of language capabilities. Is there anything in Java that limits framework architects in their quest to design more productive APIs and frameworks? How do language features impact framework design?
Much recent discussion about Java has focused either on the shortcomings of the language, or on how adding new language features to remedy those shortcomings would make Java more complex, especially for less advanced programmers. While recent Java criticism appears to center around the language, the real issue is developer productivity. Bill Venners, for example, bemoans that:
For several years I have been jealous of the joy people seem to feel when they program in Python or Ruby. I believe the sense of satisfaction stems primarily from feeling, and actually being, more productive in these languages. Although I have no doubt that my choice to use Java for Artima's architecture was the right one, for me Java was a practical choice, not a heart choice. When I work in Java, I wouldn't say I feel joy. I don't feel like I'm riding a fast stallion through beautiful wooded hills, the wind in my long, flowing hair. I feel more like I'm struggling to convince a workhorse to pull a plow.
Elsewhere, Bill Venners says that:
I think there is a natural law of languages that [says] that [a language] over time becomes harder and harder to enhance while still maintaining backwards compatibility. If a language is as successful as Java, it's really expensive to break source compatibility with Java in subsequent releases of the language. It becomes harder and harder to improve things... And it comes a time when it may make sense to jump to a language that is not source compatible, but is binary compatible.
Bruce Eckel seems to agree, adding that,
If Java is to be saved at all, it needs to become like C; a workhorse that you can rely upon. In fact, any future changes to the language need to be things that simplify and clarify the language and its use (say, fixing the classpath problem), and flesh out (for example) incomplete libraries that have languished...
But we need to become especially conservative when considering major, fundamental language features like closures which, while they can be very appealing in theory, may have a cost that is too great in practice when they are forced into a language that values backward compatibility over the clarity of its abstractions.
While the capabilities and design of a language are important, a language is but one determinant of a developer's overall productivity (and I presume that a highly productive developer is a happy one, all things being equal). Many projects choose Java more for its APIs and developer and deployment tools than for its language features. Indeed, few Java developers embark these days on a new project without relying on some framework, whether for persistence, the Web tier, or even for desktop applications. Using Java is increasingly a task of interacting with Java frameworks.
If Java developers spend a large portion of their time working with frameworks, and if the best Java developers still feel lacking in productivity—"struggling to convince a workhorse to pull a plow"—to what degree is that due to the lack of agility of Java frameworks, and to what extent is that attributable to the language itself? More interestingly, to what degree does Java's design handicap framework architects to create more productive tools?
Some of those critiquing Java often point to Ruby as an example of a productive language. Ruby code, indeed, is beautiful to look at, and I can say from experience that writing Ruby applications does make you feel productive (and sometimes happy). However, the pre-eminent Ruby application today is Rails, whereas the Java landscape is much more divided between a myriad of Web, persistence, and desktop frameworks. Could it be that part of the productivity emanating from the Ruby community is really due to Rails, and not as much to Ruby?
A little-discussed aspect of Rails is that you don't need to know much Ruby to write even a fairly substantial Rails application. A competent Java developer could learn probably in a single day all the Ruby he needed to develop a feature-rich Rails application. A typical Rails application consists of short snippets of Ruby code pulled together by the framework into a coherent whole. Behind the few lines of Ruby application of code is a clever exploiting of Ruby's metaobject protocol and module system that hides a lot of complexity from the developer.
But the designers of Flex hide much of that complexity: as with Rails, Flex applications tend to consist of small snippets of ActionScript code, short functions, mixed together with an XML-based UI layout language. Learning Flex is not so much a question of learning advanced features of ActionScript 3, but is about learning how the Flex framework affects some desired functionality.
Both Flex and Rails selected aspects of their respective languages that are relatively easy to master, and strongly encourage the use of those features in their designs. That's exactly what every framework should do. Without Rails nudging developers in a certain direction, steering clear of Ruby's more esoteric features, we may all be complaining now how Ruby leads to overly complex and hard-to-understand code. And without Flex, few would be inclined to touch ActionScript (or even EcmaScript 4).
In a recent blog post, Cay Horstmann complains that one his Java pain points is exactly in the area of Java frameworks:
When I embark on another web application ... I groan. I use JSF in the forlorn hope that someone else has given me components that make me not worry about AJAX and GET vs. POST, all of which have nothing to do with the problem that I want to solve. But then I ... despair. If I have to paste random pieces of code to make things work, I just know I'll be hosed when things don't work.
Come on, folks, When I write a web application, I want to be able to say "This is the common layout of my pages, give me a standard login screen, I want a menu here, and fill that table with those database values, but add a column with buttons..." I can do it in JSF, but it is like eating soup with a fork.
Why is it that Sun can't give me a decent web framework? Is it a shortcoming of the Java language? Or crummy API design? ... I think in this case, the Java language is sufficiently powerful, but we are hobbled by backwards compatibility with JSP and JSF, both of which are simultaneously complex and underpowered. Or could a language enhancement such as continuations make web programming dramatically easier? If so, why does Rails get all the buzz and not Seaside?
Horstmann asks the excellent question of whether there is something in Java that prevents framework architects to design a highly productive, cruft-free, and beloved framework in Java. If so, then what in Java makes it hard to write good frameworks in that language?
On the surface, it seems that some of the emerging and popular frameworks use dynamically typed languages in order to avoid unnecessary code generation and clutter. Ruby and ActionScript 3 also provide functional features and closures that their respective frameworks fully exploit. Yet, I don't believe that any those features make these languages more suitable for framework construction than Java.
Rather, the notion of a scalable language may have to do with framework bliss to a greater extent. In their book, Programming Scala, published by Artima and recently released in PDF PrePrint, Martin Odersky, Lex Spoon, and Bill Venners, write that:
Scala has a set of convenient constructs that help you get started quickly and let you program in a pleasantly concise style. At the same time, you have the assurance that you will not "outgrow" the language. You can always tailor the the program to your requirements, because everything is based on library modules that you can select and adapt as needed...
Scala is much more like a bazaar than a cathedral, in the sense that it is designed to be extended and adapted by the people programming in it. Instead of providing all constructs you might ever need in one “perfectly complete” language, Scala puts the tools for building such constructs into your hands.
I recall James Gosling mentioning many years ago that one of his, and Sun's, goals with Java was to create a language that allowed developers to write big programs reliably. Indeed, Java is eminently suitable for that task, as many large enterprise applications, IDEs, an application servers written in Java demonstrate.
But I have a feeling that most developers don't really want to write big programs. I certainly prefer a model of programming when I can write a few lines of code to affect just the functionality I desire. I can get that with Ruby and ActionScript, and even in Scala. But Java somehow always feels like having to drive a big rig to the convenience store. It scales up very well, but doesn't scale down as neatly for smaller jobs.
On that note though, the more I learn about Ruby, I'm beginning to think that just as Java doesn't easily scale down to smaller tasks, Ruby wouldn't scale up to large systems: The way Ruby classes can be opened up and parts of a class redefined—a very handy feature when writing Rails modules, for instance—can, for instance, lead to completely incomprehensible programs in the wrong hands.
In the case of Ruby, the existence of Rails remedies the language's potential scalability issues. As Rails is increasingly employed in larger, enterprise tasks, it remains to be seen whether the ability to scale down a language is overall more important than for a language to scale up to huge programs: It maybe that scaling up can be done with good frameworks, but scaling down really needs support in the language itself. The jury on that is still out.
Perhaps new languages that can scale down to small tasks as well as scale up to big programs, such as Scala, will lead to more powerful and better frameworks overtime.
If you were to write your own Web/persistence/desktop framework, what language would you pick? In what way do you think language impacts framework design?
|Frank Sommers is a Senior Editor with Artima Developer. Prior to joining Artima, Frank wrote the Jiniology and Web services columns for JavaWorld. Frank also serves as chief editor of the Web zine ClusterComputing.org, the IEEE Technical Committee on Scalable Computing's newsletter. Prior to that, he edited the Newsletter of the IEEE Task Force on Cluster Computing. Frank is also founder and president of Autospaces, a company dedicated to bringing service-oriented computing to the automotive software market.
Prior to Autospaces, Frank was vice president of technology and chief software architect at a Los Angeles system integration firm. In that capacity, he designed and developed that company's two main products: A financial underwriting system, and an insurance claims management expert system. Before assuming that position, he was a research fellow at the Center for Multiethnic and Transnational Studies at the University of Southern California, where he participated in a geographic information systems (GIS) project mapping the ethnic populations of the world and the diverse demography of southern California. Frank's interests include parallel and distributed computing, data management, programming languages, cluster and grid computing, and the theoretic foundations of computation. He is a member of the ACM and IEEE, and the American Musicological Society.