Wednesday, November 29, 2006

Broken LEGO (myth)

My wife found a broken LEGO brick in our son's room this morning. My kids apparently managed to break a LEGO brick in half, and with it the associated myth (well, at least a belief I held) that the damned things are in fact unbreakable in a domestic environment.

Absolutely coincidentally, several hours later today, Slashdot's cover page is graced with an entry "How They Make LEGO Bricks" that actually links to a BusinesWeek article "The making of a... LEGO".

(Very Useless Fact of the Day: I keep my laptop (when it sits on my desk connected to an external display, keyboard, and mouse) sitting on 4 LEGO Duplo bricks I stole from kids to provide better airflow to it.)

Tuesday, November 14, 2006

Rhino relicensed under MPL/GPL

Mozilla Foundation decided to relicense the Rhino JavaScript interpreter to use the MPL/GPL dual-licensing instead of NPL/GPL dual licensing. The reason is primarily that Apache Software Foundation published a 3rd-party licensing policy recently, and NPL was listed as "Excluded Licenses" in it, therefore prohibiting several Apache projects (Coccon, Batik) to redistribute Rhino in the future. MPL, on the other hand falls into Apache's "Binary Licenses Only" group, which'll allow those projects to bundle Rhino binaries with their distributions. Also, Mozilla's lawyers concluded that Mozilla has the legal power to change the licensing from NPL/GPL to MPL/GPL easily, so it looks like the best solution for the time being.

I plan to release the latest stable branch as Rhino 1.6R5 soon. The binaries will be completely identical to 1.6R4, the only difference being that they'll be recompiled from relicensed source, thus the line number tables in classfiles will reflect the difference in length of the boilerplate license code on top of each source file. Apache folks can then include Rhino 1.6R5 instead of Rhino 1.6R4 binaries in their project distributions, or if they're impatient they can compile it themselves from the "Rhino1_6R3_PATCH" branch in the CVS. (Of course, CVS HEAD is now MPL as well.)

1 << 5

Today's the day when my life duration has doubled for the fifth time, relative to the last such event, (counting my first birthday as the 0th). (With bit of a luck, I'm in for yet another such event down the road.)

For those less math nerd folks out there: I turned 32 today.

