Premièrement je suis d'accord pour dire que malgré toutes ses améliorations, C++ ne prend pas réellement de fonctions comme objets de première classe. Les lambdas et autres types d'inférences limités sont extrêmement bienvenus, mais on reste dans le domaine d'un langage impératif (avec désormais plus d'opportunités pour avoir un style fonctionnel). Je renvoie à l'article de John Carmack pour une exploration de style fonctionnel en C++. Ceci étant dit :
P.S: Bon, le lambda-calcul ça date de 1936, et on a du attendre C++11 pour en avoir un ersatz à lire tes exemples
Histoire de troller un chouïa : étant donné que Church et son thésard, un inconnu du nom de Alan... Alan... Alan T-quelque chose, sont les deux piliers qui ont permis de créer les fondations de l'informatique théorique telle qu'on la connaît, j'ai envie de dire que crâner à propos du lambda calcul « créé en 1936 »1, alors que les principes de la machine universelle de Turing, qui sont certes arrivés plus tard (ce qui est somme toute logique), ont eux été mis en œuvre dès les années 40, c'est quand même rigolo. :-)
Ensuite, juste pour dire, le bouquin de B. Pierce sur les types montre qu'il est parfaitement possible d'implémenter un système de typage fort à base de lambda-calcul (il propose un mini-Java comme exemple, et un mini-ML aussi).
Je pense que l'ajout de trucs types lambdas à Java et C++ vient surtout du fait que lorsque tu as un écosystème populaire, il faut d'abord composer avec ce que les utilisateurs veulent (et fabricants de compilateurs proposent). Jusqu'au début des années 90, les compilateurs de production étaient franchement médiocres en termes d'optimisation (à quelques exceptions près, en particulier pour les compilateurs Fortran à destination de machines vectorielles, genre les Cray-I, etc.). Du coup, avec un langage procédural genre C, on pouvait au moins donner une forme au code qui permettait d'optimiser l'utilisation des registres, et d'être proche de la machine. Pendant très longtemps, les langages de programmation fonctionnelle a été considérée comme inefficaces en termes de performances. Ça commencé à sérieusement changer lorsque les compilateurs ont commencé à proposer des optimisations très agressives, mais même ainsi, les algorithmes (géniaux) qui sont derrière l'inférence de type de ML, et ceux qui gèrent la curryfication par exemple, ont tendance à mener à de la compilation via continuation, ce qui peut être très bien ou terrible en fonction de l'implémentation (y'a un excellent bouquin d'A.Appel sur la compilation de ML avec continuations soit dit en passant). Bref.
Jusqu'à il y a peu, la programmation fonctionnelle était considérée comme un truc d'académicien2. L'un des rares langages procéduraux à avoir intégré des bouts de programmation fonctionnelle était Perl: il est possible de passer des blocs de code et de créer des lambdas, tout un tas de fonctions « built-in » (genre map, grep, etc.) sont directement tirées de CLISP et ses copines, ... Mais c'était aussi parce que Perl était à la base optimisé pour le traitement de fichiers textuels, et que les entrées-sorties étaient ce qui était bloquant de toute manière. Donc niveau perf, l'utilisation de fonctions de haut-niveau avec un coût à l'exécution était OK.
Quand OCaml, Scala, Haskell, etc., on enfin émergé et commencé à prouver qu'ils pouvaient, eux aussi, proposer des performances raisonnables (pas forcément comparé à C/C++, mais au moins par rapport à Java), tout en proposant une grande puissance d'expression, on a vu Java et C# (par exemple) commencer à se doter d'aspects fonctionnels. Encore une fois, c'est entre autres parce que les développeurs/utilisateurs du langage ont vu ce que pouvaient faire les voisins et ont réclamé ces fonctionnalités.
D'ailleurs je pense que tu parles du lambda-calcul typé; si je me souviens bien, le lambda-calcul non-typé avait été proposé 5 ans auparavant mais ne « servait à rien », d'où le besoin de pousser plus loin. ↩
Il faut aussi dire que c'est un peu la faute des profs. Genre en France quand OCaml était enseigné y'a ~15-20 ans, la façon d'enseigner le truc était très mathématique. On faisait en pratique des maths avec un langage de matheux. Si les profs avaient proposé de faire de la prog en OCaml mais avec un aspect pragmatique (mais en gardant l'aspect fonctionnel) je pense que ça aurait dégoûté beaucoup moins de gens de l'informatique en DEUG. ↩
[^] # Re: Jai: Language for game programmming
Posté par lasher . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 7.
Premièrement je suis d'accord pour dire que malgré toutes ses améliorations, C++ ne prend pas réellement de fonctions comme objets de première classe. Les lambdas et autres types d'inférences limités sont extrêmement bienvenus, mais on reste dans le domaine d'un langage impératif (avec désormais plus d'opportunités pour avoir un style fonctionnel). Je renvoie à l'article de John Carmack pour une exploration de style fonctionnel en C++. Ceci étant dit :
Histoire de troller un chouïa : étant donné que Church et son thésard, un inconnu du nom de Alan... Alan... Alan T-quelque chose, sont les deux piliers qui ont permis de créer les fondations de l'informatique théorique telle qu'on la connaît, j'ai envie de dire que crâner à propos du lambda calcul « créé en 1936 »1 , alors que les principes de la machine universelle de Turing, qui sont certes arrivés plus tard (ce qui est somme toute logique), ont eux été mis en œuvre dès les années 40, c'est quand même rigolo. :-)
Ensuite, juste pour dire, le bouquin de B. Pierce sur les types montre qu'il est parfaitement possible d'implémenter un système de typage fort à base de lambda-calcul (il propose un mini-Java comme exemple, et un mini-ML aussi).
Je pense que l'ajout de trucs types lambdas à Java et C++ vient surtout du fait que lorsque tu as un écosystème populaire, il faut d'abord composer avec ce que les utilisateurs veulent (et fabricants de compilateurs proposent). Jusqu'au début des années 90, les compilateurs de production étaient franchement médiocres en termes d'optimisation (à quelques exceptions près, en particulier pour les compilateurs Fortran à destination de machines vectorielles, genre les Cray-I, etc.). Du coup, avec un langage procédural genre C, on pouvait au moins donner une forme au code qui permettait d'optimiser l'utilisation des registres, et d'être proche de la machine. Pendant très longtemps, les langages de programmation fonctionnelle a été considérée comme inefficaces en termes de performances. Ça commencé à sérieusement changer lorsque les compilateurs ont commencé à proposer des optimisations très agressives, mais même ainsi, les algorithmes (géniaux) qui sont derrière l'inférence de type de ML, et ceux qui gèrent la curryfication par exemple, ont tendance à mener à de la compilation via continuation, ce qui peut être très bien ou terrible en fonction de l'implémentation (y'a un excellent bouquin d'A.Appel sur la compilation de ML avec continuations soit dit en passant). Bref.
Jusqu'à il y a peu, la programmation fonctionnelle était considérée comme un truc d'académicien2 . L'un des rares langages procéduraux à avoir intégré des bouts de programmation fonctionnelle était Perl: il est possible de passer des blocs de code et de créer des lambdas, tout un tas de fonctions « built-in » (genre
map,grep, etc.) sont directement tirées de CLISP et ses copines, ... Mais c'était aussi parce que Perl était à la base optimisé pour le traitement de fichiers textuels, et que les entrées-sorties étaient ce qui était bloquant de toute manière. Donc niveau perf, l'utilisation de fonctions de haut-niveau avec un coût à l'exécution était OK.Quand OCaml, Scala, Haskell, etc., on enfin émergé et commencé à prouver qu'ils pouvaient, eux aussi, proposer des performances raisonnables (pas forcément comparé à C/C++, mais au moins par rapport à Java), tout en proposant une grande puissance d'expression, on a vu Java et C# (par exemple) commencer à se doter d'aspects fonctionnels. Encore une fois, c'est entre autres parce que les développeurs/utilisateurs du langage ont vu ce que pouvaient faire les voisins et ont réclamé ces fonctionnalités.
D'ailleurs je pense que tu parles du lambda-calcul typé; si je me souviens bien, le lambda-calcul non-typé avait été proposé 5 ans auparavant mais ne « servait à rien », d'où le besoin de pousser plus loin. ↩
Il faut aussi dire que c'est un peu la faute des profs. Genre en France quand OCaml était enseigné y'a ~15-20 ans, la façon d'enseigner le truc était très mathématique. On faisait en pratique des maths avec un langage de matheux. Si les profs avaient proposé de faire de la prog en OCaml mais avec un aspect pragmatique (mais en gardant l'aspect fonctionnel) je pense que ça aurait dégoûté beaucoup moins de gens de l'informatique en DEUG. ↩