Styles

jeudi 9 décembre 2010

Closures - Partie 1

Alors que certains langages se posent encore des questions existentielles sur l'incorporation ou pas (et à quelle date) de closures, cette capacité d'un langage de haut niveau est largement déployée au sein des langages dits dynamiques (moins péjoratif que langage 'script'), sans parler des langages fonctionnels pour lesquels les closures sont aussi naturelles que les fonctions d'ordre supérieur.

Sur le Web, il n'est pas rare de voir des exemples explicatifs de ce que sont les closures, mais plus rarement des exemples d'application des closures à des cas concrets. Je vais, dans plusieurs billets de ce blog, essayer de vous fournir un aperçu de cas concrets où l'utilisation des closures est intéressante.

Avant de commencer, il est bien sur nécessaire de clarifier ce qu'on entend par closure.

Au départ étaient les mathématiques et tout était clair et non-ambigüe. Ils donnèrent au nom de 'fermeture' (closure)une définition algébrique : Un ensemble d'éléments est dit fermé (closed) sous une certaine opération si l'application de cette opération aux éléments de l'ensemble produit un élément qui est encore un élément de l'ensemble.

Puis vinrent les informaticiens qui par leur nature fainéante, firent des raccourcis honteux : la communauté Lisp employa le mot closure pour décrire un concept complètement différent : une closure est une technique d'implémentation pour représenter des procédures ayant des variables libres.

De cette non-conformité au concept mathématique provient une partie de l'incompréhension qu'ont la plupart des programmeurs de base. Et puisqu'il faut rester concret quand on fait de l'informatique, voici l'exemple de base pour créer une closure, qu'on retrouve dans tous les articles d'introduction. L'exemple est en Python 2.7 :
def multiplier(nb):
def multi(value):
return value * nb
return multi
Ici, multi est la closure, multiplier est la fonction fabricant la closure. La plupart du temps, il s'agit d'encapsuler dans une fonction la création de la closure. La closure dispose alors des variables locales de la fonction dans laquelle elle a été créée. On peut appeler multiplier, l'usine à closures ('closure factory').

On peut utiliser cette closure de cette façon :
>>> multi10 = multiplier(10)
>>> multi10(2)
20
C'est un peut comme si on appelait l'usine à fabriquer des closures pour configurer au moment de l'exécution (runtime) une fonction particulière et d'en produire donc de toute sorte.

Comme il s'agit ici d'encloisonner des variables dans un scope particulier à la closure, on peut très bien définir le même comportement en utilisant la notion de classe classique. L'exemple ci-dessous converti en classe donne :
class MultiplierFactory:
def __init__(self, nb):
self.nb = nb
def multiply(self, value):
return self.nb * value

>>> multi10 = MultiplierFactory(10).multiply
>>> multi10(2)
20

C'est une façon de créer des pseudo-classes anonymes, sachant qu'une classe ne sert qu'à gérer la 'globalité' de certaines variables. Pour continuer le parallèle entre une closure et une classe, il va être possible, de façon beaucoup plus succincte d'exprimer des modèles de conception comportementaux en closure.

Une closure n'est pas simplement une fonction anonyme qu'on se passe de variable en variable. Pour réellement parler de closure, il faut qu'il y ait en jeu des variables libres telles que nb dans l'exemple précédent.

A noter aussi qu'une closure ne s'exécute qu'au dernier moment, lors de son appel explicite. La configuration de la fonction n'a pas nécessité de faire fonctionner du code source de cette fonction.

C'est par exemple, intéressant quand on veut programmer par évènements et appels en retour (callbacks). Par exemple, sans closure, on pourrait essayer de coder quelque chose comme ça, mais ce code ne peut pas marcher :
from threading import Timer

def show_message(msg):
print msg

def set_alarm(msg, timeout):
Timer(timeout, show_message(msg))

>>> set_alarm("Réveille Toi !", 3)
Réveille Toi ! ---> s'affiche instantanément
En effet, Timer(timeout, show_message(msg)) va appeler show_message(msg) avant d'appeler Timer. Timer va donc être appelé avec le résultat de l'appel à show_message(msg), ce qui n'est pas ce que l'on veut. Par contre, avec une closure, on peut écrire le code de cette manière :
from threading import Timer

