Affichage des articles dont le libellé est pro. Afficher tous les articles
Affichage des articles dont le libellé est pro. Afficher tous les articles

lundi 28 septembre 2009

Septembre 2009

Intro : J'ai décidément du mal à tenir ce blog à jour... Pourtant, il y a bien des sujets dont je souhaiterais parler ici ; mais entre les articles demandant trop d'investissement en temps et ceux qui seraient trop courts, au final, je ne publie pas. Donc j'ai décidé de me lancer dans une série mensuelle, listant rapidement des petites choses intéressantes, tout domaine confondu (enfin, surtout ceux habituellement traités ici...). En espérant donner un petit coup de fouet à ce blog qui refuse de mourir.

Logiciels :

Découvert au taf, Launchy est un petit lanceur d'application bien sympathique, disponible sous Windows et Linux. Très pratique (et libre).

M'étant mis tout récemment à la musique assistée par ordinateur (voir plus bas), je vous conseille Audacity (libre et multi-plateforme) que je découvre pour tout ce qui est enregistrement et montage audio. J'avoue que j'ai toujours eu peur des logiciels de MAO à cause de la complexité de certaines références (genre Cubase), mais là ça se présente de manière plutôt simple, même s'il faut creuser un peu pour certaines fonctionalités.

Enfin, j'ai récemment commencé à utiliser Eclipse au travail... Contre toute attente, je sens que ce soft va me réconcilier avec les IDE : bien que lourd, il fait un nombre de tâches hallucinant et facilite vraiment la vie du développeur sur pas mal de points assez peu intéressants (conventions syntaxiques, intégration du gestionnaire de configuration, génération automatique de méthode, commentaires, détection d'erreurs en live, etc...). J'ai sans doute l'air de découvrir la roue, mais bon... quand ça tourne bien, faut pas bouder son plaisir.


Musique

Certains le savent, d'autres non. Je suis un gros fan de Blues, et je joue depuis "presque" un an de l'harmonica diatonique (blues harp donc). Comme je l'avais déjà dit ici, je pense que ce sujet est un peu loin des thématiques habituelles de ce blog, et donc j'en parle chez Lefty.
Notamment ce mois-ci : un article sur une compilation de Blues très bien foutue pour ceux qui veulent découvrir, et un premier essai d'enregistrement avec Lefty à la gratte (d'où l'utilisation d'Audacity).


Pro

Suite à la fin de ma mission précédente, j'ai enchainé cet été sur un nouveau truc en... Java. Et plus précisément en Java3D.
Ce nouveau job me plait beaucoup, en bonne partie parce que j'apprends énormément de choses nouvelles, et que l'environnement est assez différent de mes expériences précédentes.
D'abord le domaine de la géométrie algorithmique (que je connaissais déjà dans un contexte de calcul scientifique/modélisation mathématique) qui est bigrement intéressant. Pour l'occasion, je me suis d'ailleurs (enfin) payé le Computational Geometry (de Berg - Cheong - van Kreveld - Overmars) que je ne saurais que trop conseiller à ceux qui s'intéressent à ces problématiques (attention cependant, il n'existe pas de traduction).
Ensuite, l'environnement très libre/open source : même si c'est en bonne partie des outils classiques de développement en Java, c'est toujours agréable de bosser avec des choses comme Eclipse (voir plus haut), Ant, TestNG, SVN, TRAC, plein de bibliothèques libres, etc... (plutôt que Visual Toto, des scripts batch halakon, des outils de test et des libs internes foireux, Clearcase et Rhapsody...). Ah oui, et un wiki pour la doc : si c'est pas cool ça...
Bon, et le Java, c'est pas si terrible.


IoGraphViz := Io + GraphViz

Comme je voulais depuis longtemps m'investir dans un vrai projet libre, et qu'en parallèle je voulais me pencher plus sérieusement sur le langage Io, je me suis lancé dans le projet IoGraphViz.
Il s'agit d'un binding, pour le langage Io, de l'outil de génération de graphes GraphViz. Il n'est pas encore stable/mature, mais j'espère sortir assez rapidement une première version fonctionelle. Pour l'instant je me base fortement sur l'équivalent en Ruby : RubyGraphViz, mais je compte diverger de plus en plus de ce (très bon) point de départ.
Ce qui est intéressant en se lançant dans ce genre de projet, c'est que ça implique de nombreuses contraintes qui sont assez formatrices :

  • Mieux maitriser le(s) langage(s) utilisé(s) bien sûr
  • Héberger son projet/maitriser un gestionnaire de configuration et/ou de version (dans mon cas, je me suis mis à Git via Github - sous Windows, c'est pas de la tarte au début mais on s'en sort...)
  • Et surtout rechercher toutes ces petites choses auxquelles on ne pense pas : de la doc sur des points ultra pointus, un générateur de documentation, tests unitaires, etc...


Je compte faire un vrai article d'introduction (in English if you please...) à la lib quand elle sera présentable.


Curiosités du web

International Dialects of English Archive propose des petits fichiers audio à l'écoute illustrant les accents (en anglais) de gens des quatre coins du monde. Amusant et pratique pour bosser son oreille.

Journée Mondiale présente une liste (non exhaustive mais impressionante) des journées mondiales/internationales/européennes/nationales de... tout et n'importe quoi (genre là on est entre la Journée Européenne des Langues et la Journée Mondiale de la Surdité... touss touss).

Buzzerl : un reddit pas bien, fait par des gens biens, utilisé par des gens biens et des gens pas biens (en Erlang).

vendredi 10 juillet 2009

Fin de projet SCADE

La fin d'une mission, ou d'un projet, c'est toujours une bonne occasion de faire le point. Je viens de terminer tout récemment une mission de quelques mois en tant que développeur logiciel, en SCADE, pour un système embarqué sur avion. Cette mission a été plutôt enrichissante sur plusieurs points.



SCADE

SCADE est un environnement de développement propriétaire édité par Esterel, et basé sur le langage Lustre. Il cible principalement les applications dites "critiques", dans des domaines divers comme le ferroviaire, le nucléaire, le spatial... et bien sûr l'aéronautique.
Ce que les gens du milieu appellent un peu pompeusement de la "spécification formelle", j'aurais tendance à l'appeler du "codage graphique" (pour un certain nombre de raisons, les ingénieurs systèmes apprécient peu le terme "code"...). En effet il s'agit ici non pas de coder avec des fichiers textes, mais directement avec une représentation graphique (c'est cette représentation, qui se veut le pendant visuel de la spécification textuelle, que d'aucun nomme la "spécification formelle"). Par la suite, cette représentation graphique est convertie en langage Lustre (langage de programmation textuel, "classique"), celui-ci étant à son tour interprété afin de générer le code C (ou Ada, au choix) qui sera finalement executé sur cible.

Alors en pratique, à quoi ça ressemble ? Pour des raisons évidentes de confidentialité, je n'ai pas d'images de mon projet sous la main, mais en gros c'est un espèce d'hybride entre des représentations de fonctions logiques (notation américaine), de machines à état, et de certains schémas UML. Un exemple de chez Esterel ici (machine à état en haut,"workflow" en bas).

N'ayant jamais utilisé ce type d'outil avant, j'avoue que l'adaptation se fait assez rapidement, même si certains aspects restent déroutants (la représentation des machines à états est à mon avis assez peu intuitive par exemple), et si certains côtés sont un peu frustrants (gestion des types...).
Par contre, clairement l'outil possède des avantages sur du codage manuel normal :
  • Tout l'aspect concurrent et synchrone est épargné au développeur, évitant de nombreuses erreurs
  • Abstraction également de la gestion de la mémoire (ce qui n'est bien sûr pas le cas en C ou en Ada - de longues heures de debug gagnées...)
  • Représentation du code sous une forme lisible par quelqu'un ne sachant pas coder (un ingénieur système par exemple)
  • Annulation du besoin de vérification manuelle sur de nombreux points (revue du code généré notamment)

DO-178B

C'est mon second projet dans ce que les commerciaux aiment appeler "un contexte de DO-178B". En pratique, la DO-178B, est une norme aéronautique pour le développement d'applications critiques (le plus souvent embarquées sur avion). C'est une norme très sévère qui imposent de nombreuses règles pour la conception et le développement logiciel. Notamment :

  • La gestion de configuration obligatoire
  • La traçabilité "parfaite" entre les spécification et le code
  • Les différents aspects de la validation et vérification (revue de code, indépendance entre le codeur et le testeur, couverture des tests...)
Bizarrement, on s'habitue... Quand j'ai découvert cette norme, j'ai plus eu l'impression de la subir que d'en profiter, mais là, ayant participé à la mise en place du process de validation (l'ensemble des règles et documents pour les tests, entre autres), je dois avouer que travailler dans un cadre très strict a ses avantages. De bonnes pratiques sont obligatoires au niveau de la traçabilité par exemple : "Quel bout de code correspond à une spec donnée ?". Ou encore : "Jusqu'à quel point dois-je tester mes fonctions ?", etc...


Au niveau dev...

C'est la première fois que je me retrouvais seul, en milieu pro, à prendre en charge le développement complet d'un soft. C'est un peu flippant au début, surtout quand on a été habitué à avoir des gars très bons techniquement à côté de soi, mais c'est aussi extrêmement enrichissant.
En particulier, le fait de devoir faire soi-même des choix au niveau de l'architecture du logiciel, des conventions techniques, du design, etc... c'est l'une des parties les plus intéressantes du développement (l'implémentation est sympa aussi, hein !).

