Categories
Programming

C, Python & Ocaml ou les plaisirs simples de la vie

Un billet en trois parties qui aborde en premier lieu trois beaux langages de programmation bien différents et se ressemblant sur certains points. Ils réunissent expressivité et performance, style impératif et fonctionnel, typage dynamique (mais pas faible) et fort.

Je trouve qu’il est plutôt drôle de les comparer. Python semble sur certains points se situer entre le C et Objective Caml. Enfin c’est mon avis et ce que je constate parfois.

Pour Guido Van Rossum, Python devait être entre un language de script (interprété comme Shell) et le C (compilé) et ainsi tenter de réunir expressivité et performances avec des structures de données évoluées (dictionnaires, tuples, listes, etc.).
Python est donc un language impératif héritant de l’éducation de Guido Van Rossum et sur ce point est proche de C. Cependant il a un typage dynamique fortement typé (inutile de définir de manière explicite le type d’une variable, mais une fois fixé le type a souvent de l’importance). Au contraire le C a un typage très fort.

Cependant des fonctions comme map ou les listes en compréhensions lui donne quelques traits de languages fonctionnels, comme OCaml (preuve que Guido a l’esprit ouvert). Biensûr sur ce point il n’arrive pas à la cheville d’OCaml et c’est normal.

Ce qui est vraiment génial avec Python, c’est la liberté et l’expressivité du langage. Ce qui fait qu’on peut faire facilement à peu près ce que l’on souhaite. Voici par exemple deux petites comparaisons:

  • Ocaml et Python
    Sans être vraiment un langage fonctionnel Python de par son expressivité définit cette fonction d’incrémentation quasiment aussi simplement que OCaml. Grâce au listes en compréhension il peut même faire mieux parfois;
  • C et Python
    En le comparant à C on comprend de suite l’avante du typage dynamique (qui peut être dangereux), mais il sera parfois moins performant pour des calculs plus complexes (par exemple en cryptographie ou pour traiter des longues chaînes de caractères). Voici encore un excellent exemple.

Il y a donc évidemment plusieurs styles pour écrire du Python. Un(e) Pythonien(ne) reconnaîtra le bon.
Lorsque l’on sait un petit peu développer on sent facilement quel langage est le plus adapté dans une situation. Hormis pour des raisons de performances je n’utilisera plus le C pour calculer un PGCD, Fibonacci ou encore jouer avec une liste mais plutôt Ocaml. Je le faisais avant, je n’en ai plus besoin. Par dessus OCaml pour les listes je préfère de loin Python, parfois aussi pour des fonctions mathématiques. Pour des traitements sur des fichiers, chaînes de caractères, le C. Bref, mes trois langages favoris qui permettent de tout faire très bien.

La première partie très plaisante de ce billet se termine sur cette question: De votre côté, comment situez vous C, Python et OCaml?

§

Maintenant parlons du développeur de l’extrême (celui qui aime les lignes de code). Typiquement:

  • il aime écrire une classe en Java juste pour une fonction mathématique (exemple: incrémenter un nombre ou mise à la puissance avec gestion avancée des paramètres dans le build.xml d’Eclipse);
  • il écrit une classe en Java pour lire un fichier texte ou ouvrir une socket;
  • s’il tente de coder un petit morceau (par exemple factorielle) en OCaml, il utilisera une boucle for.

Très souvent ce malheureux Windowsien(ne) dégainera Eclipse pour générer automatiquement un tas de morceaux de codes inutiles. Ce n’est pas forcément un mauvais développeur, il est peut être juste simplement passé à côté de la programmation. Ce sera parfois la faute de l’école, souvent celle du monde de l’entreprise. Pour guérir c’est facile, il suffit de découvrir Python, Perl ou Ocaml. Attention toutefois, OCaml peut provoquer un choc assez violent chez un développeur Java de longue date.
Généralement les systèmes type GNU/Linux vous feront naturellement utiliser Python, Perl et C. OCaml ça sera par pur plaisir.

§

Pour finir passons à une autre catégorie de développeur, le fanatique. On remarquera que cette personne utilisera entre autres Python pour tout et n’importe quoi sans même savoir si Python est bon pour cela. Par exemple pour:

Ah zut, je crois qu’il y a un problème avec la liste. Vous pouvez chercher pour moi?
Certains au lieu de Python choisirons Perl. D’autres Java. Mais ces derniers, ont-ils vraiment choisi?

§

Encore une question: Y a-t-il un ordre d’apprentissage (au moins pour ces trois langages)?

2 replies on “C, Python & Ocaml ou les plaisirs simples de la vie”

Je ne pouvais pas ne pas commenter ce billet 🙂 Soyons clair: ocaml c’est mieux !

Ocaml.
Il me semble que les caractéristiques principales d’ocaml sont:
a) le polymorphisme et l’inférence de type;
b) le filtrage par motifs (pattern-matching);
c) c’est un vrai langage fonctionnel.

Les avantages sont:
a) traitement uniforme dès que possible: p.ex. on écrit en une fois une fonction qui inverse une liste, quelque soit le type de ses éléments;
b) rend lisible les longues imbrications de if-then-else, et donc développement plus sûr;
c) on peut prendre une fonction en argument, retourner une fonction en résultat d’une autre fonction, appliquer partiellement une fonction.

