Friday, May 09, 2008

Haskell - Academia goes Bowling

True to my promise, I've spent a little time looking into Haskell. I've read some intros on the web, and I have even gone as far as to download HUGS an interactive interpreter, and I have started to work through a tutorial. I'm still on the first chapter so it's still early days.

First impressions are that I like it. Haskell as you would expect is very mathematical, with terms like "currying", "list comprehensions" and "guards" to learn, so I had half made my mind up not to like it. Then I started to use HUGS and actually started writing some Haskell code. The code itself is quite readable, helped by prefix notation and type inferencing I think.

Keen to get to the point (and not wanting to have to learn a bunch of mathematical theories to do so), I sought out a real world example of a Haskell program. Thankfully I didn't have to look far. Ron Jefferies has produced a number of very good articles where he walks through his experiences coding up a Bowling Game program using TDD and a number of different languages. The Haskell example (produced by an academic), drew a lot of interest, especially since Ron spoke disparagingly about it.

The program uses pattern matching and recursion, avoiding loops. Ron's point was that the recursive implementation although succinct, said nothing about the "tenness" of a game of bowling. For those who don't know a game of Bowling always consists of ten frames. This "tenness" of the problem wasn't expressed anywhere in the solution. A number of academics jumped in defending recursion and offering recursive solutions of their own. Until one guy found out that there was actually a bug in most of the implementations presented.

I'll leave the reader to follow the debate, but what all these academics had missed, and Ron with his practical instincts had sensed is that the programmer is always the weak link. Any solution that doesn't fit with the way the programmer thinks about the problem will prove difficult for the programmer to verify in his own mind. Hence the missed bug, despite, many "clever eyes" over the code. Ron's summary is that Haskell forces you to think the way it thinks (mathematically) rather than allowing you to express things the way you think.

Gilad makes the same point about pure functional languages. In contrast, pure object orientated languages allow you to model the world the way it is. Haskell encourages you to create a stateless functional model, which by itself is useless for real world problems, but supposedly great for verification tools. Where your pure functional solution meets the real world, for things like user I/O, you must fall back to impure actions. Impure imperative behaviour can be isolated from the rest of your code using Monads. I don't yet fully understand Monads, but they appear to be a way of representing an underlying type (e.g an Integer) by wrapping it in a new type (called a Monad) that provides additional values that transmit information about side effects. So for example "Nothing" (NaN) is a valid value for a Maybe Monad, which can be used as a wrapper type for Integers. So functions that return Monads are able to communicate side effects to other calling functions (meaning that the side effect is no longer a "side effect" but a legitimate return value) . I will blog more about Monads once I fully understand them.

So where are all these great verification tools? With the exception of a type system there doesn't seem to be any built into the language itself. So you end up with a program that is hard for the programmer to check himself, and which can't be fully checked by the compiler. So what's the point?

As an academic exercise, Haskell is interesting and I guess it will float the boat of the mathematically inclined, as a practical tool though, it wouldn't be at the top of my list. I'm still going to play with it some more though, and I'll let you know if I change my mind.

Updated 11th May 2008
Corrected my description of Monads after feedback from the Haskell community. I found Daniels comment on Monads particularly useful. It prompted me to read further and improve my own understanding. I don't pretend that my description of Monads is complete, and I would refer a reader interested in a complete explanation to look here.

Monday, May 05, 2008

Newspeak - Educating the Pilots

In my Man versus Machine post I decided to play devils advocate and question Gilads motives. Having seen Gilads presentation on Newspeak, his motives are now clear to me, and as far as I understand his intent, I am in violent agreement. So why my initial discomfort?

Before I answer this I should say, that I have always agreed 100% with Gilads' point on static. On his blog I questioned whether the elimination of static, was just another way of reducing coupling, to which Gilad responded that yes this is true, but that coupling was a general term and that he preferred to be specific. I think this is the root of my discomfort. By being specific, I fear that a lot of normal programmers will miss the point.

Most programmers do not understand the importance of coupling and cohesion, and most do not understand that objects are just one approach to reducing coupling and increasing cohesion amongst abstractions. Functional programming is yet another approach. The underlying problem is the same, and as old as computer science itself. In fact the whole static thing is merely a failure in abstraction. We have no way of declaring a suitable cohesive abstraction, so we make things static and have them coupled to everything. Just like dodgy globals in C when you can't think of a better way.

So what Gilad has done in Newspeak is to provide a new way of defining loosely coupled, cohesive abstractions that are larger than a single class, removing the need for dodgy globals (static). This isn't reducing the programmers freedom, rather it is replacing a rather poor default mechanism, with a more precise way of defining exactly what you want. If you wanted to you could still create "dodgy globals" in Newspeak, but you would need to define a "global" abstraction first. There is no default "global" name space in Newspeak, which is as it should be.