Sans trop rentrer dans les détails techniques (qui seraient de toute façon une redite de pas mal de principes de base de conception logicielle), voici ce que j'en ai retenu :
  • Les spécifications, quand elles sont écrites par quelqu'un d'autre qu'un codeur, sont forcément en décalage par rapport aux réels besoins, et par rapport à leur mise en oeuvre. Ce qui veut dire que celui qui code doit participer, et influencer au maximum cette phase de spécification. En gros : participer à cette expression des besoins plutôt que la subir ensuite.
  • Avant même de réfléchir à la façon d'implémenter les fonctions demandées, identifier les problèmes à venir, d'un point de vue software (pas d'un point de vue système, ou métier), qui se posent et proposer une solution. Par exemple dans mon cas : grand nombre de variables en entrée et en sortie => création de façades ; uniquement des variables booléennes => créations de types structurés utilisés dans les interfaces de chaque fonction ; besoin temporaire de certains modes de fonctionnement => design pattern Strategy (non, il n'y a pas de POO dans SCADE, pour autant ça reste applicable) et séggrégation des fonctions par mode ; etc...
  • Essayer de piquer les bonnes pratiques des langages modernes et/ou fonctionnels : pas de variables globales, éviter tant que possible les effets de bord, composer ses fonctions, etc...
  • Le typage, c'est la vie.
  • Communiquer au maximum : "Mon code est dans tel état là, maintenant.", "Telle partie sera disponible le tant.", "On va avoir des problèmes à tel niveau sur telle spec.", "Je suis en retard par rapport au planning à cause de tel problème.", etc... et de façon systématique et quotidienne. Cela permet d'éviter bien des mauvaises surprises.
  • Séparer ce qui change de ce qui ne change pas (formulation honteusement pompé à Russ Olsen)
  • Et les classiques : KISS, DRY, YAGNI, etc...

credits : photo de nacelle par Eric E Johnson

mardi 24 février 2009

Diffusion du libre

Je ne sais pas si c'est une fausse impression de ma part, mais j'ai l'impression que la notion de logiciel libre est plus connue et mieux comprise par le grand public qu'il y a quelques années. Bien sûr, il reste du chemin à parcourir et de la "propagande" à faire, mais il me semble qu'il y a évolution (même si "libre" reste trop souvent synonyme de "gratuit").
Essayons de synthétiser les vecteurs de cette évolution, ou du moins, les facteurs contribuant le plus significativement à la propagation de la "culture libre" (au sens plus large qu'uniquement logicielle).

Vecteurs de diffusion de la "culture libre"

Bon, je passe sur Internet. C'est évidemment la clef de la naissance, l'évolution et la réussite du libre, depuis le départ. D'ailleurs, Internet et le web sont construits principalement sur des technologies (et des principes) libres ou du moins ouvertes : HTTP(S), SSH, CGI, FTP, Javascript, PHP, etc... (certes, il y a aussi le Flash...).

La fondation Mozilla, via Firefox a été et reste un acteur très important de propagation du libre. Même si la fondation est assez souvent critiquée par la communauté du libre, pour des raisons aussi diverses que de validité variable, elle mérite que l'on reconnaisse le bénéfice de ses actions.
D'abord Firefox est un bon à très bon produit, surtout comparativement à Internet Explorer. Pour autant, je ne pense pas que ce soit le logiciel libre le plus répandu auprès du grand public (les chiffres me manquent pour vérifier ça : si quelqu'un connaît une bonne source de statistiques à propos du libre, je suis preneur) : d'une part, Internet Explorer est encore majoritaire en terme de visites web, et d'autre part, on a tendance à oublier pas mal de programmes, énormément employés (en bonne partie de par leur gratuité) : VLC, eMule, Vuze (anciennement Azureus), The Gimp ou Java... La différence avec ces logiciels, est que Mozilla met largement en avant le côté libre de Firefox (et de ses autres produits), ce qui n'est pas le cas sur ces autres. C'est assez similaire sur la suite OpenOffice de Sun : le côté libre/open source est souvent souligné dans les pubs.

