Pinderkent

Pain and glory from the trenches of the IT world.

Parrot just can't compete with LLVM, the JVM, and the .NET CLR.

Posted on Sunday, May 23, 2010 at 11:51 AM.

I read an article today, written by Andrew Whitworth, that discusses Parrot and its fitness as a target platform. His article, along with other recent developments, may very well answer the question I asked nearly three years ago, Will Parrot ever truly deliver? Unfortunately, the answer appears to be a resounding No.

For those who might not be aware, Parrot is, according to their web site, a "virtual machine designed to efficiently compile and execute bytecode for dynamic languages." Although it has been in development for about a decade, there has been comparatively little to show for all of the effort that has gone into it. Sure, there have been frequent releases, but in the end we still don't have a platform that garners much attention, and we still don't see anyone really putting forth a lot of effort to target it.

Andrew's article helps highlight why both language implementors and users may be hesitant to spend time targeting Parrot. Towards the end of his article, he covers parts of the system that he thinks will be seeing major changes within the next few months. Throughout these seven points, we see some very unsettling things. The very first point, for instance, mentions that, "GC is a very internal thing, when it works properly, you don't even need to know it exists." Now, garbage collection isn't a trivial task, but it has been very well studied and implemented many times over in real-world systems. Although we can't expect any such system to be perfect, it is unsettling when we read statements like "when it works properly" regarding a ten-year-old virtual machine platform. There just shouldn't be so much doubt about such a fundamental part of a virtual machine.

The second point is no better. Just-in-time compilation, like garbage collection, is another one of those cornerstones of a VM that we should expect to be mature and robust after 10 years. It's very worrisome to read that Parrot is lacking so badly in this area, even after two major releases.

The third point is perhaps the worse of all. In it, he states, "We don't really have a good, working, reliable threads implementation now and HLLs are generally not using them." It's currently 2010, and the situation today is that almost all new desktop PCs, and even many notebooks and netbooks, have a CPU with at least two cores. Most server-grade computer systems offer several times that, with multiple CPUs, with multiple cores per CPU, and even multiple threads of simultaneous execution per core. Efficiently using these systems to their full potential currently means writing multithreaded software. Like garbage collection and just-in-time compilation, threading has been well-studied, implemented repeatedly, and is one of the major pieces of any virtual machine platform. There's just no excuse for Parrot not to have better multithreading support.

The fifth point is pretty serious, as well. It discusses packfiles, which are the files that contain Parrot bytecode, debug data, and so forth. This is one more essential part of any VM implementation that should be very mature after a decade's worth of development. It's disappointing to hear that there are still portability issues with these files after so many years.

After reading about those rather serious deficiencies, I have a hard time understanding how Andrew can suggest that, "In summary, Parrot is a good, stable platform for HLL developers to use." From what I can see, Parrot is a platform that has had a lot of time and opportunity to make something of itself, but due to various problems, from internal developer strife, to a bad reputation, to a lack of serious users, it just hasn't matured.

Since I wrote my other article about Parrot almost three years ago, we've seen major developments out of the other major VM providers. We're seeing the Java platform get better support for dynamic languages in the upcoming JDK 7 release. We've also seen Microsoft's Dynamic Language Runtime become available for their .NET platform, allowing for mature and usable language implementations like IronRuby and IronPython to be developed.

Perhaps the biggest threat of all to Parrot is LLVM. LLVM has become widely accepted by industry, and even significant open source projects like FreeBSD are integrating and supporting it. In addition to having excellent support for C, C++ and Objective-C, we're even seeing it used as the back-end for dynamic programming language implementations. Rubinius and MacRuby are two examples of Ruby implementations that support LLVM. Then there are Python implementations like Unladen Swallow and PyPy.

I just don't think that Parrot can compete with these other platforms. Parrot has spun its wheels for far too long, and just isn't as mature as the JVM, the .NET CLR, or LLVM have become. Aside from casual or hobby development, I don't see why anyone would develop a software system specifically targeting Parrot. Its future seems extremely bleak at this point.

Permalink: http://pinderkent.phumblog.com/post/2010/05/parrot_just_cant_compete_with_llvm_the_jvm_and_the_net_clr
Share:

Analyzing existing databases and their relationships with applications.

Posted on Saturday, October 17, 2009 at 3:24 AM.

Anybody working on business applications these days will undoubtedly have to familiarize himself or herself with one or more existing databases. These databases have often been "grown" rather than designed in any meaningful way, and thus will be littered with unused tables, unused functions or stored procedures, missing constraints, poor normalization, and a host of other problems.

