Archive for the Category programming

 
 

Erlang and OO

Erlang is a functional language, something that worries a long time OO programmer, especially when said programmer is starting a new project in it. My background is predominantly in OO languages that Alan Kay did not have in mind when he coined the phrase OO. I have used Smalltalk in an academic environment, never commercially.

OO is amongst the more subtle concepts used in programming. Besides silly interview questions involving OO modelling of living rooms and bathrooms, attempting to apply OO concepts in real life commercial programming is harder. However, once indoctrinated in the OO ways as currently practiced in the industry, a language like Erlang can look pretty weird, there are no classes, no objects in the Java sense. How does one ever model the nouns as objects and the verbs as methods ?

Look up OO in a textbook and you will find words like encapsulation, polymorphism and inheritance thrown about. Of these, encapsulation is probably the single greatest contribution OO has made to the discipline of thinking about organizing a software system. After having used Erlang over the last few months, Alan Kay is right (it does appear that Turing award winners usually are) message passing is what I need to achieve encapsulation. Far more important than the use of a narrowly defined construct like a class or even an object, the way Java or C++ define them.

Message passing implies encapsulation, the entities passing messages to each other do not have any knowledge of the each other’s innards. Their only contract is the message. Each side must understand the other side’s message or fail gracefully. It so happens that message passing is at the core of Erlang.

Once you break the shackles of narrow definitions of what an object is, turns out that a far more powerful abstraction of an object as a component emerges. A component constructed internally of many modules (files in the most general sense), exposing a contract, a contract composed entirely of messages. I can not only build these easily in Erlang, I can take the notion of encapsulation one step further.

Erlang comes with a built-in database called Mnesia. Mnesia is a standard library and can store any Erlang data structure. I can now encapsulate even the persistent state/representation of my component (complete with transactions). The component (or application as it is called in Erlang) is a completely independent entity with all it’s external dependencies and the services it offers specified in message oriented contracts.

Unfortunately, the contracts themselves cannot be formally specified in a language construct. Erlang is dynamically typed and so are the messages. In addition, many of the messages can be passed asynchronously, a recipient can fail “silently” if it cannot grok the message. Loose coupling can be good and bad, I prefer to leverage the good and work to avoid the bad. Erlang is the closest I have ever come to reusing software components which are not stateless lumps of code in the form of a library.

On Software Reuse

Software reuse is one of the most fascinating topics there is. A source of many myths and the basis of many project management blunders. I came across this brilliant article by Peter Naur. The article touches on so many points near and dear to my heart. From the industrial era project management techniques used in software to why teams consisting of smart programmers will frequently produce unusable junk and become miserable in the process. More on those topics in subsequent posts.

Programming as theory building is also a big reason a lot of software is not as reusable. The original programmer’s theory building exercise in the context of the problem domain has to be applicable to the problem you are solving. If you either do not understand that theory or even if you do not agree with that theory, it is far wiser to not reuse the code. The love/hate posts on Ruby On Rails I have seen on the net are a good example of this effect at work. Folks who agree with the original theory find the framework amazingly productive. Folks who either don’t get it or don’t agree with it, find it useless and will refuse to reuse the framework. Personalizing the theory behind Ruby On Rails, modifying it to suit one’s world view has resulted in so many other frameworks being created.

Another fascinating book that touches upon this topic of reuse (albeit in a slightly roundabout fashion) is The User Illusion. The book goes into a deep discussion on the nature of information, a discussion that then supports the author’s theory of the brain. One point that stuck me while reading the book relates to software reuse that Peter brings up in his article. Documentation does not really help in reusing software.

The amount of information that programmers discard before writing a line of code is actually far more important than the line of code that gets written. In fact, the complexity of a program is more a result of the amount of information discarded than the amount of information that gets encoded in the program text. No amount of documentation can make up for the information that is in the programmer’s head when the code was written. Without that information, the code is useless. Unless, you face the exact same problem and the code maps well into your context.

The exceptions are the gems, libraries that help you without imposing their theory on your code. Ironically, artifacts like EJBs which were built with reuse in mind, failed miserably at that task. The theory behind EJBs met with violent disagreement, theory building is fine, imposing that theory on everyone is and always will be risky business.

