Friday, October 24, 2008

The lost Beautiful Programming Language

It was old time when a new programming language comes out, trying to be the best of all existing languages, designed by a Guru, aiming too fill a hole, etc. I think the last one was Java. Today when we see what a developer can do with an IDE like eclipse on Java, we really wonder what will the next language be and how can it be better.

However this is not taking account what mankind can do for its own loss. When we can't do better, we do worse.

The web pressure made plenty of "web" languages pop up in the landscape. One of them, Flex, looks very popular. But after playing with it, it becomes clear to me that Flex is backtracking.

Flex comes with Flex builder, a plugin on eclipse. However, the integration in eclipse is very minimal. No refactoring, no code assist, no automatic indentation, complex project settings. Only the editor, the debugger, a profiler, and the expensive wysiwyg designer that generates xml are available. I'm not sure it worths the 400M of my RAM the flex builder is eating. All in all, I miss Java support in Eclipse.

But IDE support is not all. Flex syntax is confusing, especially when it mixes xml and ActionScript. Even the semantic is misleading. Let's take an example:


var t:Object = { foo:bar } ;


The right hand part creates an object, actually an "association list". It contains a property of type key/value, where key is "foo" and value is "bar". "foo" is a String literal, but "bar" is supposed to be an object. The value is stored in the association list, but is eventually converted to a string. To use it:


t.foo ;
// or
t["foo"] ;


Note the very unusual use of "." and "[ ]". Anyway, this construct is very handy. Basically, an association list is an hashtable.


I let you imagine how much time it needs to figure out this simple feature from the documentation, and how error-prone can be a language with plenty of this kind of counter-intuitive syntax. I know, this is common with scripting language. But can we still speak about scripting languages when it has packages and an object-oriented layer?

So yes, Flex is the royal language for RIA, but no, it's not as slick as Java.

Tuesday, October 14, 2008

I fixed a bug in 37 minutes


Obviously, this is not an outstanding performance. The statement looks very common, however it assumes a lot of things:
  • I was able to measure the time it really takes. Actually I use mylin extension of Eclipse to help me drive my work by task. This time, I don't know why, I paid attention to the elapsed time to completion, a built-in feature of mylin I never used before.
  • I was not disturbed or distracted during 37mn in a row. It seems to me it has been years I couldn't focus so much time on a single task.
  • The bug itself wasn't a big deal, but I think I am the only one on earth to fix it in such a short delay. It's not because I'm super-developer, but because I know the best this part of code, and my developing environment is ready to tackle this kind of bug. Even a genius challenger would need a couple of dozen of minutes only to setup the right environment. Actually the difficulty of this bug was to find out the right place to fix it, and I used the debugger to find this place quickly and accurately, instead of navigating through the sources. The fix itself was simple.
  • I searched in google code source an implementation of a method that was part of the solution. I could implement it myself, but it saved me a bit of time.

It's only unfortunate that the time I saved fixing this bug has been wasted writing this post!

Friday, September 19, 2008

Sofware equations

I've told already about:


Software = Algorithms + User Interface + Bugs


Here is another one:


Programming Language = syntax + semantic + doc + libraries + IDE


The two first, syntax and semantic, are mandatory to define the language. The other ones are simply making it respectively understandable, useful, and usable.

The documentation contains the reference manual, the user manual, tutorials, and sometimes other kind of document that helps the transition from another language to this one. Ususally, a language is not coming up from scratch. It reuses known concepts (e.g. object oriented, multithreads) and can be very close to another existing language. For instance, Java syntax is similar to C, so dedicated books explaining Java for C programmers are very popular.

Libraries are making today the differences between languages. The object oriented paradigm spreads the concept of library driven by an API. And the web technology is a great producer of layers and libraries. As more and more libraries are integrated, the language becomes more and more useful.

IDE is now inevitable. Once a developer has tested a serious IDE like eclipse or visual C++, it's very difficult to go back to antic era where code is written in a text editor, compiled, debugged with an external debug tool (when it exists), and deployed through a shell script. The IDE provides the editor, compiler, and debugger, but also it suggests code patterns, completion, syntax highlighting, online documentation, and provides powerful navigation, packaging, etc.

Wednesday, July 2, 2008

flex / silverlight comparison

I've just attended a presentation comparing flex and silverlight. In short, both languages are equivalent in terms of functionalities and libraries, which is not really a surprise... However, the noticeable differences are:

- IDE: Flex builder exploits 10% of eclipse capabilities and is far behind visual studio (but is far less expensive). There is not even automatic indentation!
- performance: current silverlight version (2 beta) is 3 times slower than flex 3! Remember flex is itself 3 times slower than Java.
- deployment: flex plugin is deployed at 97%, silverlight is probably closer to 3%.

Of course these differences holds at this very time. Both platforms try to catch up with the other to become the leader, but no doubt flex is ahead for the moment.

Friday, June 13, 2008

Software = Algorithms + User Interface + Bugs

This point of view holds for desktop applications, but also for any embedded software or more generally, everywhere there is a programmable chip.

The algorithm part is the most obvious for developers. It represents the processing of data and more recently the integration of libraries at different levels to provide compatibility between the various operating systems, languages, and protocols (read for instance: the web is a mess). Algorithms are the engine of the software. When developing resources are low the temptation is high to focus only on this part, because it produces the main output.