I don't usually care too much about arbitrary milestones in the flow of time, my own birthday not really being an exception, yet last night I couldn't help thinking about it (not being able to fall asleep for about two hours after going to bed - I turned from good sleeper to quite erratic sleeper lately). When trying to assess what happened since the last birthday, it always seems life only brings gradual changes (the previous year carries a rather big exception, hopefully I'll be able to write about it sometime soon). However, on such a round number occasion (both %100000 and 0x20), it made me wonder about everything that happened or changed since I was half this age.

And I have to say, it's a hell of a lots of things. My 16-year old self was a quite blissfully unaware gymnasium student in Croatia whose biggest problem was how to skip history classes to go hack on the Apple-II machines in the school computer lab, as well as to write games and fractal generators for Commodore 64 or later for Atari ST. And girls. Were a problem too, that is.

Shortly thereafter, I endured one war and one exodus that completely uprooted me and my family, had to settle in a new country. A bit later found true love, then attended university, and over the passing years grew into several different roles, including that of a husband (for more than eight years now), of a father (for more than seven years now when my son Ákos was born, redoubled the role two years later with Zsuzsi), and of a (well, what at least feels like) reasonably respected IT industry professional. I'd really like to elaborate a bit on all of this here and now, but there are two big driving forces against it: (a) not wanting to bore you to death, and (b) the aforementioned three roles unfortunately don't leave me with much time at present to write sentimental weblog entries about myself.

All in all, the previous 16 years were probably the most dynamic period of my life, past and future. Regardless, I'm looking forward to the next 32 years; stay tuned for the "1 << 6"

Wednesday, November 08, 2006

Java Notes

When searching few days ago, Google accidentally turned up Java Notes, created by one Fred Swartz (who apparently teaches at University of Maryland Unversity College). Poked around it a bit, and I must say I was pretty impressed by the quality of those examples I looked at; it indeed looks like a nice teaching material for beginning Java programmers, one Mr. Swartz put into many hours to assemble. I mean, just look at the exhaustive discussion of the algorithm for finding the maximum element of an array!

What's an especially nice additional touch is that the author indeed donated all of this to public:

Many textbooks show useful code examples, but ironically copyright them so you can't legally use them! All Java code examples in Java Notes and Java Basics are placed in the public domain.

Wednesday, October 11, 2006

Of empty bags, or how to coerce a null

Let's say you implement a language (we'll call it "higher layer") atop of an existing language (we'll call it "lower layer"). Examples I work on are Rhino (JavaScript atop of Java) and FreeMarker (text generator template language atop of Java). Imagine that you wish to expose the lower layer objects within the higher layer. What do you do? Well, you implement a wrapper. Your wrapper object will then do its best to disguise the wrapped object as being native to the higher layer (you can use the terms "marshal" or "coerce" instead of "wrap" if you want to appear more serious when talking about it).

Now, this'd be okay if it weren't for the fact that sooner or later there'll inevitably be a situation where there's a semantic ambiguity between the languages, where you can design certain behaviour in more than one way. And inevitably, whichever way it is designed, you'll have users that'd prefer it be designed some other way.

One of such issues is how to coerce a lower layer representation of a null (or nil, or nothing, etc.). Suprisingly, coercing a null the right way is not actually ambiguous at all, yet folks from time to time request it to be done differently, or outright declare the current behaviour to be a bug.

Freshest example is here. Basically, this user would like it if in Rhino, the JavaScript == operator would find equal a null and a wrapper that wraps null. Basically, if x implements the Wrapper interface and ((Wrapper)x).unwrap() == null, he'd like it if ScriptRuntime.eq(x, null) == true.

Now, this'd be utterly problematic. This reminds me of one of my first set theory classes where the teacher stressed that an empty set is not equal to a single-element set containing the empty set (if it was, it would make it impossible to construct the set of natural numbers axiomatically starting from set theory, but I digress). An empty bag is not equal to a bag containing an empty bag, and null is not equal to a wrapper disguising null. (However, any two wrappers that both wrap a null could be equal if the higher-layer language considers null == null to be true for its own null representation, provided it has one at all.)

Although you'd probably be better off if when your custom wrapping code is faced with the request to wrap a lower-layer null, it'd just return a representation of the higher-layer null (if there is one - in Rhino at least JS null is represented by Java null, so custom wrappers can have it quite easily) instead of creating a wrapper object for it. That's the most acceptable way to coerce a null.

Friday, September 29, 2006

Gradual typing

Via Lamda the Ultimate: Gradual typing as the ultimate unification of static and dynamic typing. The basic idea is that the type system does not enforce you to specify types, but when type information is present, it is used for static checking. This way, you can reinforce the structure of your program by using static types, but you need not be hindered by it when you need more flexibility. The paper's references are worth reading themselves, especially (a two year old, but just now discovered by me) "Static Typing Where Possible, Dynamic Typing When Needed: The End of the Cold War Between Programming Languages" by Erik Meijer and Peter Drayton. I was already quite delighted by the abilities of type inference in Scala as compared to Java, but the possibilities outlined in these papers are such that I just can't wait for them to get adopted by other mainstream programming languages on managed platforms.

I'm all for contracts in programming - the more intentions you can express in the source code in a form that the compiler can understand and enforce, the more errors you have caught early. Static typing is just a subset of possible contracts you can enforce on your code. Also, contracts allow you to write much terser code where eventual ambiguities arising from omitting declarations can be resolved by applying contractual expectations in effect. However, the critical point here is "can" - it gives you the most flexibility when you "can use it" to express the intents but you aren't forced into a "must use it" as you are with lots of today's statically typed languages. To me, an ideal language and compiler would be one that:


  • Has broad expressive power for programmer intentions in forms of type declarations and contracts, but

  • doesn't force you into using them, however

  • enforces them when they're used, and ultimately

  • can clearly indicate which pieces of code are compiled as dynamically typed so I can periodically scan the code for unwanted type weakness.



Of all this, it'd already be a big improvement if at least normal type inference got into Java in the foreseeable future, just as it got into newest C#. In the meantime, there's always Scala for more pleasant JVM work. Yes, I know I talk about Scala too much lately.

Wednesday, September 20, 2006

Manifold Destiny

The New Yorker published a rather fascinting (and rather long) piece about a month ago about the people involved in the proof of the Poincaré conjecture (guess we can start getting used to it being called a theorem now). I started reading it as I hoped to discover more about Grigori Perelman, and the article indeed provides plenty of information about him, but also provides insight into the politics of the mathematical communities, and much more.

Here's the article authors' rather amusing account of the quite unconventional way they managed to meet with Perelman:


Before we arrived in St. Petersburg, on June 23rd, we had sent several messages to his e-mail address at the Steklov Institute, hoping to arrange a meeting, but he had not replied. We took a taxi to his apartment building and, reluctant to intrude on his privacy, left a book—a collection of John Nash’s papers—in his mailbox, along with a card saying that we would be sitting on a bench in a nearby playground the following afternoon. The next day, after Perelman failed to appear, we left a box of pearl tea and a note describing some of the questions we hoped to discuss with him. We repeated this ritual a third time. Finally, believing that Perelman was out of town, we pressed the buzzer for his apartment, hoping at least to speak with his mother. A woman answered and let us inside. Perelman met us in the dimly lit hallway of the apartment. It turned out that he had not checked his Steklov e-mail address for months, and had not looked in his mailbox all week. He had no idea who we were.

Friday, September 08, 2006

The 9/11 Report: A Graphic Adaptation

I have a copy of a book whose full title is "The 9/11 Commission Report: Final Report of the National Commission on Terrorist Attacks Upon the United States, Authorized Edition" on my bookshelf - I bought it a year ago in a bookstore at the JFK airport. It's a hefty 567-page tome and a rather dense reading (I'll admit that by now, I managed to read just a small part of it). Anyway, it's definitely not something I'd expect to see in a graphic adaptation, yet that's exactly what you'll find over at the Slate magazine. (BTW, for whatever reason it opens at Chapter 13. If you want to go to the first page, just click the orange "9/11" at the top left of the page.). It turns out you can buy it in print, too.

