J'essaie d'apprendre un peu à programmer pour Android ; j'ai un certain nombre d'idées d'applications qu'il pourrait m'amuser d'écrire[#] : par exemple, un programme d'éphémérides astronomiques[#2] ou une calculatrice scientifique à notation polonaise inversée ; mais plus pragmatiquement, je suis intéressé à apprendre un peu plus sur Java — que je ne connais que d'assez loin[#3]. Je trouve que parcourir la référence de la bibliothèque standard donne un peu envie de coder pour ce gadget. À l'inverse, la complexité du cadre général fait un peu peur (et explique en partie pourquoi, même du point de vue de l'utilisateur, on soit un peu perdu : savoir quand une application continue à tourner en tâche de fond, quand elle est arrêtée, à quel point on va revenir en appuyant sur la touche de retour arrière, etc., tout cela est assez explicitement mal défini).
Ce qui est souvent irritant, en programmation, ce sont les
quantités d'incantations propitiatoires qu'on doit prononcer
avant de pouvoir enfin arriver à un état qui fait vraiment quelque
chose d'utile : j'ai l'impression que, plus l'informatique progresse
et plus ce phénomène se répand — les langages ou environnements
modernes ont peut-être une efficacité marginale plus élevée
que les anciens, mais les environnements graphiques ont tendance à
demander un code extrêmement lourd pour juste ne rien faire du tout,
c'est-à-dire, pour pacifier les puissances tutélaires qui veillent sur
votre code. En C standard, pour
écrire Hello, world!
, il suffit de faire
#include <stdio.h> int main (void) { printf ("Hello, world!\n"); return 0; }
alors que si vous voulez faire la chose analogue (dans une fenêtre), disons, en Gtk, ça ressemble plutôt à ceci :
#include <stdio.h> #include <stdlib.h> #include <glib.h> #include <gtk/gtk.h> #include <gdk/gdkkeysyms.h> static gboolean key_callback (GtkWidget *window, GdkEventKey *event, gpointer data) { if ( event->keyval == GDK_Escape || event->keyval == GDK_q || event->keyval == GDK_Q ) gtk_main_quit (); return TRUE; } int main (int argc, char *argv[]) { GtkWidget *main_window; GtkWidget *event_box; GtkWidget *text_label; gtk_init (&argc, &argv); main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_container_set_border_width (GTK_CONTAINER (main_window), 10); event_box = gtk_event_box_new (); text_label = gtk_label_new ("Hello, world!"); gtk_container_add (GTK_CONTAINER (main_window), event_box); gtk_container_add (GTK_CONTAINER (event_box), text_label); g_signal_connect (G_OBJECT (main_window), "delete-event", G_CALLBACK (gtk_main_quit), NULL); g_signal_connect (G_OBJECT (event_box), "button-press-event", G_CALLBACK (gtk_main_quit), NULL); g_signal_connect (G_OBJECT (main_window), "key-press-event", G_CALLBACK (key_callback), NULL); gtk_widget_show (GTK_WIDGET (text_label)); gtk_widget_show (GTK_WIDGET (event_box)); gtk_widget_show (GTK_WIDGET (main_window)); gtk_main (); return 0; }
Beaucoup de ces lignes sont vraiment ce que j'ai envie d'appeler
des incantations rituelles. Et je doute que ce soit beaucoup mieux
dans un des concurrents quelconques de Gtk
(comme Qt ou, sous d'autres OS, les
environnements graphiques de Windows ou Mac OS) : d'une
manière ou d'une autre, il faudra bien décider comment on quitte le
programme, et aussi définir tous
les widgets et
comment ils s'imbriquent, même si j'aurais envie que le code pour ça
ressemble plutôt à quelque chose comme new Window([new
Label("Hello, world!")])
— enfin bon. Parfois des gens
se sont dit, oh, pour concevoir les interfaces utilisateur, au lieu
d'avoir du code qui fabrique les widgets un par un, mettons-les dans
un arbre XML : ça part d'une bonne intention, mais
le XML est à peine moins lourd, en fait, et je ne parle
pas des cérémonies qu'il faut effectuer pour pouvoir utiliser
ce XML depuis le code proprement dit (sous Android, quand
on veut utiliser des chaînes de caractères placées dans un
fichier XML pour aider l'i18n, il y a un truc magique qui
génère une classe R
qui contient uniquement des
constantes qui permettent de désigner des ressources accessibles
via ctx.getResources().getText(R.string.leNom)
: était-il
vraiment impossible de faire plus concis ?
pourquoi R.string.leNom
ne serait-il pas directement la
chaîne voulue ?).
Tant qu'à faire des incantations propitiatoires, autant l'assumer
et imaginer un langage de programmation dans lequel on doive
régulièrement appeler perform_ritual_sacrifice(&apollo,
cattle_head, 100)
, un peu comme le PLEASE
d'Intercal.
[#] Soit parce qu'elles n'existent pas du tout, soit qu'elles existent mais pas sous une licence libre, soit simplement que je trouve que ça a l'air amusant de réinventer la roue.
[#2] Oui, je sais qu'il existe Google Sky Map.
[#3] Ce qui devient un
peu irritant, cependant, avec les langages de programmation, c'est
qu'on dépense l'essentiel de l'effort cognitif associé à leur
apprentissage sur les détails complètement insignifiants
du sucre
syntaxique. Se rappeler pour quels langages il faut
écrire else if
, pour lesquels
c'est elsif
, elif
ou
encore elseif
, c'est vraiment assez peu intéressant. (Et
pour Java, je n'ai pas forcément envie non plus de retenir les choses
marginalement syntaxiques comme la signification
de final
public
static
private
blah.) Bizarrement, je n'arrive pas à trouver facilement en ligne de
générateur de cheat sheet qui permette
commodément de générer et d'imprimer des listes récapitulatives ou
comparées des constructions syntaxiques les plus communes dans les
langages qu'on choisirait. Je note ça pour plus tard !