Developers in such a situation will often look for an easy way out, such as the use of tools to automatically reverse-engineer various parts of the existing database or databases. While these tools can be useful, I don't think they are ever a replacement for just stepping through the code, line-by-line, and observing exactly what queries are executed.

Depending on the application, it may even be a bad idea to try and think of the application and database as separate. Many times we find that one can't exist without the other, and vice versa. For instance, we find hard-coded SQL queries within the application code written in languages like Java, PHP or C#. In such situations, one literally has to take a debugger and step through the application code in order to get even a basic understanding of how the system works.

Another thing that may be worth avoiding is trying to understand the system all at once. Often, it will take many months to truly grasp even a moderately sized application and the database behind it. As changes are made or bugs are fixed, take a moment or two to study and document the code paths that are involved. Doing this on a daily basis will eventually expose a developer to large portions of the software system they're working with.

Regardless of the approach, one thing to keep in mind that it's not an easy task becoming familiar with existing codebases and databases, especially when they're as ugly as so many real-world systems are. Give it time, remain patient, and eventually the system will start to feel much smaller and manageable.

Permalink: http://pinderkent.phumblog.com/post/2009/10/analyzing_existing_databases_and_their_relationships_with_applications
Share:

"Utility" or "helper" classes are a sign of a language defect.

Posted on Tuesday, October 06, 2009 at 2:03 AM.

Chris Eargle recently wrote about so-called "utility" or "helper" classes. Within his article, he states that "There should never be a Utility class which is used as a general bucket. Every method in your system means something, it belongs somewhere." I can agree with this sentiment, nor can I necessarily argue in favor of using such classes. However, I do think that a tendency for developers to create such classes indicates that there is likely an inherent flaw with the programming language that they're using.

We most often see "utility" or "helper" classes arise when using languages like Java and C#. When first developed, these languages took an OO-or-nothing approach. This isn't surprising, especially in the case of Java. When it arose during the 1990s, the software development community as a whole was generally quite enthusiastic about object-oriented programming. So one notable feature it is missing is the traditional function.

Many OO purists will decry the functions and procedures that are native to many imperative languages. They claim there is no place for standalone functions within object-oriented languages and well-designed software. But it really just comes down to a typical clash of theory versus pragmatism. When developing real-world software, sometimes a plain old function is exactly the tool that we need.

So while languages like C++, Python and even OCaml allow for both functions and objects to be used, Java and C# unfortunately do not. Developers using languages like Java and C# have to resort to abstract classes with static methods, or similar workarounds. As Chris notes in his article, this isn't an ideal situation by any means.

Given that we, as a community, now have many more years of developing software using object-oriented languages and techniques, I think it's safe to say that our tools may need some minor modifications. Languages like Java and C# are missing an essential construct, and that construct is the function. Like any tool, functions can be misused. But as we've seen, their absence can result in other hackish designs that pose several problems of their own. So perhaps we will eventually see this deficiency addressed by adding functions to such languages, so we can use them when they do prove to be the best tool for getting the job done.

Permalink: http://pinderkent.phumblog.com/post/2009/10/utility_or_helper_classes_are_a_sign_of_a_language_defect
Share:

Don't architect software just for the sake of architecturing software.

Posted on Thursday, September 10, 2009 at 2:08 AM.

Today I read an article written by Davy Brion a few months back. It talks about his experiences interviewing several developers, and some of the techniques and concepts that some of the candidates were and weren't familiar with. Namely, he found Java developers to be more familiar with dependency injection, inversion of control, test-driven development, aspect-oriented programming, object-relational mapping, and so forth. While he seems to see such knowledge as a benefit, I'm not so certain it truly is.

The Java community is well-known for their adoption of design patterns and frameworks. One of the most popular frameworks is the Spring Framework, which offers an IoC container, an AOP framework, a data access framework, and so on. AspectJ is widely used for AOP. Many projects use the Hibernate ORM library. And JUnit was integral in bringing test-driven development to the mainstream.

However, various notable software developers have suggested that design patterns are merely missing language features. In many cases, this does appear to be the case. Some common features and techniques of functional programming languages, for instance, render many design patterns irrelevant.

Unfortunately, design patterns and various frameworks have become quite embedded within some portions of the wider software development community. The devotion that some developers have to the "cause" can best be described as a religious in nature. It is particularly strong within the Java community, and to a lesser extent (usually Java expats) within the .NET community.