UPDATE: fixed the link to Slate - sorry about the glitch...

JAOO

Just a heads up that I'll be attending JAOO again this year. If you too are around and feel like meeting me, look for a guy that looks something like this, only with his hair given 4 more months to grow by October :-)

Tuesday, September 05, 2006

Server sent events

Came across a post on Opera Web Applications Team blog saying Opera will soon support Server Sent Events. Basically, you embed a special HTML element into your document containing an event source URL, and then the browser opens a persistent HTTP connection to it and have the server stream events to it over it and interpret the events as commands for transforming the DOM tree of the document.

This looks like the formalization of an early rudimentary form of AJAX (not called that then, of course) that I stumbled across about four years ago, where they had a page with two frames, one for the content, and another 0-pixel wide one where the server kept streaming an endless HTML page with JavaScript commands that the browser executed in chunks as it received them and thus manipulated the DOM tree of the page in the other frame.

It sounds like a nice thing, with only a single worrisome bit - it doesn't scale. It'll definitely be nice for intranet applications, but I just can't imagine a web application on the Internet based on this technology that can serve several thousands of clients, because that means thousands of open persistent HTTP connections at once. It may work if you code your server using non-blocking IO instead of the traditional one-thread-per-connection model, but I have the feeling sooner or later you'll hit a resource limit, i.e. run out of file descriptors as the number of persistent connections goes up. Right, this can be a concern with ordinary HTTP as well, but at least there connections are usually short and not kept open while idle. On the (yet an)other hand, it might still beat the current AJAX technique of periodically polling the server for events - depends on the frequency of polls, I guess.

Anyway - seems like yet another Web 2.0 feature to keep an eye on.

Friday, September 01, 2006

Life's important questions, 5 year old's edition

My kids like to ask me questions after I've tucked them in for the night - a good technique to delay the sleeping a bit longer. They know I love explaining the world to them, so it's a quite sure thing. Last evening, my 5 year old daughter suddenly asked "Dad, how is plastic made?". I had to give it a bit of a thought and then proceeded to try to explain her the process as I could, hoping I could tell it adapted to the level of a bright, but nevertheless five-year old kid.

Halfway through my exposition, she impatiently interrupts me with "Okay, okay, but how does it end up being blue and shaped as a pony?". Ah, so that's the actual burningly important question :-)

Tuesday, August 29, 2006

Japanese Algorithm Dance

Japanese Algorithm Dance (compiled from various episodes of Japanese children TV-show "Pitagorean Switch").

Even if you think you don't get it, don't stop watching until you have seen the part with ninjas.

(Via Little Gamers)

Thursday, August 17, 2006

Scala might be Java platform's new hope

Last saturday was rainy, and I spent a big part of saturday's afternoon reading "Scala by Example". I was, and am still, rather blown away.