Wikipédia a, je pense, indirectement, mais fortement, contribué à diffuser la culture libre. Le principe d'encyclopédie collaborative est bien connue du public. Le droit de réutilisation du contenu est également bien admis (bien que les conditions de rediffusion imposées par la license de documentation libre GNU (GFDL) le soient nettement moins...). Sur les principes, le logiciel libre et les règles de Wikipédia sont très proches : tout le monde peut participer/contribuer, réutiliser, diffuser, etc... C'est en bonne partie Wikipédia qui fait connaître les licences Creatives Commons via Wikimedia Commons (de plus en plus de sites les mettent en avant cependant, comme Flickr récemment). Ces principes étant compris pour l'encyclopédie, ils deviennent plus clairs lorsqu'ils sont expliqués pour les logiciels.
Par ailleurs, la communauté libre utilisant Wikipédia de façon soutenue, les projets libres sont souvent mis en avant dans les articles du site (parfois de manière subjective et un peu pénible d'ailleurs : je ne pense pas qu'on ait besoin de ça...), ce qui permet une certaine forme de publicité : la pub par la doc (un logiciel (ou autre d'ailleurs) existe-t-il vraiment s'il n'a pas d'article sur Wikipédia ?).

Ensuite, phénomène commercial plus récent, l'apparition des netbooks ou ultra-portables a contribué à faire connaître le logiciel libre et surtout Linux (pas forcément en bien cependant) à un public de néophytes (à commencer par les vendeurs informatiques eux-mêmes...). Je ne suis pas persuadé que les gens aient bien compris la notion de logiciel libre en achetant un eeePC sous Xandros, mais ils ont au moins compris la différence de prix avec Windows... c'est déjà ça (c'est l'argument principal de vente de Linux, hormis la moindre consommation mémoire par rapport à Vista ou même XP).
Par contre, j'ai des doutes plus que prononcés sur l'efficacité de la "pub" des netbooks pour Linux. En effet, les 2 distributions majeures sur ces machines (majeures car les plus "vendues") sont Xandros (eeePC) et Linpus Linux (Acer Aspire One) : ces 2 distros sont... nazes. Bloquées, interfaces trop simplifiées, modification constructeur de packages "basiques" (sous Linpus : Firefox, Pidgin notamment...)... Bref, je les trouve extrêment mauvaises, assez loin de l'esprit de départ de Linux, et forcément décevantes pour le grand public issu de Windows XP. Il y a cependant des exception comme la Suse SLED sur le MSI Wind par exemple, ou d'autres sous Xubuntu.
Il faut par contre noter que l'apparition de ces machines a pas mal boosté la communauté et les entreprises sur le développement, la relance, ou l'adaptation de distros adaptées : gOS, Xubuntu (mon choix sur Aspire One A150 : XFCE devrait vraiment être relancé par les netbooks), Ubuntu Netbook Remix, Joli Cloud (à venir ?), Android (pas mal de boulot a été fait pour récupérer le dev effectué pour les OS de mobiles ou PDA)... plus l'adaptation matos pour les "grandes" distributions existantes : OpenSuse, Ubuntu, Mandriva, etc...
Je suis mal renseigné sur les BSD, mais il serait intéressant de savoir comment ces communautés ont réagi par rapport à ces nouvelles machines.

Bien sûr, il serait injuste de ne pas parler ici du travail constant fait par la communauté dans son ensemble : développement bien sûr, mais aussi et surtout : rencontres, stands, aide, forums, install parties, propagande, pétitions, etc... C'est un boulot souvent ingrat, faut reconnaître le mérite des gars et des gyals qui font ça (bénévolement en général, rappelons-le).
C'est aussi eux qui diffusent l'information lorsque le logiciel libre est adopté par une grande entreprise ou mieux, par une administration de l'état : c'est souvent un bon coup de pub pour le libre.
Plus méchant, les procès contre les entreprises ne respectant pas les licences libres (en France on a eu Free notamment pour du soft intégré dans la Freebox si je me souviens bien) ou contre les monopoles (Microsoft, bien souvent... mais bientôt Google probablement) font parler du libre, et sont toujours une occasion d'expliquer les fondamentaux.

Cela dit, tous ces facteurs doivent, selon moi, à terme devenir de moins en moins significatifs. Même la partie "éthique" du LL passe, à mon avis, au second plan derrière la qualité logicielle. Je ne parle pas ici d'une quelconque norme industrielle bancale : je parle simplement du fait que de par leur nature, les projets libres, ou open sources (sous réserve d'être suffisament "importants") doivent logiquement être d'une qualité supérieure à leurs homologues propriétaires (et à fortiori freewares). Cela peut se constater déjà sur de nombreux exemples : Firefox est probablement le meilleurs navigateur web actuellement (même si Opéra ou Chrome se défendent), la JVM est toujours probablement la meilleure machine virtuelle sur le marché (depar sa portabilité : faut se méfier de .Net sur d'autres aspects...), les langages libres sont systématiquement meilleurs que leurs homologues propriétaires (troll ?), OpenOffice arrive petit à petit au niveau d'offre de Microsoft Office, en science de nombreuses libs sous GPL ou autre dominent l'écosystème (Lapack entre autres...), Linux (troll ?), etc... Je n'ai pas parlé ici des domaines que je connais mal comme le P2P ou la messagerie instantanée où il y aurait des choses à dire...
C'est à mon avis sur ce point qu'il faut appuyer encore et toujours pour convaincre. Il faut croire que Microsoft a droit à l'erreur avec Vista, les migrations d'OS ayant surtout profité à Mac OS et à... Windows XP (!), mais dans le libre, un nouvel utilisateur déçu, c'est un utilisateur perdu ad vitam aeternam. Au boulot ! ^^