def set_alarm(msg, timeout):
def show_message():
print msg
t = Timer(timeout, show_message)
t.start()

>>> set_alarm("Réveille Toi !", 3)

Au bout de 3 secondes on a :
>>> Réveille Toi !
Ce bout de code permet d'éviter l'emploi d'une variable globale msg, qu'il serait alors difficile de maintenir cohérente dans un environnement multithread par exemple.

jeudi 2 décembre 2010

Python en remplaçant de Perl

Je me suis mis récemment au langage python. J'avais des préjugés sur ce langage au moment où j'ai entendu dire qu'il fallait respecter la tabulation pour que le programme fonctionne. Je voyais là le signe d'un langage complètement arriéré, digne des plus beaux langages de grand papa, notamment COBOL qui obligeait à respecter la tabulation, la taille des lignes, des sections particulières...

Comment ce fait-il que des gens aient choisi un tel retour en arrière pour créer ce langage ? En fait, il s'agit surtout d'une incompréhension. La tabulation en elle-même peut être celle que l'on souhaite mais la tabulation sert à définir le début et la fin des blocs de lignes de codes. C'est en fait un moyen astucieux de définir des blocs sans avoir à utiliser de symbole particulier comme { } par exemple :
def fib(n):    # write Fibonacci series up to n
"""Print a Fibonacci series up to n."""
a, b = 0, 1
while a < n:
print a,
a, b = b, a+b
Moins je tape de caractère, mieux je me porte. C'est un principe fondamental de la programmation : le meilleur programme c'est celui qui n'a pas de ligne de code.

Après m'être auto-formé à python, je me suis aperçu que python est aussi souple que mon autre langage de prédilection : Perl. Python comme Perl, centralise les packages disponibles au sein d'un même répertoire appelé PyPI. Sous Perl, c'est le répertoire CPAN.

La différence philosophique entre Perl et Python se situe au niveau des slogans qu'ils utilisent : Perl a choisi le TMTOWTDI (There's more than one way to do it) tandis que Python, justement, est parti sur le slogan "There should not be more than one way to do it". Et finalement, sur le long terme, c'est payant pour Python. Le langage Python reste simple et évite toutes les tortures mentales introduites par Perl. Cela permet à plusieurs programmeurs de travailler sur un même code, la maintenance est facilitée. De plus, quand vous arrêté de faire du perl, ne serait-ce que 6 mois par exemple, vous perdez la connaissance que vous avez des bricolages possibles de Perl, et les détails commencent à vous échapper.