As many other fellow professionals working with Java on a daily basis and having it pay our bills, I'm somewhat dissatisfied with the language, especially seeing the innovation going on in the C# language. C# acquired lots of interesting traits in its 2.0 and upcoming 3.0 release, and let me list some of them here without striving for completeness:


  • Anonymous functions, and even

  • lambda expressions

  • type inference, so instead of "String x = new String()" you can write "var x = new String()"

  • related to type inference, it now has anonymous types, which is a very nice feature for i.e. adding strong typing to a results of a SQL projection

  • generator functions, using the "yield" keyword. This allows certain quite useful forms of continuation-passing programming techniques incl. coroutines without it looking much like continuation passing at all, much like in Python.



And I could go on. Now, there's little hope for Java to achieve this, however there's Scala - a language built on top of JVM, its compiler producing Java .class files that interface seamlessly with any other Java code, and supports a bunch of the above features.

One of quite mind-blowing aspects of the language is its support of generic types. You can explicitly require nonvariance, covariance or contravariance for type parameters and the generic types will act accordingly. I.e. a Stack[String] by default is not a subclass of Stack[AnyRef] by virtue of String being a subclass of AnyRef, but it can be, if Stack[T] is defined to be covariant in the T type parameter. Scala even has a type named "Nothing" that is the bottom element of the subclass relation lattice, a subtype of all types. You can declare the empty stack to be of type "Stack[Nothing]", and have it be compatible with any other stack type without annoying compiler warnings. Contrast this with Collections.EMPTY_SET in JDK 1.5.

There's some real innovation going on in the area of libraries in the C# world. Things that come to mind are LINQ and CCR. Both of them heavily leverage the new syntactic aspects of C#. It occurred to me that if one were to "port" these libraries to JVM, one should probably do it in Scala, and not in Java. In Java, you'd end up with lots of explicit interface declarations and anonymous inner classes, that have quite a syntactic baggage, i.e. compare the verbosity of

filter(x => x * x)

with


filter(new LambdaExpression()
public float calculate(float x) {
return x * x;
}));


Rather straightforward, isn't it? Also, I realized that Scala's for-comprehensions basically already implement the basic LINQ. You can write expressions like:

for (val p <- persons; p.age > 20) yield p.name

To obtain a list of names of persons older than 20 years. LINQ does the same basically for in-memory objects. In Scala, a for comprehension works on any kind of a collection that appropriately implements the "map", "flatMap", and "filter" methods. Built-in lists, streams, and arrays all do, which is quite a good start. Unfortunately, this is something that can't be easily extended to relational data sources, at least not until Scala allows the argument to "filter" to take a parsed abstract syntactic tree of a lambda expression instead of a function object with the compiled bytecode for the said expression. C# people had to resort to a trick here with their DLINQ implementation - they now have the C# compiler emit a representation of the AST for a lambda expression if the type of the variable it is assigned to is a special "System.Expressions.Expression" type. That way, the DLINQ can analyze the lambda expression and convert it into a SQL query. As I said, Scala doesn't have this feature - yet. Being free of standardization lock-in and of legacy baggage, it could soon gain this feature as well.

As I said, if you work with Java, consider whether Scala could fit your next project. You needn't give up any of your Java infrastructure and libraries, as Scala compiles to bytecode, and you gain the expressivity and productivity that a fully featured functional language plus a big pile of accompanying syntactic sugar can give you.

Friday, August 11, 2006

Jailhouse innovation

Via Bruce Schneier's blog:

A collection of 11 prison shivs confiscated over 20 years ago in New Jersey.

Think about these, and the adverse conditions they were made under, the next time you see someone's pocket knife being taken away from them at airport security. We can't keep weapons out of prisons; we can't possibly expect to keep them out of airports.


Not entirely unrelated, Prisoners' Inventions, an exhibition of reproductions of objects created by prisoners from the available materials by an incarcerated artist. From paper mache dice to a tatoo gun.

Wednesday, August 09, 2006

Good concurrency article

Here's a good article on code concurrency on MSDN, written by Joe Duffy, a concurrency-obsessed Microsoftie whose (mostly concurrency-on-Win32 related) blog where I found the reference is otherwise here.

While the article talks about CLR when it brings up examples, the discussion is actually generic enough to be of interest even if you write code that targets the JVM. It covers many aspects and pitfalls that you need to keep in mind when developing parallel(izable) applications. You even get few theoretical equations you can use to calculate the optimal number of threads to use as well as the maximum achievable performance increase through parallelization. (Assuming you can figure out the values of the variables in those equations for your system... ahem...) At the bottom of the page, there's a box named "Recommended Reading" which links to three more articles that look like they're also worth giving a shot.

