Sunday, December 24, 2006

Citation: Concurrency in Java (Van Roy and Haridi)

Concurrency in Java is complex to use and expensive in computational resources. Because of these difficulties, Java-taught programmers conclude that concurrency is a fundamentally complex and expensive concept. Program specifications are designed around the difficulties, often in a contorted way. Biut these difficulties are not fundamental at all. There are forms of concurrency that are quite useful and yet as easy to program as sequential programs (e.g., stream programming as exemplified by Unix pipes). Furthermore, it is possible to implement threads, the basic unit of concurrency, almost as cheaply as procedure calls. If the programmer were taught about concurrency in the correct way, then he or she would be able to specify for and program in system without concurrency restrictions (including improved versions of Java). (Concepts, Techniques and Models of Computer Programming, Peter Van Roy and Seif Haridi)

First of all, I completely agree with the authors. I like learning new languages/paradigms/models and find quite restricting sticking to just One Language, One Platform, One Model. I'm fond of Python (but indeed Python is an excellent imperative/object oriented language that allows functional programming -- and logic programming is experimented among other things in pypy). I also like Ruby (again Imperative with functional capabilities). I recently discovered the power of Prolog, and I love Haskell (although I never wrote any substantial piece of software in Haskell).

I can't imagine working with Java and only with Java (and the same applies to 'C++ and only C++' or whatever). However, there is plenty of programmers out there that chose One Language, One Platform, One Model and stick with it. I'm wondering if we can generalize Dijkstra statement

The use of COBOL cripples the mind; its teaching should, therefore, be regarded as a criminal offence.

In fact it seems that Java has the very same problem. A lot of Java programmers are only able to formulate problems (and solve them) thinking in Java. One may argue that maybe business programmers already had their mind crippled, but I don't think this is the case.

I'm afraid to say the problem is not limited to Java, of course (it's just more evident because there a lot of Java programmers). There are a lot of excellent C++ (for example) programmers that simply do not believe that large programs written in dynamically typed languages can work (and of course they are wrong, since we can exhibit such programs). On the other hand some Python/Ruby/etc advocates think that static typing is fundamentally bad. In fact it is not: Java type-system is poorly designed. It's not that static typing is wrong or clumsy. Haskell and OCaml are statically typed, but types do not get in the way: they are a concrete help for the programmer (but this does not imply that a language should be statically typed).

My opinion is that more programming languages, models, paradigms should be taught to programmers. For two main reasons: first, they know more ways to solve a problem and hopefully they will be able to choose the best one; second, they will be able to adapt concepts coming from other models/paradigms/languages to the language they are currently using, thus making the design more elegant.

Elegance is not a dispensable luxury but a quality that decides between success and failure. (Dijkstra)

Saturday, December 23, 2006

Books and information technology.

This article won't be very interesting for people living in an English speaking country: most technology books are written in (or at least translated to) English. However, things change if you do live in a country where English is not the main language (like Italy) and most people can't read English comfortably (again, like Italy).

A lot of people working in the IT field here find it more difficult to read in English than in Italian, and they choose books translated in Italian, if they are available.

I prefer English books: they usually cost less and there are no translation errors (by definition). Moreover, there are less errors in general, since more people read the book (and thus has the opportunity to find and report errors). Famous hackers and scientists from all the world usually speak English (and deliver lectures in English): they also tend to write books in English (even if it is not their main language).

Moreover, there are subjects where the translated books (for example Python books in Italy) are *not* the 'best' books on the subject. For example in Italy you can buy 'Programmare in Python' (that is the translation of Learning Python) or the *very* old 'Python 2.1 Tutto ed oltre' (that refers to Python 2.1 and is still being sold). Python in a Nutshell (whose author *is* Italian) is not available, and the list of 'missing' titles is much longer.

In a country like Italy, availability of books on a particular technology can be one of the main reasons why that technology is adopted. In fact a lot of Microsoft books (or books on Microsoft products) are translated (or even written from scratch in Italian by Italians). Another language that fills whole bookcases in our bookshops is Java. PHP has a lot of beginners books, too.

In my opinion none of the aforementioned programming environments excels. Java has a beautiful library (although terribly over-engineered) and a very promising VM, but the language itself sucks. PHP has a horrible library, a terrible Virtual Machine and the language itself sucks even more. .Net has a wonderful VM (but unfortunately not cross-platform -- a part from Mono), but C# is not better than Java, and VB... luckily enough you can run a recent Python version in the .Net environment, but again, you don't find a lot (if any) of information about this in Italian books.