For every case when I've seen a techniques like IoC or DI used sensibly, there are many, many more cases of systems I've dealt with where they've became huge obstacles and only served to unnecessarily complicate the software system. The use of ORM systems is another frequent problem area. The first major problem that arises is usually performance-related, with the object mapper sometimes generating some truly horrific database queries, or bringing back huge quantities of data that are never used. In short, what was meant to save time ends up wasting it.

We often see these problems arise with business software. Often times, this sort of software is relatively simplistic in implementation, with most of the complexity coming in the various and often inconsistent business rules that need to be supported. So what I think we've seen in many cases is software "architects" who feel the need, for whatever reason, to build horribly complex systems where they're not needed. Design patterns, along with the copious use of frameworks and over-generalizations, facilitate this sort of development.

Soon, what should be simple systems quickly explode in complexity. The quality of the software drops, even though there may be a huge number of automated unit tests. Usability becomes a nightmare. Simple maintenance tasks and bug fixes take far longer than they should, because the developers need to unravel unnecessary abstractions.

Some of the most successful business software systems I've dealt with have evolved over time, often with different parts being written in isolation from one another. The only "frameworks" used were developed in-house, tailored specifically to the problems at hand. Any "design patterns" used were those that were observed naturally occurring in the software system as it grew. Instead of trying to provide overly-abstract and highly-generalized "solutions", each part of these software systems performed a very specific role, and did that role well.

So if we feel the need to start explicitly using design patterns or frameworks for our software, maybe we should take those feelings as a warning alarm. Finding a more powerful and expressive programming language may be a good place to start. After that, the reasons for employing design patterns or frameworks should be considered very carefully. It often ends up being quicker and easier just to sit down and write the software, rather than planning and debating and designing it. This is especially true if such techniques are used merely to add complexity to what should be a simple system, just to make it more challenging for the developers.

Permalink: http://pinderkent.phumblog.com/post/2009/09/dont_architect_software_just_for_the_sake_of_architecturing_software
Share:

Project Coin is some badly-needed good news for the Java programming language.

Posted on Sunday, August 30, 2009 at 10:55 PM.

I recently saw an article about the accepted Project Coin changes that are planned to be included in JDK 7. This is some good news for the Java community. After a relatively long period of stagnation concerning the evolution of the Java language, and some fierce competition from C#, these are the sort of practical changes we need to see.

Most of these proposed changes aren't exactly revolutionary. Several of them have already been implemented for some time in C# and other .NET-based languages. They've proven to be effective there, and will hopefully bring the same benefits to Java.

The Automatic Resource Management proposal is a good example of a feature that is badly needed in Java. The using statement of C#, and the Using statement of VB.NET, have proven this concept. They make it safe and easy to ensure that certain non-memory resources are disposed of appropriately. This is exactly the sort of practical language-level change that Java needs.

The Strings in Switch proposal is another one that suggests a very useful change. Not being able to use a switch statement to select a case based on a string value has always been an annoyance to me.

The Improved Type Inference for Generic Instance Creation proposal may help making coding quicker, although I'm not convinced it's as beneficial as it sounds. Although it reduces what some may consider to be redundancy in code, most decent Java IDEs offer auto-completion support that helps prevent a programmer from actually typing out the parameterized types. And we do lose some detail within the object instantiation code, which otherwise is self-documenting in some sense. I think the benefits of this change will require some experimentation once an implementation is available.

Some of the other proposed changes, such as the addition of language support for JSR 292 and the collection-related changes don't seem as sensible to me. In the case of adding more support to the JVM and the Java language for supporting dynamically typed languages, I think this is a bad idea. The JVM itself is better suited to statically typed languages, and trying to hack on support for dynamically typed languages may just result in further bloat.

In the case of the collection-related changes, we are getting to the point where a major reworking of the collection classes is in order. We already have older classes like java.util.Hashtable and java.util.Vector, as well as the Java Collections Framework, and then all the changes that were made to both groups during the introduction of generics with Java 5. Trying to further build on the existing mess may just make the situation worse. But a clean up would be massive, and would have many repercussions on existing software. So there may be no easy answer here.

The acceptance of these proposals is a very good sign. They show the sort of activity and change needed to keep the Java programming language and platform relevant in the face of numerous other competing programming languages and platforms. I do hope that we get to see these implemented in JDK 7, as some of them do sound to be practical and badly needed by Java developers.

Permalink: http://pinderkent.phumblog.com/post/2009/08/project_coin_is_some_badlyneeded_good_news_for_the_java_programming_language
Share:
Feeds
  • RSS 2.0 Feed
  • Atom 2.0 Feed
Tags
Archives