Also on MSDN, Jeffrey Richter (the guy who wrote "Advanced Windows", a book that taught me Windows programming back in 1995 (together with Petzold's) and was the first technical book I came across that was also full of good jokes) writes about the Concurrency and Coordination Runtime, a CLR library that promises to make writing concurrent code much easier than it is "the manual way" (read: managing your threads and synchronization on your own; y'know, that which used to be the only way). What's interesting is that he also points out how concurrency is especially of importance in robotics applications, where there is really a great deal of processing going in parallel - all data coming from different sensors, multiple motoric instructions, etc. I also learned that Microsoft apparently has a product called "Microsoft Robotics Studio" targetted for writing software for robots. Hm...

Sunday, July 30, 2006

Blown up car, cornfield, midnight

Here's what I was doing last midnight.

I'm standing beside my car in a middle of a dirt road that's cutting through a cornfield. I don't dare go further as my car has sporty, quite low-suspension and I'm afraid one of the holes in the bumpy dirt track ahead of me will prove too deep for it. My wife is trying to figure out how could I safely turn the car back. What are we doing in the middle of the nowhere at this hour anyway? Why aren't we at least on some regular road, if not safely tucked away in bed?

The problem is, few minutes earlier we came across a wreck of a blown-up car blocking the normal road, lying on its roof (or what remained of it), surrounded by one fire truck, several police cars, and a slew of firemen and policemen, impossible to drive past it. On advice of one of the by-standing villagers, we tried to get around it on a "back road", which turned out to be the aforementioned dirt track through a corn field. When it proved unpassable for my Mazda, we scrambled back to the road, to wait for the firemen to eventually clean up the wreck from the road.

My biggest problem though is that when we came upon this roadblock, we were only ten short kilometers away from our beds at my parents' house, after I spent my last thirteen hours behind the wheel (only stopping for gas), covering nine hundred kilometers. I'm exhausted beyond belief. I can't actually believe this is happening to me.

(Not too relevant to the story: the car blew up because its fuel tank was leaky. The kid driving it, his driving license only four days old, miraculously survived it with only burns to his legs, as bystanders told me.)

I was royally pissed off after all other things that happened to us earlier that day leading up to this. You might have noticed it took me thirteen hours to cover nine hundred kilometers. It's a very bad average speed, considering I drove most of it on highways. Short explanation for it is two words.

Italian highways.

We spent our vacation this year near Rimini in Italy. The people were kind, the sea warm, the food great. Everything was perfect, except for italian highways. We run into a congestion because of an accident, both ways. Took us more than an hour each time to get out of it, driving in lockstep. You'd say it's no fault of the highway system itself - accidents happen. That's true. However, there's also one 100% predictable, huge congestion that's coded into the system - the tollbooths near Venice. The idea is that you pay as you leave the section of the highway built and operated by one particular company. They do however have a throughput problem, which manifests itself in a nine kilometers long queue of cars before it. Yes, nine kilometers. In rows of three. Unfortunately, their business model completely defeats the function of the highway. The function, to me at least, being efficient road transportation. It took us an hour and a half of driving in lockstep from reaching the end of the queue to clearing the tollbooth. Together with the one-hour accident-caused congestion between Rimini and Bologna, this resulted in four and a half hours to cover the first two hundred and seventy kilometers of our trip back home. On a highway. Do the math.

By the time we reached the tollbooth, both me and my wife (and our seven-year old son, too) were red with fury. The poor clerk at the booth got on its receiving end. It isn't his fault, but he was the closest human representative of the company that operated the highway, the company we by that time hated fiercely for operating a highway where you stand in a queue by design with thousands of other cars for an hour and a half, or more if you're unlucky enough to run into an accident. And then you pay fourteen euros for the privilege. We told the clerk how this isn't a highway, this is an inhumane joke, a horror, not something belonging to western civilization, how even Balkans are better, and we know because we were to Balkans earlier. He had a look telling us he hears this kind of testimony of customer satisfaction regularly.

So, I won't make any service to that highway, as it didn't really do me any service either: I'm telling anyone reading this that if you can avoid using higways going through Venice-Mestre tollbooths, avoid them. You can't go any worse on secondary roads - they're free, and you'll probably have a far, and I mean far-far better average speed and fuel economy. You certainly won't get two and a half hours behind your travel schedule. And this isn't an isolated event - I drove on that highway five years ago, and it was the very same experience back then as well.

Those +150 minutes then led to me standing with my car in the middle of the night in a cornfield, exhausted, ten kilometers away from a bed I should've instead been in at that time.

Update: To be completely honest, we did acquire some more delay after we left Italy, while driving through Slovenia, due to one case of bad signage (in Maribor), a blindingly pouring rain, one case of detour (near Murska Sobota), and a general disagreement between our road atlas and the physical reality regarding existence of certain roads. The exploded car wreck and the cornfield were really just the finishing touches in that day's demonstration of God's sense of humour.

Tuesday, July 18, 2006

A grab-bag of two-week memories

This is really just a quick grab-bag about various things that happened with me in the last two weeks.

Been to Croatia a week ago. Went on workdays - thursday and friday (and saturday). Kids were at wife's relatives, wife was working on these days, so my absence had minimal impact on family :-) It also had minimal impact on work, as I took my laptop with me and stayed at a friend who could provide me with internet connection, so I worked during the day and visited friends in evenings. I even called into the work-related conference calls during these days, although calling US numbers from a Hungarian cellphone while romaing in Croatia earned me a call from T-Mobile customer relations next monday asking whether there's a chance my phone was used unauthorized as they registered calls worth 300$ in a single day on it. Whoops, here comes my record phone bill. Anyway, it was really great to visit childhood friends and go for swimming at sunset in the same lake I swam in every day of every summer of my childhood. This was my very first return to that lake in fifteen years - since I had to leave the region because of the then-war. Yes, I'm being sentimental. A bit.

I desacrated my MacBook Pro by installing Windows XP on a small 8GB partition on it few days ago. I guess I just couldn't watch my copy of Far Cry gather dust on the shelf anymore knowing that I didn't complete the game before I switched to the Mac. I have to report that all is peachy with it. It even takes advantage of the two CPUs reasonably well (i.e. it runs with over 50% CPU utilization). After few hours of installing XP, Far Cry, and all patches for Far Cry, I even got a chance to play with it for about an hour :-) Far Cry BTW is one hidden gem of a first-person shooter - it brought the same graphical excellence and gameplay experience to the market as Half-Life 2 did, only Far Cry hit the market about 9 months earlier than Half-Life 2 did. It is somewhat underappreciated compared to HL 2 though, unfortunately.