Notes :
Je comptais initialement faire un article pour présenter quelques logiciels libres que je considère comme étant injustement méconnus du grand public (Thunderbird, Pidgin, Sage et Freemind probablement). M'étant un peu enflammer sur la diffusion du LL, j'ai pas envie de coller le reste à la fin, ça viendra dans un prochain article.

Je ne prétends aucunement faire autorité sur les questions évoquées ci-dessus (même si mon "style", je m'en rends compte et m'en excuse, peut le laisser penser) : c'est plus un avis personnel, pour invitation à la réflexion et à la discussion sur ces sujets (les commentaires sont grand-ouverts).


Crédit images, par ordre d'apparition : libre.taxi par Gabriel Juan (utilisation commerciale interdite),

mardi 8 juillet 2008

Règles de codage, mes amours

Il n'est pas rare d'avoir quelques règles de codage dictées lors du développement d'un programme dans une entreprise, ou dans un projet en général. En soi, c'est plutôt bien, ça rend souvent le code plus homogène, lisible ou maintenable. Certaines règles se justifient pour les besoins de performances, de documentation ou de fiabilité. Mais parfois...


  • Pas de ligne de plus de 131 caractères. Moral, mais pourquoi pas 132 ou 130 ?
  • Minimiser les boucles, mais maximiser leur portée. Hein ?
  • Pas d'identifieur (nom de classe, variable ou package) de plus de 31 caractères. Si ça parait évident, attendez de voir la suivante... (et celle d'après !)
  • Les noms des identifieurs doivent être clairs et représenter l'objet identifié. Par exemple, "Initialize_Space_Craft_With_One_Pilot" et non pas "Init_SC_with1_pilot". Hahahaha !!!
  • Interdiction d'utiliser use. RHAHahahaha... BANG!
  • Pas d'appel récursif. Boom.
  • Pas de condition IF sans ELSE. Peut se justifier par des raisons de fiabilité (le codeur a effectivement envisagé le cas contraire et écrit exlicitement null, avec commentaires dans le ELSE).
  • Dans les CASE-WHEN, interdiction d'utiliser when others. Moral pour la fiabilité (Ada95 plante si l'on omet un cas possible), parfois très pénible en pratique (heureusement que l'Ada admet les OR dans les CASE, parce qu'avec des litéraux de 15 à 20 entrées...).
  • Les variables doivent être déclarées dans l'ordre d'apparition dans le code. Dumbest rule ever.
J'en passe et des meilleures. L'important est surtout de mettre au point ces normes avant de commencer l'implémentation... Dommage pour certains, pas vrai ?

Mais quelles sont les règles de codage indispensables en réalité ? Celles qui apportent effectivement la lisibilité, la fiabilité et la maintenabilité ?

samedi 7 juin 2008

Ruby Duck-Safe interface

Suite à un précédent article sur DiamondBack Ruby, j'ai un peu réfléchis à la question de la sécurisation de l'appel de fonctions/procédures/méthodes, au niveau des types dans un langage dynamique tel que Ruby (/Python,/Perl/Etc...).

Finalement, quel est le problème ? Quelque soit le paradigme, il se situe au niveau de la capacité d'une fonction/procédure/méthode à traiter ses arguments en fonction de leur type, classe ou comportement. Problème simple donc. (Les aspects plus bas niveau sont ici peu intéressants : on est actuellement capables de les éluder).

Tout est dans la notion d'interface : dans les langages statiques, une interface n'est pas seulement un moyen d'appeler un "service" (fonction/méthode/...) mais c'est également un "contrat" qui impose des conditions sur les informations passées à l'appel (le plus souvent sur leur type). Par exemple, la fonction acheter_une_baguette ne peut se contenter de prendre 0.45 en argument : il faut que 0.45 soit en €, "de type €".

Ruby est un langage dynamique comme tant d'autres. Mais de par sa conception, sa "philosophie", il fait le choix de se concentrer sur ce que fait un objet plutôt que sur ce qu'il est : c'est le Duck Typing. On peut facilement critiquer cette approche du typage pour plusieurs raisons. Cet article sur Otaku en expose plusieurs. Pour ma part, je me contenterais de dire qu'elle réside dangereusement sur la langue (quel rapport entre Balançoire.balancer et Coupable.balancer ?).

Mais les langages statiques ne sont pas nécessairement satisfaisants sur ce point non plus. Pour faire un parallèle avec les mathématiques, on peut considérer que :

f : R -> R
x |-> x + 2

avec R l'ensemble des réels, est une déclaration de type statique.

Pour autant, f reste valable de N dans N (naturels), de C dans C (complexes), etc... Le Duck Typing assure que f est valable du moment que x possède une méthode "+", ce qui évite de redéfinir f pour chaque espace où cette fonction est valable.

Mais est-ce suffisant ? Prenons :

f : x |-> 2 / x

Dans ce cas, on doit de plus assurer que x n'est pas nul. Si mathématiquement, cela s'exprime sur l'espace sur lequel est défini x, "informatiquement" on aura le plus souvent x entier ou flottant. Les contraintes sur un argument ne se limite donc pas à son type/classe, ni à son comportement (possède méthode "+"), mais aussi à d'autres paramètres, comme son état (ici sa valeur). De plus, s'il s'agit ici d'un exemple simple : il existe probablement d'autres exemples mettant en évidence l'influence du contexte d'appel.

Je vous propose ici un module (naïf) permettant d'exprimer assez simplement, lors de l'implémentation d'une méthode, les contraintes associées à ses arguments. Le but est d'assurer ces contraintes sans pour autant surcharger le code de structures conditionnelles avec gestion d'exceptions : on déclare simplement notre contrat.