Every time a new programmer goes to a bookshop to buy a book to start learning programming, he is very likely to find a book on Java/MS/PHP. And until he 'grows' up, and learns to look for pieces of information in other places, he will be bound to those technologies. In fact she could have learned sooner (and having more fun) if she discovered Rails (for Web development) or Python. There *are* some books on those subjects (and a whole free book -- but in English -- on Django (a Python Rails-like framework), however, they are a few, and someone who starts looks for 'big names'.

Friday, December 22, 2006

.Xmodmap hex digits

I's a couple of day I'm hacking with xmodmap and keycodes to make my keyboard behave as I expect.

Recently it sprang to my mind that with SuSE 7.1 I used a utility called xkeycaps.

Unfortunately enough xkeycaps generates an .Xmodmap with keycodes expressed as hex numbers, while xev shows code as decimal numbers

This simple ruby oneliner converts an .Xmodmap file with hex codes to one with decimal codes

cat .Xmodmap.hex |
ruby -n -e "if $_ =~ /keycode\s*(0x[A-F0-9][A-F0-9])\s*=\s*(.+?)\n/; puts \"keycode #{$1.hex} = #{$2} \" else puts $_ end">
.Xmodmap.dec
provided you called the hex .Xmodmap '.Xmodmap.hex'.

Tuesday, December 19, 2006

A Prolog XML printer in less than 100 lines.

Suppose we have an XML parser that converts an XML file into a Prolog term.
We may (quite) easily build one with DCG. I will be doing one soon, for values of 'soon' that depend on the status of my thesis.
We describe the way the prolog term is built:
Text is simply a prolog term. In a less naive implementation we may want to use the string datatype. However, to show the power of a declarative approach, things would not change a lot. Moreover, if we are using swi-prolog (a widespread open source implementation) internally itis able to use UCS (that is a superset of 16 bit Unicode). We only have to make the parser smart enough to convert entities in the right Unicode character and the whole thing will behave correctly
Attributes are represented as key:value terms, where : is a binary infix functor. Again, this is quite a natural representation.
A tag is represented like an tag(Attributes, Children) term, where term is the name of the tag, andl Attributes and Children are (possibly empty) lists of attributes and 'children'. This representation is not very clever. In fact you can have more optimized programs representing tags like element(tag, Attributes, Children). That is the way things are done in SWI-Prolog official SGML/XML parser library, but this is a simple example.
A 'child' is either a tag or a text section.
This (informal) description can be translated in a straightforward manner in a prolog program. The last thing before presenting the source is an example term representing a very simple XHTML file.

html([], [head([], ['']), body([], [p([], ['ciao ciao', img([src:'ciao.jpg'], [])]) ])])

And now the (81 lines long) prolog source code. You can call it with pp_tag(Term), where Term is the term representing the XML file.

pp_tag(Tag) :-
        !,
        pp_tag(Tag, 0).
pp_tag(Tag, N) :-
        Tag =.. [Tag_Name, Attributes, []],
        !,
        s(N),
        write('<'),
        write(Tag_Name),
        pp_attributes(Attributes),
        write(' />').
pp_tag(Tag, N) :-
        Tag =.. [Tag_Name, Attributes, Children],
        !,
        s(N),
        write('<'),
        write(Tag_Name),
        pp_attributes(Attributes),
        write('>'),
        N1 is N+1,
        pp_children(Children, N1),
        nl,
        tab(N),
        write('
        write(Tag_Name),
        write('>').
pp_text(Text, N) :-
        name(Text, Chars),
        pp_lines(Chars, N).
pp_line(Line, N) :-
        name(Atom_Line, Line),
        s(N),
        write(Atom_Line).
pp_lines(Lines, N) :-
        ((append(Line, [10|Rest], Lines), !),
            pp_line(Line, N),
            pp_lines(Rest, N)
        ;
            Line = Lines,
            pp_line(Line, N)
        ).
pp_children([], _N) :-
        !.
pp_children([X|Xs], N) :-
        !,
        pp_child(X, N),
        pp_children(Xs, N).
pp_child(Child, N) :-
        pp_tag(Child, N)
        ;
        pp_text(Child, N).
pp_attribute(Name:Value) :-
        !,
        write(Name),
        write('='),
        pp_quoted(Value).
pp_attributes([]) :-
        !.
pp_attributes([X|Xs]) :-
        write(' '),
        pp_attribute(X),
        pp_attributes(Xs).
pp_quoted(Term) :-
        !,
        write('"'),
        write(Term),
        write('"').
s(0) :-
        !.
s(N) :-
        nl,
        tab(N).

Of course this is a 'toy' implementation. You find the real thing here.

Monday, December 18, 2006

Windowmaker

How much I love windowmaker...

Now it is much less used than once... Most people do use KDE or GNOME (or XFCE) and the good old Window Managers are kind of forgotten (or maybe simply unknown to the masses). However, when I started KDE was slow and took every single byte of RAM from my machine. GNOME was somewhat lighter. However, the desktop environment was not polished and practical (it wasn't even the 2.0).

In fact some window managers/desktop environment had higher usability (at least in my opinion) even though you had to renounce to a good file-manager (and back than gmc/nautilus was not as good as today).One of those is WindowMaker.

Simple and powerful. As it is today. Well... I restored it on my Ubuntu. Without the debian menu you have to build the application menu yourself (and that is a pain in the ass). However, since most of the times I'm only using firefox, emacs and a terminal, I managed to do it in a very short time.

Saturday, December 16, 2006

Compilers: Principles, Techniques & Tool (Dragonbook)

A couple of days ago it arrived my own copy of "Compilers: Principles, Techniques & Tool" by Aho, Lam, Sethi and Ullman, better known as the "Dragonbook" (look at the cover to understand why). This weekend I am starting reading the 992 page long book. Actually I find it well written and very clear, even though I'm at the beginning of the book.

I suspect things will get more complicated while proceeding further. However, I find the subject dramatically interesting. I hope to find enough time to read it quickly and eventually start implementing something. Some ideas contained in the book I suppose will be of great help for my thesis (in fact I'm implementing something that is closely related to a compiler).