Been re-watching Futurama Season 1 lately as work-unwinding. It stuns me as a bit boring and predictable - well, maybe because I already saw it once, but still. I don't have the same feeling when rewatching The Simpsons. Pausing it a lot though to spot various not uncommon easter eggs that are visible for only a second or so. Speaking of work-unwinding, I'm trying to cram in at least half an hour of cycling or running lately in the evenings. I noticed that a bit of a physical activity after an all-day sitting in front of a computer really refreshes me for an evening of Uno with kids :-)

Been listening to "Kite" and "Sometimes You Can't Make It On Your Own" much lately. Not going to explain it - if you're a close friend, you understand anyway.

Oh, and here's your movie recommendation: make sure you watch "Hoodwinked!". It's an indie CG animation feature "loosely based" on Red Riding Hood. Better said, it turns it a bit upside down and is absolutely hilarious. It being indie shows at the CG models and animation, which are few years behind the big-budget Holywood state-of-the-art, but believe me it wouldn't diminish the experience at all - the lovable and zany characters, the twisty story and the jokes, provide for over an hour of fully immersive fun. My wife generally doesn't like animation, but even she said this was a cool one.

On professional side, few things are moving. Just asked Norris Boyd today to pack up the current Rhino CVS HEAD and release it as Rhino 1.6R3 - last release was over nine months ago, so it's about time we give people a bunch of bugfixes in an officially blessed release state. Watch the Rhino download page to see when 1.6R3 pops up for download. Shouldn't be more than a day.