The next time you are wondering why that other programmer’s code looks like crap, it could be because the code is truly crap or maybe you just do not understand the underlying theory of the program or maybe you sub-consciously do not agree with it. It might be that the original programmer discarded way too much information that is relevant to you or you have clue no why they discarded the information. In all these cases, the best course of action is to just re-write the code. Now, if you find yourself wanting to re-write something as complex as Windows, reusing Mac OS X or Linux might be easier.

jQuery

As a server side programmer, I am petrified at the thought of building a Web UI. Not that I have not tried to build a Web UI in the past, but the experiences usually left scars. Experiences that had me scampering back to the coziness of the server side. After all, the server side is rough enough, I thought. There are issues with persistence, state, transactions, scalability, fault tolerance. None of them even remotely require any artistic skills. Well, maybe API design is an art form, but nothing a good JavaDoc cannot fix.

Each time I ran away from front end development, I swore I would come back to it. For the last few months, I decided to take a more careful approach. First, I scouted around to find a good book on design. Based on Amazon reviews, I bought Transcending CSS. It is a pretty interesting book, especially for a technical person. Light on technical details of CSS and heavy on design and different ways to think about design.

Good stuff, but the problem is that most of the JavaScript frameworks out there set out to conquer the world. I did not find a framework that fits in nicely with the HTML/CSS philosophy, until I came upon jQuery. This is an amazing framework. It makes thinking about the Web UI so much easier. Like I mentioned in a previous post, it is very important for a programming language or a framework to surface a few important concepts. These concepts should then be repeated over and over to solve problems for a particular domain. It is very difficult to come up with these central concepts, but very easy for users to understand and use a framework. jQuery does this very effectively.

Now, on to building something meaningful with jQuery….

Merge Sort

There are certain incidents in your life that stick around in your brain for a long time. One such incident for me was a job interview a few years ago (at an unnamed company) where I crashed and burned quite spectacularly in the space of 2 hours. It was so bad that mid way through the first interview, I no longer even wanted the job, I just wanted to cut my losses and go back home. Needless to say, the post-mortem analysis of that incident has been going on for a few years. Over the years, the incident has lost a lot of the emotional rawness. To me, it has turned into an analysis of how programming languages shape the way you think about solving problems.

On the day of the interview, I was functioning on an hour’s sleep from the previous night, it did not help at all when the first question I was asked was to write the Merge Sort algorithm on a whiteboard. Not a very difficult question. The classic divide and conquer algorithm I said aloud, break the unsorted list into smaller lists, sort the smaller lists and merge them back together. The devil as always is in the details. In this case, it was in the details of how I translated that sentence in English into code on a whiteboard. No IDE to tell you how badly the syntax is screwed up. No REPL environments to test out a few things. No writing the unit test first and going back and refining the algorithm over successive attempts. A whiteboard is the most stark programming environment in the world, especially when the code you write is supposed to meet some standards of rigor.

As always, I was granted the luxury of writing the algorithm in any programming language. Over the years, in analyzing the incident, I have realized that this choice is not a luxury. In fact, the worst thing you can do is pick the wrong programming language to think in. Even simple things like the representation and manipulation of a list get in the way of how you solve the problem. The language, the libraries, the idioms commonly used, all shape the way you approach any problem.

From that point, any new language I try out has to go through my Merge Sort test. I had no clear favorite, until I tried it in Erlang. It was a like a walk in the park with Erlang (I admit I did compile and run it a couple of times, but in my defense I am still learning Erlang and had syntax errors). Here is the merge routine I came up with on the first attempt.


merge(L1, []) -> L1;
merge([], L2) -> L2;
merge([H1|R1], [H2|R2]) when H1 =< H2 -> [H1] ++ merge(R1, [H2] ++ R2);
merge([H1|R1], [H2|R2]) when H1 > H2 -> [H2] ++ merge([H1] ++ R1, R2).

Pattern matching, recursion and literal syntax to deal with lists just seem to lend themselves to these kinds of problems.
Den ganzen Beitrag lesen…

Why did Java succeed ?

It seems like the number of pronouncements about the “next java” is on the rise. Folks are boldly announcing their pick, Ruby, Python, Erlang, JavaScript are all apparently in the running. I have seen folks also back Haskell. But, the one question that has bothered me for a while is I don’t understand why Java succeeded in the first place. Shouldn’t the successor for Java then follow the same/similar recipe or have the times changed and the old rules don’t apply.

