Pinderkent

Pain and glory from the trenches of the IT world.

Functional programming JavaScript is a dead-end exercise.

Posted on Saturday, October 31, 2009 at 4:30 PM.

Yesterday a colleague forwarded me the link to Underscore.js. It's a JavaScript library that provides some functions commonly offered by functional programming language implementations.

Now, I can understand completely why JavaScript programmers would desire to use such techniques. They bring some very clear and powerful benefits, including shortened development time, fewer lines of code, greater flexibility, and improved readability. However, I do hope that JavaScript programmers using such a library don't come to think that they're actually doing functional programming.

One of the most significant areas where JavaScript fails with respect to functional programming is immutability. Current implementations have spotty support for constants, leading to various workarounds. So while it's possible to manually avoid state changes as much as is possible, it becomes difficult to do when performing browser-based JavaScript development. And it's almost always better to have the language implementation strictly enforce const-ness, rather than trying to have developers communicate this intent through all-caps variable names, for instance.

Many functional languages also offer very rich pattern matching functionality, which we just don't get with JavaScript. While some people have tried to implement pattern matching in JavaScript, it is nowhere near as clean or natural as pattern matching in Haskell or pattern matching in Erlang.

Many, but not all, functional programming languages also offer strict, static typing. There has been much debate about the pros and cons of the various typing techniques employed by various languages. In the end, however, experience shows that static typing results in higher-quality software, and static typing saves developer time. Unfortunately, JavaScript as a language, as well as its current widely-used implementations, don't lend themselves to strong, static typing.

It also doesn't help that JavaScript came mainly from the imperative and prototype-based OO world, and is only now trying to adopt features and techniques from the functional paradigm. It's often much cleaner to start with a purely functional language, and then add useful imperative features like for loops and references, as was done with Objective Caml. So the language and standard libraries have a functional feel to them, and naturally encourage the use of functional techniques, yet still allow the use of imperative features where they may prove to be the best option.

In many respects, I see trying to do functional programming in JavaScript much like doing object-oriented programming in C. While it can be done, to some extent, it never feels very natural because it lacks support that should be provided at the language level and by the implementations of said language. GObject is one of the most widely used C object systems, and as anyone who has written even a moderately sized GTK+-based system in C knows, it's not a very pleasant ordeal. Languages like Objective-C and C++ offer a much more developer-friendly experience.

So I see trying to add features and techniques from functional programming to JavaScript as generally being a pointless exercise. It may help in some cases, but ends up just masking the symptoms of a greater problem, namely that we want (and maybe even need) a true functional programming language available in all of the popular Web browsers. I've suggested Haskell in the past, but just about any functional language would be better than JavaScript.

Permalink: http://pinderkent.phumblog.com/post/2009/10/functional_programming_javascript_is_a_deadend_exercise
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:

Firefox 4.0 to bring a significant degree of UI inconsistency?

Posted on Thursday, September 24, 2009 at 2:15 AM.

Early last month I gave my opinion about some OpenOffice.org UI prototypes. In short, I wasn't too impressed. Unfortunately, we now see similarly flawed ideas coming out of the Mozilla Firefox camp with their "Windows Theme Revamp" project.

Take, for instance, this proposed design for the Firefox 4.0 UI. I do realize that it's a very early proposal, and will likely be subject to much change. However, it looks to me like it's heading in a very bad direction from the very start.

My main complain is the complete lack of consistency we're seeing. Functionality that was previous organized in a sensible and accessible manner within menus and toolbars is now spread out haphazardly throughout the top of the window. We have buttons to the left of the browser tabs, along with some to the right. Within the buttons to the right of the browser tabs, one button looks like a browser tab, while the other doesn't. We have various kinds of buttons around the URL bar, and some within the URL bar itself. Then there are what seem to be "Page" and "Tools" dropdown menus at the right-hand side. While likely similar in functionality, these dropdowns and buttons just aren't graphically consistent with one another.

Something that recent UI designers seem to forget these days is the benefit of textual labels. Traditional menus often do a good job of using text to explain the different actions that are available. These days, however, we get icons that probably were descriptive to the designer, but don't mean a damn thing to many of the users stuck using their design. At a glance, I have no idea what clicking on the hat-shaped thing next to the "+" tab in the tab bar would do.

Another uncertain aspect of the design is what clicking on the button to the left of the "Page" dropdown would do, the one with the picture of a book containing a star. I assume it involves bookmarks, but would that bookmark the current page, or would it just expand the dropdown? That isn't clear from just looking at the button. It also isn't clear what the relationship is between that button and the star within the URL bar is. Contrast this to the "Bookmarks" menu of Firefox 3.0, which by its label clearly indicates that it involves bookmarks, and has a very clear "Bookmark This Page" item at the very top.

I'm not sure what drives these UI designers to create these completely inconsistent and unfriendly user interfaces. It's almost as though they're trying too hard. They're making changes and breaking with tradition not to truly improve the user experience, but rather just to be "different". And that's not the way to go. It's good to be different when those differences bring some benefit. Unfortunately, we just don't see that with the differences proposed in the recent OpenOffice.org and Firefox 4.0 design proposals. As a user of both pieces of software, I hope that these design proposals don't become reality. They'd seriously hinder the usability of those applications.

Permalink: http://pinderkent.phumblog.com/post/2009/09/firefox_40_to_bring_a_significant_degree_of_ui_inconsistency
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:
Feeds
  • RSS 2.0 Feed
  • Atom 2.0 Feed
Tags
Archives