I'm still trying to find myself a bit of a time to learn a new programming language. No specific reason, just trying not to narrow my view too much on Java and try a language that forces me to adopt/discover new ways of thinking about software architecture. The only problem is, there are too many candidates. LUA, Haskell, Ruby, to name just a few. There's one particularly interesting new language that seems to get lots of publicity lately: Scala. A fully OO (every value is an object, no primitive/object types dualism as in Java) and at the same time fully functional language, that also natively compiles to either CLR or JVM bytecode, allowing it to be used within a .Net or Java system seamlessly. This is quite an advantage since it makes it possible to use any Java library with it, something that I can maybe readily and easily introduce into daily work if need be. I sometimes find myself in a situation where an otherwise elegant idea takes quite a verbose and/or awkward code to be expressed in Java, and think that a language that is more friendly toward designing internal domain-specific languages (Ruby, as Martin Fowler demonstrated it nicely during his presentation at JAOO last year), or even comes standard with macro preprocessor of some description (yes, I know C macros are evil, but I don't generally use them in evil ways) would really help reduce clutter. Maybe Scala? Don't know yet. I did download its full documentation - something to print out and then read on my vacation in Italy next week. Wife is going to kill me for it, though :-)

Saturday, July 01, 2006

First penguin to climb Mt. Everest

Few days ago, while spending our vacation in a camping near the Hajdúszoboszló Aquapark, in the evening sitting on a bench in front of our trailer home, my son Ákos asked with a fully serious face: "Dad, what was the name of the first penguin to climb Mount Everest?".

I just adore my big seven year old son.

We tried to discuss it briefly, and he suggested that some alpinist could actually tie up a penguin and take it with him to the Top O' The World, but I told him that the animal rights activists would have a word or two about it, so it's highly unlikely. On the other hand, we speculated that as a rule, humans only climb Mt. Everest during summer and maybe penguins visit it in the winter, that sort of weather certainly suiting them better, when no human can observe them. We envisioned a crowd of penguins in full alpinistic equipment gathering at the foot of the mountain, looking enthusiastically to the challenges that await them. We rolled with laugther.

He then went on to invent a story about a penguin who left South Pole as he wished to see the world, climbed Mt. Everest, crossed the Kalahari desert where he found a small town, settled in it, then went on to earn a living first by being a street musician (we recently watched "Cars", and they show One Man Band before it, maybe that's where the idea came from) and later by building a power plant and wiring the houses and selling electricity to the city. There was also a wish-granting magic stick involved in the story that the penguin used to wish all his penguin friends he left behind are with him, but it backfired as they quickly died of dehydration in the desert (when I asked why our hero, also a penguin, didn't die as well, he explained that he travelled in a special aquarium car that kept him wet). Fortunately, for undisclosed reasons, the magic stick only transferred third of his friends, so he presumably got few more left back home.

I remember sitting on a chair placed to face opposite the bench, rendered too unwilling to move by the slight fever accompanying my bronchitis (ideal development for a vacation, huh? Right, I thought so too.) and not very willing to talk either due to a sore throat, and just listening to him fascinated as he tirelessly spun his story further and further for at least an hour. It finally ended when I told him we'd have to head for showers and then for bed soon lest we be totally consumed by mosquitos. By that time the penguin (who remained nameless, or at least, unnamed) was providing electricity for the whole world, but in the end got homesick, went back to South Pole (yes, I know strictly speaking they don't live at the Pole proper, but that's how he told the tale), and divided the wealth he accumulated during his electricity tycoon and street musician times among its (remaining two-third of) friends.

Few days later, on a similar evening while sitting on a bench and eating cherries he asked me whether there's a limit to one person's creativity.

Guess what I answered him.

Wednesday, June 14, 2006

Accomodating for everyday parallel computing

A bit more than a year ago, Herb Sutter published "The Free Lunch Is Over: A Fundamental Turn Toward Concurrency in Software" in Doctor Dobb's Journal (which is incidentally the only printed computer magazine I buy). If you don't know this article yet, go and read it, I'll wait right here.

In case you're hasty and decided to skip it in spite of better advice, here's the summary: the trend over the years was that you could afford yourself to keep writing ever less efficient code and have it be compensated by increase in hardware processing power. That trend is over. The reason: CPUs today aren't made faster by increasing their linear processing speed anymore. CPU manufacturers are encountering big technical difficulties on that route lately. Rather, the CPU processing power is increased by adding multiple cores. The bad news is that your sequential, single-threaded algorithm won't automatically benefit from this, as it did from clock speed bumps in the past years.

So, what's to do? Ignore the problem is one solution, but computers with multicore CPUs are today quite widely available on market. I'm typing this on an Intel Core Duo system myself. Running a test program with an infinite loop won't max the CPU utilization on this gear. It'll push it up to 50%. I need to run another instance of the program to push the CPU all the way to 100%. If you ignore the system, you'll produce software that can only utilize 50% of the CPU resources. People will inevitably find it slow over time and use your competitor's software who chose to not ignore the problem.