I have heard so many reasons for Java’s success. Reasons including

  • It was a shrewd marketing campaign, folks just assumed that Java had something to do with the internet. Applets were a nice selling point, even though Java’s eventual success was on the server.
  • Java was a better C++ (at the time).
  • Write Once Run Anywhere cracked open the platform portability problem. Certainly was better than using #ifdef’s all over the place.
  • Java took Smalltalk and made the syntax more palatable (although Alan Kay makes it a point in some of his keynotes that Java and C++ are not what he had in mind when he coined the term OOP).
  • From the Paul Graham school of thought – Java is a mediocre language for mediocre programmers. It thus become a “safe” option for IT middle management, because in theory Java programmers were replaceable. After a point, there were so many of them (us), it minimizes the risk associated with programmers leaving a project.
  • J2EE is a standard and provided an API for for anything an “enterprise” would want to do. Being a standard meant that vendors were replaceable, once again working into the IT middle management’s risk averse mindset.
  • This reason is the one I like best – J2EE application servers provided IT operations staff with a standard deployment environment. One they could provision, deploy, maintain and operate without having to worry about the language du jour.
  • Eclipse is a great tools platform, made Java development a snap.

So, which of these reasons is it ? Or is it a combination of some or all of them ? I am probably missing some reasons, but, if Erlang is to become the next Java, which reason will it go after. I like Erlang, I think message passing concurrency, a system built to handle failures are fantastic design principles. However, is technology enough of a forcing function ? Businesses only react when their competition is able to gain an edge through technology or when their business goes away because of technology.

Will the “next Java” replace Java in an existing customer set or create a whole new customer set ? I have a sneaking suspicion that existing customer sets will not replace Java, there is way too much invested in the language, the libraries, the VM and in J2EE application servers. The change has to come from a new customer set.

Language Envy

I have been trying to port Joe Gregorio’s Robaccia framework into Groovy in my spare time. Robaccia is written in Python and since Groovy was
inspired by Python (and Ruby), I wanted to see how easily Python code can be translated into Groovy. Plus, I now realize there is no better way to learn
new languages than trying to translate relatively non-trivial pieces of code from one to the other.

In general, I have been able to translate Robaccia code into Groovy without line creep. A method in Python 5 lines long translates to a Groovy method 5 lines long. There is this one situation I ran into, where I have not been able to find a good translation. Here is the line(s) of code :


parts = ["a=10"]
params = dict([tuple([s.strip() for s in param.split("=")])\
for param in parts ])

Run this and you will find that given a list of strings, the string “a=10″ gets munged into a dictionary with the key “a” and a value of “10″. As an aside, try this in Java and let me know how many lines it took. Seamless transitions between data structures are a very useful feature in a programming language.

This is the best I could come with in Groovy. If anyone has a better way, please let me know. For some reason, I think the Python code looks cooler.


parts = ["a=10"]
map = new HashMap()
parts.each { List list = it.split("="); map.put(list[0].trim(), list.size > 1 ? list[1].trim() : null)}

Why does this work in Groovy ?


test = null
test.println(test)

This prints out null. In fact, you can even do this :


null.println("Hello")

Component Composition

Will Java programmers ever stop trying to build a better component composition model ? I am tired of seeing folks do this all the time and then shouting from the rooftops that they have nailed the problem. The usual component composition pitch goes like this :

Welcome to Acme component composition, the only tool you need for software nirvana. Reuse is guaranteed, just build Component A and Component B using my new formula. You can test Component A and Component B independently, because I have figured out a clever trick to fool Java’s static type system (Disclaimer – you will have to use my Classloader and my bag of reflection tricks). You can swap out Component B for Component C any time you want – by editing my new spiffy XML file (the next version will give you properties files, YAML files in all languages). This way any deployer (who are generally assumed to be idiots) can switch to using new components. The reason I give you this impressive framework, is because I don’t know what my framework will be used for. But, if I give you the tools to make my framework whatever you want, you can build anything you want with it.

Seriously, just give me libraries and a dynamic language, I don’t want to solve unsolvable problems.


-->