So this is the issue, new and improved mechanisms are fine, as long as the pilots understand why? With OO programming, lots of programmers understand the "what", but very few understand the "why". This is how languages like Java can claim to be Object Orientated whilst only delivering on half the story. It is also why many (most?) Java programmers are happy programming in a procedural style in blissful ignorance.

With Smalltalk, it gave very little scope for misunderstanding, because there was only one way to do things. You were constrained to think in Objects. Newspeak has this same property, and by replacing static with a better mechanism it will force developers to think about higher level abstractions and name spaces, rather than defaulting to static.

I guess it isn't Gilads job, but there is a big education task needed if languages like Newspeak are to ever take off. Most people don't get the basic concepts behind OO and Smalltalk, whilst Gilad is ramping things up to the next level by borrowing from Self and Beta. My education is only partial. I have read about slots in Self and they make sense. I didn't think of them as a way of defining immutable functions though, and as a way of eliminating state. The elimination of state, similar to the elimination of static is yet another way of reducing coupling. If nothing changes, then any dependent abstraction can't be adversely effected by unsuspected side effects. This intuitively makes sense.

So Gilad prefers:

identifier = letter, (letter | digit) star. (Immutable)


identifier ::= letter, (letter | digit) star. (Mutable)

In both examples identifier is a slot. This means that identifier is a method, that answers the value of the given expression. There are no instance variables in Newspeak. In the first example identifier is immutable, in the second it is mutable. In this presentation at Lang.NET Gilad makes the point that if you remove the ::= operator from Newspeak, then Newspeak becomes a purely functional language with no state.

What are the implications of this? Well this is where I hit the bounds of my education. I think I'm going to need to take a look at a purely functional language like Haskell and get to grips with Nomads before I can comment further. Even with a vehicle as powerful as Newspeak, the limiting factor on success is still the pilot :)

Saturday, May 03, 2008

To the Victor the Spoils

Yardena kindly supplied this link to an interview with Erik Meijer, Gilad Bracha and Mads Torgersen, talking about Programming language Design and Evolution. The interview was interesting with Gilad confirming something that I have suspected for a while, which is that state is optional, and that most/all? problems can be decomposed into immutable functions. The problem with pure functional programming though is that it is really hard to do well, simply because we just don't think of the world this way. We think of the world as having state and we find it easy to model the world as stateful. Gilad uses the example of the interviewer as being a thing that is "stateful", rather than being a sequence of immutable things each one with no prior memory, only existing for a given moment in time.

Given that programming is hard enough as it is, relaxing the constraint of "no state" and introducing the idea of encapsulated state is a big leap forward I think, and represents a great, still untapped opportunity when compared to "anything goes" procedural programming. Contrary to the "OO" marketing hype over the last decade, the dominant programing paradigm today is still procedural in my view. The direct consequence of procedural based hybrid languages like C++, Java and C#, that only pay lip service to OO and functional ideas, whilst lacking the uniformity to be truly functional or Object Orientated.

It was interesting to hear John McCarthy say that the idea of encapsulated state, as introduced with Smalltalk has been the only significant step forward in programming language design in the last 50 years since Lisp. It was painful to watch the interview as the interviewer made claims for languages like C++. Even going as far as claiming that Mac OS X was written in C++ (although OS X is written in C and Objective-C), and that we still need C++ for all our "Systems" programming needs today. Gilad winced more than once. Which prompted the question: "Why is it that "beautiful" languages aren't more popular if they are so much better?". Gilad tried to answer this one, using a form of Alan Kays "prior context" argument, saying that programmers didn't like new ideas, and that change needed to be introduced incrementally.

Interestingly it was the C# guy Mads, who debunked this half truth, by saying that programmers were interested in new ideas, but that "new thinking" didn't pay the bills. Mads also admitted that a lot of the work that lead to the dominant static VM platforms of today was based on wrong thinking stemming from compiler based, code optimisation ideas, and it would have been much better to have started off with a dynamic platform and to have layered on top an optional type system, much like Gilad advocates. He puts this realisation down to hindsight, forgetting to mention that people like Alan Kay and Dan Ingalls were advocating just this at the time.

The biggest disagreement was over the future role of C++ with Gilad claiming that the language was as good as dead, and that they should have stopped extending it long ago. The others, including Erik, felt that it was still useful with advances in static analysis tools still being made today. It was painful for me watching advances in IDEs and Operating Systems being attributed to C++ and it's prodigies Java and C#, when it is clear to anyone with any grasp of history that we owe the modern Graphical, Windowing Personal Computer world to Smalltalk. You could see the pain on Gilads face as he sat through this mis-representation of history, mostly by the interviewer.

Mads made the point, that the successful languages today are all incremental changes to the thing that existed before them, namely C. And I guess this is the rub. C/C++, Java and C# are all successful. Smalltalk is not. To the victor the spoils, which means that the victor gets to write history.

This is fine with me as long as Smalltalk gets to write the future :)