Perl est bien si vous en fait régulièrement, que vos programmes n'ont pas besoin d'une architecture orienté-objet (bien qu'il soit possible de faire de l'orienté-objet avec du Perl, mais c'est vraiment une horreur à écrire).

Perl, par toutes ses particularités et ses bricolages, a permis la constitution d'une communauté soudée, car assez élitiste finalement, Elite dans le sens de : qui maitrise tous les aspects de perl.

Je crois que je vais définitivement arrêter de coder en Perl mes programmes, et passer sur Python parce que je n'ai plus le temps de réapprendre les tortures mentales nécessaire à la programmation en Perl.

lundi 29 novembre 2010

Hypocrisie et gestion de projet

Quel est le plus vieux métier du monde ?

Non, ce n'est pas péripatéticien, c'est le métier de chef de projet. Depuis la nuit des temps, l'Homme a souhaité une vie meilleure, a projeté son être vers un avenir plus radieux, a ambitionné de créer ce qui n'existe pas encore.

Sous un qualificatif pompeux (tout le monde veut être chef à la place du chef aujourd'hui) se cache le métier le plus ingrat qui soit quand on borne sa définition à ce qui se fait dans une société de service par exemple.

En effet, l'intérêt d'un projet est de profiter des biens faits produits par ce projet, soit de façon directe (utilisation des produits et services), soit de façon indirecte (gagner de l'argent sur les bénéfices offerts par les produits du projet)

Un autre intérêt est l'estime de soi, une certaine fierté d'avoir réussi à produire quelque chose de nouveau dans ce monde. Les personnes dont l'égo est habitué à recevoir de tels émoluments seront satisfaites par le simple fait d'avoir terminé un projet.

Dans beaucoup de sociétés, notamment les sociétés de service, chef de projet n'est pas un grade, mais une fonction, au même niveau que développeur débutant, architecte ou expert d'un domaine.

Par définition, un chef de projet est responsable de tout. S'il ne respecte pas ses engagements initiaux, il sera tenu pour responsable et souffrira des conséquences. S'il réussi son projet en temps et en coût, aucun remerciement, aucune gratitude ne sera offert au chef de projet victorieux.


Nombreux sont ceux qui, informaticiens à la base, se dirigent vers la gestion de projet, très souvent leurrés par la dénomination de "chef" quand il faut lire "gestionnaire". L'emprunt d'une telle carrière par une personne de culture scientifique comme l'est l'informaticien peut être semé d'embuches, de désillusions et de déconvenues.

Dans toute société, l'hypocrisie est au cœur du système pour fluidifier, apaiser, permettre les relations interpersonnelles. Ce n'est pas forcément une mauvaise chose que les gens ne disent pas toutes les vérités à tout le monde. Si nous vivions dans un monde sans hypocrisie, le chaos ne serait jamais très loin car plus de rêve ne serait possible, tout le monde serait ramené immédiatement à la raison triomphante, froide, inhumaine.

Dans ce monde du double langage, il est donc important de rappeler quelques règles à suivre quand on est en face de comportements hypocrites, pour que la vérité apparaisse, sans froisser les égos et rompre les communications.

L'article Hypocrisy in Project Management de l'équipe Project Perfect en Australie, analyse justement cette hypocrisie inhérente à toute activité commerciale, donc humaine.

vendredi 28 mai 2010

iPad versus le Livre

Que faudrait-il pour que je me mette à lire la majorité de mes livres sur un iPad ?

Les qualités d'un livre sur papier sont nombreuses :
  • Ultra-résistant : je peux le jeter contre les murs (ça peut arriver si l'auteur méprise le lecteur que je suis), je peux l'emmener à la plage le laisser dans le sable en plein soleil, le tordre dans tous les sens. Le livre a aussi l'avantage de ne jamais tomber en panne et est relativement résistant sur le long terme.
J'ai dans ma bibliothèque le livre Sainte Jeanne de Georges Bernard Shaw. C'est un livre ancien tel qu'on peut maintenant facilement les acheter sur des sites web comme chapitre.com ou abebooks.fr. Ce livre date de 1932 et est toujours aussi lisible qu'à l'époque de son impression. Chez mes parents, j'ai trouvé des livres de poche des années 1960 qui sont, certes, en moins bon état que le "Sainte Jeanne" mais tout aussi lisible.
  • ultra-pratique : ne tombe jamais en panne, n'a pas besoin de pile ou de batterie, je peux passer à n'importe quelle page en un seul et très léger mouvement de doigts. Je peux marquer les pages qui m'intéressent, je peux gribouiller, écrire dessus ou souligner des lignes. Je peux offrir cet objet réel qu'est le livre à une personne et y apposer un petit mot.
  • ultra-plaisant : je peux lire un livre pendant des heures, voire des jours entiers sans avoir mal aux yeux, que ça soit en plein jour et plein soleil ou la nuit, à la lumière d'une lampe de chevet. Un livre de poche pèse dans les 300g je peux le tenir à bout de bras dans tous les sens, il permet une bonne prise en main.
  • très peu cher : un livre de poche ou un livre de taille moyenne est très peu cher. Je peux prêter mon livre à tout ceux que je connais sans qu'ils aient besoin de quoique ce soit. Je peux même revendre mon livre sur amazon ou ebay et rendre ce livre encore moins cher à l'utilisation. Je peux relire le livre autant de fois que je le désire. Je n'ai pas de problème d'obsolescence technologique, je peux donc garder mon livre jusqu'à la fin de ma vie sans avoir peur de ne plus pouvoir le lire.
Si on met en parallèle tous ces avantages, est-ce que l'iPad tiens la comparaison ?
  • résistance : bien que conçu pour être un appareil électronique portable, l'iPad n'est pas conçu comme un PC durci (rugged computer) aux normes militaires par exemple. Je ne vous conseille pas de laisser votre iPad en plein soleil toute une journée sur la plage dans le sable ou encore moins de le laisser tomber régulièrement de vos mains.
  • pratique : les batteries de l'iPad, comme toutes les batteries, finiront par s'user et devront être changée, pour un prix élevé bien sur (car l'utilisateur ne peut pas changer lui même les batteries). Qui dit pile, dit rechargement. Bien qu'il ait une bonne autonomie, (on parle de 10 heures de vidéo ou 140 heures d'audio), c'est toujours très court par rapport à un livre qui a une autonomie aussi longue ... que votre vie !
  • plaisir : j'ai beau avoir essayer tous types d'écrans, quand il s'agit de lire pendant des heures, d'être plongé dans un récit et de ne pas en décrocher, le seul moyen viable est l'utilisation d'un écran non rétro-éclairé. L'éclairage d'un écran, bien que pratique pour l'informatique générale ne permet pas une lecture longue d'un texte. Je peux passer toute ma journée à travailler sur écran, mais l'activité de lecture est différente, elle nécessite de se concentrer sur un espace réduit d'un écran et de faire défiler ses yeux sur des caractères et ce, dans la durée. Lire sur du papier est bien plus plaisant que lire sur un écran rétro-éclairé.
Sur ordinateur, je suis parfois amené à lire de long passages de texte ardus comme des lignes de codes. Je le fais sur un éditeur configuré pour afficher le texte en blanc sur noir, ou plutôt, en saumon clair sur vert foncé. Ce sont les couleurs les plus agréables que j'ai pu trouver pour coder pendant des longues heures. Je ne suis pas sure que l'iPad propose de configurer complètement l'apparence du texte sachant qu'iBookstore contiendra des livres des éditeurs classiques sur papier et que ces derniers imposeront l'apparence de leurs livres.
  • prix : Le modèle économique de l'Apple iPad :
- justifier un prix élevé du produit (il va coûter dans les 500 euros en France) grâce à une marque forte qui flatte l'acheteur (un des ressorts du luxe)

- mettre une taxe à chaque utilisation du produit pour lire un livre, le prêter, etc. La taxe doit être suffisamment faible pour être indolore pour le client. Mais la taxe doit être à tous les niveaux.

Je n'ai pour le moment pas trouvé beaucoup de livres sur l'iBookstore mais ça peut s'arranger avec le temps. Je n'ai vu que des livres gratuits où valant 0,99$ :

Alice au pays des merveilles

Twilight

Je ne pense pas que ça soit le prix de base des livres de qualités qui pourront être mis dans l'iPad. Les éditeurs pourront faire des économies de papier, mais pas de distribution : au lieu que ce soit les distributeurs traditionnels qui se sucrent sur les prix des livres, ce sera Apple. Un livre de poche aujourd'hui vaut entre 2 et 7 euros. La différence ne sera jamais très grande entre le prix d'un livre sur iPad et le prix d'un livre papier.

De plus, comment faire pour prêter un livre sous iPad ? et comment revendre un livre ?

En bref : l'iPad est moins intéressant sur toutes les caractéristiques d'un livre papier. Mais il y a quand même des éléments intéressants pour certaines personnes (pas moi, malheureusement) :


Avec un iPad, vous pouvez lire dans le noir complet, vu que c'est rétro-éclairé. Personnellement, je me vois mal lire dans le noir complet.

Avec l'iPad vous pouvez avoir pleins de livres sous la main, disponibles en 1 seul clic. Personnellement, je ne lis au maximum que 2 ou 3 livres en parallèle, et les mettre dans un sac n'est pas un surpoids énorme quand je pars en voyage. En général je ne lis qu'un livre à la fois. L'argument comme quoi on a plus besoin d'avoir une énorme bibliothèque chez soi ne me convainc pas : avoir une bibliothèque ne me gène pas, cela me permet de revoir en quelques coups d'œil l'ensemble de me livres.

Avec l'iPad, il est beaucoup moins cher d'avoir des livres en couleur. Cela est intéressant quand on veut lire des bandes dessinées. Mais quand il s'agit de "beaux livres" d'art, une reproduction sur papier est bien plus belle et précise qu'une reproduction sur un écran rétro-éclairé.

Pour que l'iPad devienne plus intéressant face aux livres, il faudrait :
  • mettre suffisamment de cellules photovoltaïques pour permettre de fonctionner sans batteries... mais ça semble assez difficile vu la taille de l'objet.
  • durcir l'objet aux normes militaires : avec de telles normes, on a plus du tout peur de casser ou d'emporter son iPad n'importe où.
  • permettre des hyperliens directs vers toutes les références citées. Mais là encore, si tout est payant dans le monde iPad, sauter de référence en référence signifie sauter de livre en livre, donc de taxe en taxe. On n'est plus dans un modèle gratuit du web mais dans un modèle de contenu payant. ça peut être intéressant pour des chercheurs, ou autres étudiants, mais pas pour le lecteur de base que je suis.
  • permettre un modèle économique similaire au livre : achat / prêt / revente.
A noter aussi que l'iPad n'est en rien une nouveauté, et qu'il existe de nombreux concurrents : on se demande d'ailleurs ce que fait le CSA car tous les médias parlent d'Apple comme si c'était un phénomène unique, alors que de nombreuses autres marques existent. Je pensais qu'il était interdit de citer des marques pendant les émissions ?

vendredi 9 avril 2010

Règles pour le Codage

Ce que je trouve très intéressant dans un livre technique c'est quand celui-ci liste explicitement de "bonnes pratiques" que l'on sent sortir tout droit de l'expérience de l'écrivain.

L'œuvre majeure dans ce domaine est bien sur Code Complete 2 mais je suis tombé sur une page Web contenant une liste très intéressante, tirée du livre Programming Pearls.

Il s'agit de l'Annexe 4 : Rule for Coding qui est une retranscription d'une liste que l'auteur, Jon Bentley, avait constitué en 1982 dans son livre "Writing Efficient Programs". Oui, 1982 !!! et toutes ces pratiques sont toujours valides. Qui peut se targuer d'une telle longévité de ses conseils en matière informatique ?

Quand vous lirez ces règles, vous vous direz certainement que c'est évident, que vous mettez déjà en pratique ce genre d'heuristiques programmatoires. Oui, mais Jon Bentley a réussi à mettre des noms aux activités que nous menons tous les jours quand nous programmons. Comme dirait le poète, une chose n'existe pas si elle n'a pas de nom. Mettre des noms à tous les aspects de l'activité de programmation sert à faire reconnaitre le véritable travail qui est effectué. Sans cela, la programmation, pour le non-informaticien reste du ressort de la magie.

Aujourd'hui, 2010, le problème n'est plus vraiment de ressortir toutes ces "bonnes pratiques", toutes ces règles. La difficulté réside dans l'application systématique de ces règles. Comment faire pour que tous les programmeurs d'un projet de développement logiciel connaissent, utilisent, appliquent toutes ces règles de façon exhaustive ? Comment, au niveau de l'activité d'assurance qualité, vérifier l'application complète de ces règles pour l'ensemble de code concerné sans devenir un tortionnaire envers ceux qui programment ?

La programmation se base sur le mécanisme d'abstraction pour permettre de construire des systèmes complexes et gérables par des êtres humains. Or le revers de la médaille "abstraction" est le fait que chaque programmeur peut cacher l'implémentation d'une fonction sous des aspects de code fonctionnant correctement.

Le meilleur moyen pour qu'un programmeur mette en œuvre les règles et les bonnes pratiques est de lui fournir des outils lui permettant de tester par lui-même la qualité de son code. Car, comme l'optimisation est la cause de tout mal en se bas-monde, il faut optimiser, et donc essayer d'appliquer les règles explicitement que si on constate un problème de performance. Il est donc utile de repérer dès la conception de l'architecture les points clés dont dépendent les performances attendue. La qualité de tous ces points clés doit être soigneusement vérifiée.

Ainsi, lors de la façon de définition de l'architecture, il faut non seulement définir les éléments statiques, dynamique et l'allocation des ressources matérielle, mais en plus, identifier les éléments critiques en terme de performance.

mercredi 17 mars 2010

Ecran mat ou brillant ?

Je me suis toujours demandé pour quelle raison la tendance actuelle est de vendre des écrans brillants plutôt que des écrans mats. Les écrans brillants reflètent toutes les sources de lumière et rend très désagréable le travail sous des néons (cas très courant faut-il le rappeler).

Je ne suis pas sure que le coût soit véritablement différent à la production entre un écran brillant et un écran mat. Peut-être que les gens achètent plus des écrans brillants parce que "ça en jette". Personnellement, autour de moi, la plupart des personnes préfèrent des écrans mats.

C'est d'ailleurs aussi la préférence de AnandTech dans leur revue du Netbook Asus Eee PC 1001P :
"The screen also has a matte finish, thankfully one of the few computers to forego the trend of featuring a glossy screen." (L'écran a aussi une finition mate, heureusement l'un des rares ordinateurs à renoncer à la tendance à faire figurer des écrans brillants).
Ce nouveau Eee PC a un écran vraiment incroyable à en croire les performances mesurées :


Assurément un des meilleurs netbook du moment...

mercredi 17 février 2010

Microsoft, l'anti-pattern économique

A tout ceux qui voit en Microsoft un exemple à suivre, un modèle d'entreprise, à tout ceux qui croit que Microsoft a des clients parce qu'il a de bons produits, je recommande la lecture de deux graphiques :
Où on apprend entre autres choses le coût d'achat d'un point de marché des moteurs de recherche (bing) : 667 millions de $ et que perdre 2 milliards de $ par an pour un produit qui ne marche pas n'est pas un problème pour Microsoft.

Quand Microsoft génère autant d'argent de son Trust Windows/Office, il plonge allégrement dans l'irréalisme économique. Microsoft semble vraiment incapable de faire du business rentable sur internet.

samedi 16 janvier 2010

Déplacement de code invariant de boucle

L’optimisation de code est un vaste sujet, car il s’agit plus d’un art que d’une théorie axiomisée. Elle n’est que la conséquence des limitations auxquelles sont confrontés les informaticiens.

Il est bien connu que l’optimisation prématurée est la source de tous les malheurs, mais il est quand même recommandé de connaître les limites des outils et langages que l’on utilise pour pouvoir coder juste au premier coup.

Avec les RIA, ils est maintenant nécessaire d’écrire des portions de code relativement importantes en Javascript alors que ce langage n’était prévu à l’origine que pour dynamiser un peu les pages Web statiques.

Javascript n’a pas été conçu pour réaliser des optimisations de code en amont de son exécution comme pourrait le faire un compilateur C ou Java. Une des optimisations à faire absolument est le déplacement du code invariant de boucleLoop-invariant code motion »).

Par exemple si vous avez du code comme ça :
for (i = 0; i < n; ++i) {
x = y + z;
a[i] = 6 * i + x * x;
}
Alors il vaut mieux le réécrire comme ci-dessous sous peine de laisser l’interpréteur Javascript recalculer à chaque itération des valeurs invariantes :
x = y + z;
t1 = x * x;
for (i = 0; i < n; ++i) {
a[i] = 6 * i + t1;
}
Ce genre d’optimisation est généralement bien réalisé par les compilateurs C ou Java mais Javascript n’a pas ce genre d’intelligence. Le déplacement de code invariant de boucle est une des optimisations préconisées par Jon Bentley dans Programming Pearls, livre O combien recommandé dans ce domaine.

lundi 11 janvier 2010

Répertoire de sons pour vos homebrew...

Je surfais par hasard sur la toile, à la recherche de sons gratuitement réutilisable pour une création multimedia sur Nintendo DS.

Je suis tombé sur ce répertoire de liens vers des sites collection de sons divers et variés.

C'est un bon point de départ pour ceux qui font du homebrew sur Nintendo DS ou autre, et qui cherche des sons réutilisable sans frais.