User interface is the steering wheel and the dashboard of the software. It becomes more an more an issue especially for portable devices, like a mobile phone or PDA where it really makes the difference between a useful gadget and a piece of crap. A bad user interface cancels all efforts provided by the software and hardware behind. UI is not trivial. The communications between machine and human goes mainly through a screen in one direction, keyboard, buttons, and mouse in the other direction. This is not always intuitive, and that's why UI is critical as machines become more complex.

Unlike Algorithm which is an hard science backed up by the power of mathematics, UI is an cognitive science. There is no formula for UI, only general guidelines for developers and eventually statistical studies bring the most reliable metrics.

Bugs are the dark side of the software. Nobody wants them, they are here. They are just part of the process. In our car metaphor, the bugs are all what don't work as expected from the annoying inside light that don't work when the door is open, to what can cause or aggravate an accident.

UI is a cognitive science, bugs are no science at all... They are unpredictable, and apart research projects around formal provers that are applicable in specific conditions, only intensive test suites can find out the bugs in the general case. But it remains the environment around bug fixing. I mean if we accept software have bugs (and we should do), then let's spare resources and prepare tools to handle them efficiently once they are found.

To take care of bugs, a dedicated team named QA is needed. If QA has a price, the lack of QA has a much higher cost. For most secure applications like embedded software in planes, QA can represent up to 70% of the product price...

The common point between Algorithms, UI, and Bugs is that they are much more easier to handle when they are taken account early in a product life cycle. It's not once the product is out that you start taking care of UI or tests ...or the algorithms!

Tuesday, June 3, 2008

OS scheduler and grilled beef skewers

BBQ
Did you try to cook beef skewers on a BBQ ? A BBQ is not a balanced heat source, and skewers are difficult to turn around. The result is that some pieces are burned while others are still raw.

For sure OS makers are aware of this problem. The proof ? Try to run an infinite loop in a shell, like in bash: while true; do set x 1; done, and look at the task manager to see how busy are your multi-core machine.

The naive answer suggests one core is 100% busy while others are free. However the reality is different. On XP, the OS scheduler happily migrates the infinite loop process from one core to another making all cores partially busy with this infinite process.

Advantages: the only one I see is that load balancing avoids extra heat on one part of the CPU, exactly as if the skewer where regularly turned and moved around all over the grid to be better cooked.

Drawback: the process migrates, which means in addition to context switch overhead the data are copied from one L2 cache to another. Overall time is longer than on a mono-core machine.

Workaround: You can pinpoint a thread on one core and prevent it to migrate elsewhere. This is called "single core affinity".



Tuesday, May 13, 2008

Multi-threading: the mine field is ahead

You think you master multi-thread programming ? CPU makers are asked to improve CPU efficiency, without paying
attention to the software behind who needs to cope with the new features. To put it clear, CPU makers are working on your next traps.
  1. memory access swapping
  2. instruction reordering
  3. asymmetric cores and unfair memory access

A read instruction is a lot faster than a write, and the memory bus cannot perform in both directions at the same time. Memory access, even a read, is still slower than CPU basic instructions. To keep the CPU busy, it may be needed to swap some memory access. For instance if the CPU has enough data in the cache to run without other memory access, it's a good time to perform an expensive write, even if read access are scheduled first. Also, some instructions can be reordered to optimize the processing pipeline and take advantage of the co-processors.

These arrangements inside the CPU are managed by a code analyzer which detects commutativity of sequence of instructions, and independence between variables. This analyzer works in a single thread context, so it's up to the developer to identify multi-thread issues and to forbid the CPU to arrange some parts of the code by synchronizing code and protecting data access.

Examples are numerous, here is a simple one, in a symbolic language

boolean ready = false;
int result = 0;

thread1:
while (!ready) {
Thread.yield();
}
print(result);

thread2:
result = 11;
ready = true;



The human understands quickly the purpose of this program. Thread2 is producing a result, toggling a boolean when completed. The other thread waits for the result to be ready before consuming it. But without any protection, this program can print 11, 0, of even nothing because thread1 loops forever!

That's because if you imagine yourself a single core executing thread2, you don't bother writing back the values result and ready because you don't need them afterward. Only a context switch forces you to flush the cache and then to update the memory location of these variables.

The core running thread1 is even worse. ready and result are not bound by an expression. They are independent so they can be fetched in any order. In particular, if result is read before ready, it prints 0. Also ready, once loaded on the cache may never been refreshed from the main memory, which leads to the infinite loop.

Sometimes it runs just like human expected, and the program prints 11. But that's a lucky execution, actually...

Last mine in our field, for the moment, is the asymetric architecture: a core has some privileges, runs faster or has more cache, or gets higher priority to the memory bus. It's a nice idea. An important thread can run faster than the other. But once again the software is far behind. OS kernel are usually SMP (symetrical multi-processor), and dispatch processes in a fair way across the processors, which is exactly what we don't want. Same for the higher level.

Assuming we have the possibility to pinpoint an important thread in the best core, the developer still have to think again the multi-thread logic to optimize the core assignments. Still good development time to go...