Dans tes exemples, ça m’intéresserait de voir les équivalents python et C de tout ça (le point c en python est faisable).
Je t’aide un peu pour l’application partielle en proposant l’incrémentation qui devient en ocaml:
let inc = (+) 1;;
Pour le point b), ça doit se faire à coup d’objets… mais probablement difficilement.

Python:
La principale difficulté que j’ai avec ce langage c’est ce que tu appelles typage dynamique. En particulier, ça permet de faire ça:
def f(n):
if n==0:
return 0
else:
return “1”

Autrement dit f(0) -> 0 et f(1) -> “1” qui sont des résultats de types différents.
Ce genre de manquement à la rigueur n’est pas signalé, et peut amener à attendre que f(1) + f(1) -> 2, alors qu’on obtiendra “11” (vu que + agit autant sur deux chaînes que sur deux entiers). Et vive le débogage !

En revanche les syntaxes raccourcies sur les listes (slices et compréhension) sont agréables. Mais avec camlp5 il me semble qu’on doit pouvoir étendre la syntaxe de caml avec ce genre de truc.

C:
Je me demande bien à quoi peut encore servir ce langage comparé à Python. Vu qu’en C tout est entier (pointeur, fonction, entier, caractère, etc.) les problèmes de typage se posent aussi. Python possède une syntaxe bien plus agréable et une bibliothèque nettement plus fournie tout en conservant tous les appels systèmes nécessaires.
En plus question efficacité, il semblerait que gcc finira pas compiler du python tôt ou tard (cf. google summer of code), ce qui éliminerait ce critère de choix.
Y a-t-il des projets de système d’exploitation en Python ?

Mieux qu’ocaml !
Mais il y a mieux qu’ocaml et qui se profile: la programmation avec types dépendants. Dans ce cadre les types des fonctions dépendent en plus de la valeur de leurs arguments. Par exemple, là où jadis il fallait écrire la fonction qui renvoie la tête d’une liste en prenant en compte le cas de la liste vide et en retournant une erreur bidon (ou une exception), ici ce n’est plus nécessaire. En effet, la fonction head aura simplement le type:
head: forall n:nat, list (n+1) nat -> nat

Autrement dit, avec nat les entiers naturels (i.e. >= 0), elle prend un entier naturel, une liste de taille strictement plus grande que 1 (list n est le type des listes de taille n) et retourne un entier (ici la tête de la liste).
Ainsi, plus besoin d’exception, plus besoin de traiter de cas particulier, etc. En revanche, pour utiliser une telle fonction, il risque d’être nécessaire de fournir des preuves (p.ex. ici le fait que la liste passée à head est de taille > 0).

En espérant t’avoir donné des idées pour un prochain billet…

P.S.: pour les malchanceux du java qui veulent du pattern-matching et de la fonctionnalité, il y a tom (http://tom.loria.fr).

Excellent commentaire 🙂

En effet, c’est surtout le filtrage par motifs qui me plaît dans OCaml. Aussi le polymorphisme souvent lié au typage dynamique comme avec Python.

Merci pour “let inc = (+) 1;;”, je connaissais (dans mes souvenirs). Je vais l’ajouter au Wiki. Mais après ma version, car la tienne est trop puissante 😉
C’est vraiment super comme déclaration. Je crois que c’est un truc du genre:
“val + : int -> int -> int = ” et on fixe un paramètre à la fonction ‘+’ pour avoir “val inc : int -> int = (+) 1” ? C’est beau.

Si tu veux, tu peux même éditer le Wiki pour Ocaml. Tu ferrais mieux que moi. J’ai prévu d’expliquer un peu l’aspect fonctionnel, les signatures des fonctions…

Encore un truc marrant avec OCaml:

cedric@debian:~$ ocaml
        Objective Caml version 3.11.2
# exit;;
- : int -> 'a = fun

# exit 0;;
cedric@debian:~$

C’est marrant aussi le fonctionnel.

Ta principale difficulté avec Python (le typage dynamique), en fait ça me plaît aussi. Par exemple:

>>> def mystere(a,b):
...     return a+b
... 
>>> mystere(2,3)
5
>>> mystere("a","b")
'ab'
>>> mystere([1], [2])
[1, 2]
>>> ...

C’est le polymorphisme. Certaines personnes au début d’une fonction utilise: “if type(x): …”. C’est moche de faire ça. Ça gâche tout le côté marrant de Python. J’aime le polymorphisme. Mais attention le polymorphisme de Python est vissieux. On est entre adultes consentants, comme on dit dans la communauté.

> Y a-t-il des projets de système d’exploitation en Python ?
Tu veux dire kernel? Je doute. J’ai déjà rencontrer certaines choses vraiment low level en Python. Mais tout un système…
Avec du recul je trouve que C est un beau langage. Quand j’avais 18-20 ans il m’impressionait et me parassait moche.
Mais si tu lis un bouquin comme http://www.librarything.fr/work/3600740/book/62075147, tu te rends compte que c’est un langare avec peux de choses à apprendre finalement…

Très intéressant ce type de programmation. Je voulais programmer une fonction Python en une ligne de code pour faire head() de manière générale sans traiter les cas particuliers. Mais c’est vrai que c’est tiré par les cheuveux… Je réfléchierai tête reposée (jai dormi 4h cette nuit).
En tout cas dès que j’ai le temps je regarde à ce sujet, merci.

Comments are closed.