Another possibility is manual parallelization. Identify hotspots in your code. Rewrite them to be multithreaded. Use mutexes, locks, the whole shebang of multithreaded programming. If you have an array of 1 million elements (a big sound sample, maybe, or a picture), chunk it up and feed each chunk to a different thread. Even better, than chunking it into 2 equal parts on a 2 CPU system, code a producer-consumer pattern to chunk it into many small pieces and feed to threads adaptively. Of course, your code increases in complexity considerably. Of course, your program might have a runtime overhead for spawning new threads. And then there's the fact that concurrent programming on "low level" - using threads and locks explicitly is hard. It is easy to get it wrong and create race conditions and deadlocks at runtime. So, is this solution ideal? Far from it.

An ideal solution would be a programming paradigm that does yield readable source code, and still allows the compiler or the runtime system to identify paralellizable operations and paralell them, either statically (compiler) or dynamically (a runtime JIT compiler after it decides that the up-front cost of setting the paralellization is less than the gain from paralellization of an operation).

Just as today we have runtime environments with implicit memory management and languages designed for writing programs that run in such an environment, we could soon have environments that have implicit parallelization.

As a typical example, a transformation applied to all elements of a collection independently is a good candicate - provided your programming language lets you express it in such a way. I believe that functional languages are better prepared for this kind of implicit parallelization. There are already some academic-level efforts underway, witness Parallel Haskell.

One very interesting notion some people are vocal about is that stack-based computational models inherently stem from the sequential approach to programming, and that as we strive to embrace programming approaches that naturally lend themselves to paralellization, we'll gradually embrace computation models that aren't stack based. Like the just mentioned functional programming where you don't really express your program in terms of subroutine calls. Or how Excel 12 will also feature parallel computations. BTW, the previously linked blog entry also contains links to some interesting research going on in this general area of single-machine parallel computing.

Is it a say hello again to state machines? Maybe, maybe not. One thing I can more readily imagine is that a today's widespread architectural model for enterprise systems - asynchronous messaging - will somehow get adapted for single-machine single-process development that is meant to run on multiple CPUs.

Saturday, June 10, 2006

New Gear

I bought a MacBook Pro. It's a first-gen 15.4" 1.83GHz Intel Core Duo piece - it was the only one that the dealership could ship quickly, so I sacrificed 170 MHz per CPU core rather than having to wait one month for the machine to ship. I ordered a +1GB RAM stick and a bigger HDD, but they managed to screw up the order, so these will arrive next week. Sheesh.

The reason I bought a MBP: I need mobility. I realized that while my iMac G5 is an absolutely satisfying machine for all my work, it falls short if I need to do work, but kids insist that I take them down to a playground. Or we want to spend the weekend in our hobby garden out of town, and I want to have a computer with me for evenings. Also, lugging the 11kg 20" iMac is possible - I proved this to myself taking it with me from Szeged, Hungary to Reading, UK and back - but by no means a pleasant experience. (There were no problems with airport security, mind you - Heathrow has a policy that you must take your laptop out of the bag and have the bag and the laptop screened separately. I argued that my computer is not a laptop, and they let me not have to unpack it from its iLugger, thank God. The screening lady cheerfully said "Look, this guy carries a big computer screen with him!" to a passing colleague, so that I can feel like a complete dork.)

Anyway, I'm typing this on the MBP now, after a rather painless transition - all my files, applications, and settings were transferred automatically from the iMac. I had a strange incident though - when the setup got to setting up wireless, I forgot that my router is locked down and will only accept connections from predefined MAC addresses. After two unsuccessful attempts (I thought I forgot the password), the setup froze, and I had to reboot it. It was rather painless afterward though, but since the second time I opted to not transfer data from another machine (would take another three hours), I had to create a local account that I later deleted.

Also a hopefully minor problem - I have to reinstall Fink, so it's bootstrapping in the background as I'm writing this, fingers crossed it'll all work. The nice thing is, the Fink binaries transferred from the iMac actually worked after the migration, as the Rosetta (Mac OS X's built-in PowerPC CPU emulator) picks them up, but various update processes quickly notice that the CPU architecture suddenly changed to x86, and get mightily confused, so it looks like the best idea is to recompile everything from scratch. It does make me a bit anxious though. Fingers crossed, as I said.