(sources également disponibles **sans fuck1n' coupure** ICI)

module Safety

# Negator for error message
@@neg_converter = {:is_a? => "is not a",
:respond_to? => "does not respond to",
:include? => "does not include",
:each_element_is_a? => "contains element(s) that is(are) not"}

# Ensure that constraints are respected
def ensure_it cstr
cstr.each do |arg, cstrs|
value = cstrs[0]
cstrs[1...cstrs.size].each do |pair|
if not value.method(pair[0]).call(pair[1]) then
raise "Argument #{arg} (#{value.inspect}) \
#{@@neg_converter[pair[0].to_sym]} #{pair[1]}."
end
end
end
end

private

# A simple example of constraint method
def each_element_is_a? klass
assertion = true
self.each do |elt|
assertion = false if not elt.is_a? klass
end
assertion
end

end


La méthode ensure_it checke les contraintes passées. Une contrainte est facilement exprimable par une méthode telle que each_element_is_a?.

Exemples :


require 'Safety'

class Fixnum
include Safety
def mult_by_plus num1, num2
ensure_it({:num1 => [num1, [:is_a?, Fixnum]],
:num2 => [num2, [:respond_to?, :next]]})
self*num1+num2
end

end

a = 1
puts a.mult_by_plus(1,2)
puts a.mult_by_plus(1,1)
puts a.mult_by_plus(1,1.0) #=> Error raised


Et :


require 'Safety'

include Safety

def potamok tab
ensure_it({:tab => [tab, [:respond_to?, :each],
[:each_element_is_a?, Fixnum]]})
val = 0
tab.each do |elt|
val += elt**2
end
val
end

puts potamok [42,33,59]
puts potamok [1,2,3,6,59.3] #=> Error raised


Toute remarque est la bienvenue.

mercredi 23 avril 2008

Ruby : Sécuriser la redéfinition de méthode

Etant un peu angoissé de nature, il y a un truc qui me tracasse en Ruby depuis quelques temps : l'absence de warning à la redéfinition de méthodes existantes. Un exemple ?




class Object
def self.new
puts "Oh dude !"
end
end

a = Array.new 46
#=> **Judgement Day**


Ceci devrait bien vous convaincre de l'utilité d'avertir le programmeur durant le développement. Rappelons aussi que Object.methods dénombre 77 méthodes pour cette racine de tout objet en Ruby...

Du coup, voilà un petit trick qui permet de sécuriser ce point, grâce à la méthode de classe method_added :


class Object
def self.method_added sym
if self.methods.include? sym.to_s then
print "WARNING: method #{sym}" + \\
"of class #{self} redefined\n"

end
end
end

class Integer
def clone
puts "I'm your dark twin !"
end
end
#=> WARNING: method clone of class Integer redefined

mercredi 2 avril 2008

Une classe pour une fonction

Une petite idée comme ça : plutôt que d'appeler directement une fonction, comme ici (loi des gaz parfaits) :

def compute_p v, n, t
r = 8.314
p = (n*r*t)/v
return p
end
puts "p = #{compute_p(1.0, 10.0, 273.5)}"


Pourquoi ne pas créer une classe, représentant cette fonction ? En effet, on peut alors définir un certain nombre d'options à l'exécution "internes" à notre fonction (ici, j'ai mis des exemples simples : print pour un affichage console, et clock pour retarder l'exécution d'un temps donné). On pourrait aussi sécuriser les arguments (non fait ici...) par rapport à des contraintes internes à la classe (ex : température > 0, autre ?) ou décider de remplacer certains arguments sous certaines conditions, éventuellement externes. Et bien d'autres choses, pour des problématiques concurrentielles... Des idées ?


class Compute_p_class

# Initializing the arguments as attributes
def initialize args
@v = args[:v]
@n = args[:n]
@t = args[:t]
@@r = 8.314
@opt = []
@opt_args = {}
end


# To add an option at execution
def add_option option, argopt = nil
@opt.push option
@opt_args[option] = argopt
end

# Wait for @opt_args[:clock] s before executing
def option_clock
t_beg = Time.now
t = t_beg
if @opt.include? :clock then
while t < t_beg + @opt_args[:clock]
t = Time.now
end
end
end

# Verbose-like
def option_print
if @opt.include? :print then
puts "Executing function Compute_p"
puts "with arguments"
puts "v = #{@v}"
puts "n = #{@n}"
puts "t = #{@t}"
end
end

# Execution after options
def execute
# Options management
option_print
option_clock
# Function core
p = (@n*@@r*@t)/@v
return p
end
end

values = {:v => 1.0, :n => 10.0, :t => 273.5}
calcul = Compute_p_class.new values
calcul.add_option :clock, 5.0
calcul.add_option :print

puts "p = #{calcul.execute}"

mercredi 26 mars 2008

Google Summer Of Code

Cette année encore, Google organise le Summer of Code (abrégé en SoC) : il s'agit d'une opération permettant à des étudiants du monde entier de s'investir dans un grand projet libre le temps de l'été. Pour en savoir plus :

Plutôt que de plagier cette dernière news très bien faite, je vais juste apporter quelques remarques.

Beaucoup de projets impliqués ; Un grand absent ?

De mes petits yeux fatigués, j'ai compté 177 projets libres participant au programme. C'est énorme. Chacun profitant de l'engagement de plusieurs étudiants, à temps plein, pendant 2 mois complets, il faut se figurer le bénéfice que cela génère pour le monde du libre ! Sans compter les 4500 $ pour l'étudiant et 500 $ pour le projet en cas de succès...

On retrouve beaucoup de noms très connus du monde libre : Apache, The GIMP, Wikimedia, Linux, Mozilla... ( Mais aussi certains un peu moins célèbres qui m'ont fait plaisir comme Battle for Wesnoth).

Mais il en manque certains, dont un qui saute aux yeux : OpenOffice.org. Pourquoi ? Vraiment là, je donne ma langue au chat... (Mauvaises relations avec Google ?).
J'ai aussi noté l'absence totale de logiciel de P2P (Azureus et Bittorrent sont eux aussi libres). Là en revanche, ça peut s'expliquer plus simplement vu l'utilisation souvent approximativement légale de ce type d'application. Quoique. A ce compte là, on pourrait exclure tous les projets de langage de prog' : on peut potentiellement en faire mauvais usage...

Les langages ? (Ruby ?)

Question essentielle s'il en est... On en retrouve un nombre considérable : C, C++ et Java bien sûr. Mais pas seulement. La plupart des langages de script sont là : PHP, Perl, Python, Ruby, Javascript, Groovy, Scheme... Et aussi du fonctionnel pour les durs : LISP (CommonLISP et Scheme notamment) et Haskell au moins. Et puis des langages de grognards : Fortran et Ada notamment sur GCC.
Au passage, je trouve vraiment exceptionnel de pouvoir participer, en tant qu'étudiant, au développement d'un "grand" langage via ce programme : LISP, PHP, Perl... Geeky !

Et le Ruby ? On le retrouve sur différents projets, et pas forcément ceux auxquels on pouvait s'attendre...
Certes, il y a Ruby Central dont les propositions de sujet sont très axées sur Merb et sur la collaboration avec d'autres langages (Python et Java notamment) ou d'autres interpréteurs (JRuby et Rubinius).
On retrouve ensuite Ruby dans les projets Codehaus (JRuby) et... NESCent : le "National Evolutionary Synthesis Center" sur le projet Bio* (Bio_ : Perl, Python, Ruby, SQL, Java...) dans le domaine de la bio-informatique. Ruby en science ?

Triple-win ? (Winwinwin...)

Vous l'aurez compris, je suis très favorable à ce type d'opération qui semble profitable aux trois protagonistes :
  • Pour les étudiants : de l'expérience (très valorisable) et potentiellement une rétribution non négligeable.
  • Pour les projets : 2 mois de travail par étudiant (+ 500 $ ?), un peu de pub, et potentiellement un nouveau contributeur régulier avec de l'expérience.
  • Pour Google : de la pub ciblant plus particulièrement le monde du libre. Mais aussi une grosse manœuvre RH de pré-recrutements éventuels.
Pourquoi je pose cette question ?

Parce qu'il est toujours bon de savoir pourquoi l'on reçoit de l'aide ou de l'argent. J'apprécie Google pour différentes raisons et différents produits. Mais si les pratiques de cette entreprise me paraissent bien plus correctes que d'autres (là je pense très fort à la petite boîte de Bill le portail, mais aussi au principal concurrent de Google pour la recherche en ligne, et malheureusement parfois à l'autre pomme...), elle n'en reste pas moins une entreprise comme une autre (peut être plus riche, certes...).
S'il serait dommage de tomber dans la paranoïa libriste extrémiste malheureusement trop courante, il faut néanmoins que le monde du libre sache clairement garder son indépendance et ses valeurs, tout en s'ouvrant davantage sur le monde de l'entreprise. Cela semble être le cas ici.

En bref...

Si contrairement à votre serviteur vous êtes (encore) étudiant et vous avez un poil de talent (l'acharnement marche aussi parfois...) : allez (re-)jeter un coup d'œil sur la page du SoC 2008...


jeudi 20 mars 2008

Matrices en Ruby : 3 - Linalg !

Les matrices sont assez mal gérées de base en Ruby (cf articles précédents : [1] et [2]). Heureusement, il existe une bonne bibliothèque basée sur LAPACK (Linear Algebra PACKage, bien connue en Fortran) :

Comme indiqué dans sa doc, cette lib permet pas mal de choses : gestion simple et fiable des matrices, opérations classiques (déterminant, trace, valeurs propres...), décompositions diverses (LU, Cholesky...) et différentes autres méthodes.

L'installation est simple. Ensuite un simple require 'linalg' suivi de include Linalg, et c'est parti ! La doc contient un bon petit tuto (recopié dans le README) d'introduction pour faire tour avec irb.

Deux petits exemples d'utilisations :

Problème N-corps :

N corps interagissent gravitationnellement selon la loi de Newton. Dans cet exemple, j'utilise Linalg uniquement pour la structure de mes vecteurs position et vitesse. Code crade et valeurs mal choisies...


Convection-diffusion :

Ici, il s'agit de la résolution 1D par la méthode des différences finies de l'équation d'advection-diffusion d'un scalaire passif (exemples : polluant en rivière, transfert de chaleur...). La méthode mathématique a été écrite rapidement... j'ai essayé de faire en finesse : la partie diffusive est centrée, et la partie advective décentrée. Mais du coup, j'ai pas pris le temps de faire de calculs de conditionnement et de condition CFL, ni de faire un schéma en temps moins brutal que du pur explicite... Je me suis cependant autorisé la possibilité de faire varier le champs de vitesse au cours du temps (utile par exemple pour coupler avec un modèle de calcul de champs de vitesses : Saint Venant pour de l'hydraulique ?). Par contre, ici aussi, les valeurs proposées sont assez mauvaises (pas de diffusion notamment !) : n'hésitez pas à tester avec d'autres !


Toute question, remarque ou commentaire est le bienvenu !

dimanche 9 mars 2008

Work World Whores


Big Billou soit loué ! Jason Calcanis, fondateur de Mahalo (un moteur de recherche moyen mais pas trop...), vient de publier sur son blog une liste d'astuces pour économiser de l'argent pour une start-up (trouvé via techcrunch / techcrunch en français). Alors bon, c'est un peu en décalage par rapport aux sujets habituels de ce blog, mais je vais me permettre de commenter un peu ses "astuces". D'abord parce qu'elles ne sont pas toutes immondes. Ensuite parce qu'elles ne se limitent absolument pas au monde psychédélique des start-up.

How to save money running a start-up, by J. Calcanis.

Passons en revue ces 18 points :

  1. Achetez des Macs. Tu es sur la bonne voix pitchoune : une licence MacOS X.5 coûte effectivement moins cher qu'une Vista et est meilleure. Mais pourquoi s'arrêter en si bon chemin ? Même avec des macs, il me paraît illusoire de croire que l'on peu complètement s'affranchir des frais d'une équipe d'assistance ou réseau. A ce compte là, autant passer sur un OS libre, gratuit et efficace. Bien sûr, je pense à Linux. OpenSolaris aussi. Dans certains domaines, comme les sciences et/ou avec une dose importante de développement informatique, je ne comprends pas qu'on investisse dans autre chose...
  2. Achetez un second écran pour chaque employé. Oh god damn' yes ! Je prends. Win-win.
  3. "Pas de réunion" : faites vos réunions pendant les repas. Oui et non. Il faut aussi couper la journée. Tojo ! Pourquoi pas des entretiens aux toilettes ?
  4. Achetez des tables "cheap" et de très bonnes chaises. Tout à fait d'accord, mais pas pour les mêmes raisons. Qui se soucie de bosser sur un bureau à 3000 quand il a le postérieur éclaté sur une chaise pourrave ? Idem : de bons écrans/claviers/souris sont plus importants qu'une unité centrale esthétique.
  5. Pas de système de téléphones : utilisez IRC ou autre. Pourquoi pas, mais : si les PC / le réseau plante(nt), comment tu préviens l'assistance ? A voir.
  6. Louez vos bureaux en trop. Bof bof...
  7. Outsource et RH... No comment.
  8. N'achetez que quelques licences Microsoft Office et utilisez Google Docs. Nan. Achetez UNE licence MS Office complète (avec PDF converter) et n'utilisez QUE Open Office. Bannissez le .doc. C'est mal.
  9. Ne payez pas pour un serveur d'échange, utilisez GMail. Oui, mais il manque quand même des fonctionnalités.
  10. Payez des PC à ceux qui bossent le plus pour qu'ils continuent à la maison. On te pendra avec tes tripes.
  11. Virez ceux qui ne sont pas des workaholics ("fous de travail"). Augmente tes salaires tojo ! (On te pendra quand même, et en plus on va te châtier. Grave.)
  12. Achetez de la bouffe et une très bonne machine à café pour garder les employés au bureau. C'est vicelard, mais il faut reconnaître que c'est pas forcément désagréable. D'autant que payer à la machine à café, au taf (payer - au taf), c'est très désagréable. Win-win.
  13. Pareil avec des sodas. Idem donc.
  14. Autoriser les gens à faire les horaires qu'ils souhaitent (arrivée et départ, hein !). Oui : win-win. Non, quand celui qui se pointe à 11H fait rester celui qui est là depuis 8H le soir à 20H pour une release naze.
  15. Négocier des prix de gros. Incroyable ! Innovant ! Personne n'y avait pensé !!!
  16. Ne perdez pas d'argent avec des recruteurs, utilisez FaceBook. Hahahaha !!! Quel cou1llon ! Tu vas engager qui ? Celui qui a le plus de potes ? Celui qui lance le plus de moutons ? Ou celui qui a reçu comme "gift" un caleçon à cœur ? Cela dit, il existe des méthodes alternatives efficaces, comme la cooptation.
  17. Prendre un consultant plutôt qu'un contrat avec une PR firm. A voir... différences entre les USA et la France à ce niveau ?
  18. Outsource to Middle America. Comme nous en Inde ? Touss touss...

Bref, vous l'aurez compris : un employé prend en moyenne 15 minutes par jour pour déféquer : 15 min * 218 jours par an donnent environ 37 H, soit près d'une semaine de travail perdu dans les toilettes.

EMPLOYES ! PRENEZ SUR VOUS ! NE CH1EZ PLUS !


dimanche 2 mars 2008

Travail, travail...

Dans la vie, on fait pas toujours ce qu'on veut : Scheme va devoir un peu attendre... j'ai trouvé du taf :
Du coup, la fréquence de publication sur ce blog devrait baisser sensiblement dans les prochaines semaines. Je n'abandonne cependant pas ni ce blog, ni les petits langages que j'aime : en cas de disette, je posterai des vieux codes rigolos sortis des placards, en Fortran ou Ruby notamment. Je reste à l'affut sur le SDZ également.

Pour parler prog', j'avais cité Ada l'autre jour, et je l'attaque donc pour le boulot. Je ne suis pas persuadé de pouvoir "blogger" là-dessus tout de suite : il s'agit d'un langage assez particulier. OO dans sa version 95, mais avec de grosses séquelles de son origine procédurale. Il est souvent préféré au C dans le cadre d'applications critiques (pour systèmes embarqués notamment) pour sa rigueur imposée, sa meilleure (à priori) gestion des tableaux (et des problèmes d'indices), et sa capacité à ajouter des "règles" (contraintes) supplémentaires au compilateur : le tout dans un soucis permanent de fiabilité de l'exécutable. Exécutable plus volumineux qu'en C en revanche, mais (selon certaines sources) d'une vitesse (notion importante en temps réel) comparable au C++. Correct donc. Que dire d'autre, sinon qu'Ada possède un compilateur libre du projet GNU : GNAT (la référence, existant en version "pro" avec IDE et services associés) et que ce langage gère "nativement" la programmation concurrente ?

J'espère pouvoir vous en donner quelques exemples bientôt...

mardi 19 février 2008

Et maintenant, quel langage ?

Les habitués de forums de programmation pour débutants (SDZ ?) devraient avoir souri en lisant ce titre... (En effet, ce type de forum voit apparaître avec une fréquence de 2 à 10 par semaine des sujet portant un titre approché de ça : "Quel language choisire svp URGENT ?" le plus souvent).

Blague à part, la question n'est pas idiote. Loin de là.
Quel langage apprendre ?

Des langages !
Beaucoup !

Il y a beaucoup de langages. De plus en plus même (note : je vais parler ici des "vrais langages" de programmation, c'est à dire, à mon sens, ceux qui sont Turing-complet ; pas du HTML, LaTeX, XML ou autres...).

Lesquels sont généralistes ? La plupart.
Lesquels sont spécialisés ou orientés vers une utilisation précise ? La plupart aussi !
Je m'explique : Fortran permet de tout faire (à condition d'être courageux) mais n'a que peu d'intérêt en dehors du domaine scientifique. Ruby est généraliste, mais est surtout employé pour des applications web (Rails...). Python permet de faire de "vrais" programmes mais sera surtout utilisé (dans le monde pro) pour du scripting d'appoint. On cherche encore Ada ailleurs que dans de l'embarqué et le Javascript ailleurs que dans des applis web côté client... Et pourtant, dans l'absolu, tous permettent de faire la même chose.

Les généralistes et les familles

Cela dit, il existe quelques langages qui sont utilisés (utilisables ?) pour à peu près tout : le C++ et le Java. Pas de chance pour eux (ou pour moi !), je ne les apprécie pas outre mesure. Sans être allergique au C++ que j'ai déjà utilisé en milieu professionnel, je trouve qu'ils sont assez proches et assez lourds (j'ai déjà le Fortran à la maison, merci !) : je reconnais sans problème leurs qualités respectives, mais ils ne conviennent pas, à mon sens, pour un usage domestique/éducatif/récréatif. De plus il ne recèlent pas ou peu de concepts nouveaux pour moi (même si ça ne me ferait pas de mal de revoir la gestion des pointeurs et références en C++ et deux, trois petites choses...).

Dans le même ordre d'idée, je pourrais me mettre au Python. Mais comme il est très proche de Ruby, à quoi bon ? Me taper les différences de syntaxe et de convention pour faire les mêmes choses qu'en Ruby mais en Python ? Pas assez rentable à mon goût ! Je pense, ou plutôt espère, que connaître un langage dans une "catégorie" facilite et accélère l'apprentissage des langages proches, en cas de nécessité. Par exemple pour Ruby : Python, Perl, Groovy, Smalltalk...

Coder, pourquoi ?
Coder plus pour gagner plus...

Car si je code, ce n'est pas que pour le plaisir.

C'est vrai qu'après des débuts difficiles, je me suis mis à apprécier de plus en plus la programmation, pour pas mal de raisons. D'abord pour l'aspect mathématique assez fort que j'y retrouve. Ensuite pour le côté "Lego" : il y a un aspect "architectural" dans la construction d'un programme, des contraintes mais aussi une grande liberté devant son éditeur de texte (un peu comme face aux briques), et une fois terminé on peut "jouer avec" son programme. Enfin, c'est un monde riche en "concepts" liés à l'image que l'on (l'homme et/ou la machine) se fait d'un problème et de sa résolution.

Mais la programmation, c'est aussi une partie importante de mon métier (ingénieur modélisation - bon, ok, pas en ce moment, mais je vais trouver ^^). Et dans ce contexte, à mon niveau, il n'est pas question de choix. On travaille avec le(s) langage(s) qu'on nous donne. Et c'est là que ça se gatte... Dans le domaine de la simulation et analyse numérique, sont surtout utilisés le Fortran et le C++, que je maîtrise "relativement" bien. Les informations glanées sur le web, au cours d'entretiens, etc... ont mis en lumière d'autres "technologies" possibles : Matlab, VisualBasic, C et Ada principalement.
  • Je pourrais me mettre au Matlab mais c'est pas gratuit, même s'il existe SciLab dans le genre...
  • L'environnement VisualBasic, malgré tout le mal que j'en pense, a été installé sur ma bécane... moins d'une heure. Déjà, les IDE m'insupportent, alors quand on ajoute un helper autiste et des tutos qui commencent par "Comment insérer un copyright dans votre programme" (véridique : cherchez sur le web !) et enchaîne sur "Créer un menu dans une fenêtre", ça fait beaucoup. Sans rire, ce genre de truc est extrêmement dangereux pour le PC d'un gars comme moi... Dix minutes de plus et je transperçais l'écran à coup de tête. Dangereux je vous dis !
  • C après C++, connaissant le Fortran ? Mouais...
  • Ada serait sans doute le plus intéressant, mais il y a peu de chance qu'il me serve en milieu professionnel, vu qu'il est le plus souvent dédié au systèmes embarqués (domaine intéressant, mais un peu loin de ma branche).

L'utilisation éventuelle d'un langage en entreprise m'aide donc peu.

Concept ?
Aqui lo paradigme !

Il reste les "concepts".
Cela fait déjà un bon moment que le monde de la programmation fonctionnelle me fascine : attraction/répulsion.
Attraction car c'est une grande famille de langages, de LISP à Haskell en passant par Scheme et OCaml avec des méthodes intéressantes.
Répulsion car jusqu'ici, j'ai toujours été incapable de "décrypter" le moindre bout de code fonctionnel aperçu ici ou là : crispant.
Il y a aussi d'autres "concepts" (paradigmes en l'occurrence ici) : logique (PROLOG), concurrent (Ada, encore !), par contrainte...

Finalement...
Tout ça pour ça...

Finalement, c'est par hasard que je me suis mis... au Scheme.
Un article, chez RubyInside, décrivait un interpréteur pour Scheme, codé en Ruby, dans le bus. J'ai voulu tester. Du coup, il m'a fallu taper un peu de Scheme ; du coup, j'ai lu du Scheme ; du coup je me suis mis à comprendre un peu le Scheme ; du coup, j'apprends le Scheme.
Pour être tout à fait franc, ce langage faisait déjà parti de ceux qui me tentaient fortement, avec le LISP, l'OCaml, Io et Cobol (non, pour le Cobol, j'd3conne !).
Io a perdu car je voulais voir autre chose que de l'OO. Quite à se lancer dans le fonctionnel, autant prendre un langage "simple" : l'OCaml me semblait "trop riche" car multi-paradigme. Enfin, le LISP a eu un petit désavantage : cette citation de G. Chaitin sur la "pureté" d'un langage.
Scheme donc, avec l'interpréteur MzScheme (Bus-Scheme, celui en Ruby étant... peu utilisable ?).

Effectivement, Scheme est austère. Mais il semble reconnu pour son côté pédagogique et est (hormis pour les parenthèses) assez bref dans sa syntaxe : il y a une certaine élégance proche des maths je trouve. Il est vieux, mais a un certain charme... et j'avoue que je l'apprends avec un certain plaisir. Et pour ma bonne conscience professionnelle, Scheme est utilisé dans certains codes de calculs industriel, en appoint (bientôt un article sur "Quel(s) langage(s) dans tel programme ?").Que demander de plus ?

Références et Docs :

D'abord, deux textes pleins de sagesse (si si, il y a un rapport avec le reste...) :
L'article sur Bus-Scheme, l'implémentation en Ruby :
Commençons gentiment en Scheme (avec un interpréteur qui marche !) :
Pour tout le reste vu dans cet article, Wikipédia saura répondre... sinon demandez toujours !



jeudi 24 janvier 2008

Software Engineer. Engineer ?

Un début de débat intéressant (tendant un peu vers le troll), par blogs interposés, sur la question suivante (et ses corollaires) :

Un "Software Engineer" (approximativement : ingénieur logiciel) est-il un ingénieur à proprement parler ?

D'où découlent plusieurs questions intéressantes, quasiment épistémologiques pour certaines :
  • Peut-on définir l'ingénieur comme étant celui qui utilise les mathématiques comme un outil fondamental ?
  • Qu'est-ce qu'un modèle scientifique ? Pourquoi UML, par exemple, ne semble-t-il pas en être un ?
  • Quelle(s) valeur(s) pour mesurer un "travail" ?
  • Distinctions entre un ingénieur, un chercheur ("scientist" dans les articles) et un cadre ("clerk" ici) ?
Le débat :