Bonjour, je voudrai apprendre le paradigme fonctionnel avec un langage bien, vous pouvez m'en conseiller un ?
Par exemple je voudrai bien apprendre ocaml, est-ce une bonne idée ? Merci beaucoup.
Bonjour, je voudrai apprendre le paradigme fonctionnel avec un langage bien, vous pouvez m'en conseiller un ?
Par exemple je voudrai bien apprendre ocaml, est-ce une bonne idée ? Merci beaucoup.
Je pense que OCaml est le meilleur langage fonctionnel pour commencer (attention, je ne suis pas mortellement objectif, il se trouve que c'est aussi mon langage préféré).
En gros, un langage est considéré comme fonctionnel quand il permet de passer des fonctions comme argument ou comme valeur de retour d'une autre fonction, et qu'il favorise le style déclaratif (en gros, le fait de coder sans effets de bords ou presque).
L'exemple typique de langage fonctionnel est Lisp, qui a donné lieu à une foultitude de langages dérivés, entre autres Scheme. Ils reposent sur une syntaxe très, très simple, et permettent des manipulations syntaxiques voire de la métaprogrammation assez simplement.
Ensuite, il y a une deuxième grande famille de langage fonctionnels descendant de ML. Ce sont des langages qui sont statiquement typés (alors que Lisp est dynamiquement typé), comme le C, le Java etc., à ceci près que le typage est en grande partie inférable c'est à dire que le programmeur n'a pas besoin de préciser le type des variables, le compilateur les "devine" tout seul. Ils apportent aussi des fonctionnalités très intéressantes comme les types algébriques et le filtrage de motifs, des fonctionnalités complémentaires qui permettent de travailler facilement et sûrement sur des types de données complexes (et potentiellement récursifs : listes, arbres, etc.).
Les deux plus grands représentants de cette famille actuellement sont sans doute OCaml et SML.
Enfin, il y a une troisième branche, très proche des langages ML (on peut considérer qu'ils font partie de la famille ML), eux aussi statiquement typés, à types algébriques et filtrage de motifs, qui sont les langages paresseux. La paresse est une stratégie d'évaluation (le fait de choisir à quel moment on calcule les expressions du langage pour avoir leur valeur, par exemple quand on passe une expression en argument à une fonction, etc.) différente de celle utilisée dans les langages que tu connais, qui sont stricts. Elle est assez déroutante au départ, et dispose d'avantages et d'inconvénients. Enfin, le représentant principal de cette famille, Haskell, a une particularité supplémentaire : c'est un langage fonctionnel dit "pur", c'est à dire qu'il ne permet aucun effet de bord. C'est une contrainte très forte sur les programmes, cela impose des restrictions sur la manière dont on code (et introduit des choses pas forcément facile à comprendre pour un débutant, entre autres les monades), mais cela a aussi des avantages au niveau du raisonnement sur les programmes et pour le compilateur.
Il faut aussi citer le langage Erlang qui a fait pas mal parler de lui ces derniers temps. C'est un langage fonctionnel dynamiquement typé, relativement pauvre (en tant que langage fonctionnel) mais spécialisé dans la concurrence et le parallélisme. C'est un bon langage pour essayer la programmation avec de nombreux processus parallèles, sur des machines distantes, avec gestion des erreurs réseau, etc.
Mon avis : le typage statique, et plus généralement l'ensemble des caractéristiques des langages ML et de Haskell, sont très importantes et il faut les voir quand on fait de la programmation fonctionnelle. Je te conseille donc de commencer par un de ces langages plutôt que Lisp ou Erlang, qui ne te montrent pas cet aspect des choses. En particulier ce sont des fonctionnalités redoutablement efficace si tu t'intéresses à la programmation de parseurs, d'interpréteur ou de compilateurs de langages (mais elles sont utiles pour tous les programmes : ce sont des langages généralistes).
La paresse et la pureté sont des aspects intéressants, mais très spécifiques à certains langages et difficiles à aborder au départ (.. et même ensuite), surtout si tu viens d'un langage impératif (ou objet) classique.
Je te conseille de commencer par OCaml, qui est un excellent compromis : il t'apportera beaucoup de choses et un bon point de vue de la programmation fonctionnelle, tout en étant plus proche de ce que tu connais et moins difficile à aborder que Haskell. Si tu veux par la suite t'intéresser à un autre langage fonctionnel, son approche sera grandement facilitée par ta connaissance de OCaml (en particulier si tu veux regarder du Haskell, tu n'auras rien de difficile à oublier, seulement des choses à rajouter; l'inverse n'est pas vrai).
Voici de bons documents pour commencer :
- pour Scheme (un bon choix si tu veux un langage de la famille Lisp), je pense que la référence est le SICP
- pour OCaml, le livre de Jason Hickey, très complet. Tu as aussi en français, mais un peu plus difficile d'approche je pense, le DA-OCAML. Si tu veux une introduction plus rapide au langage (mais moins complète) tu peux aussi regarder le cours de Filliâtre.
- pour Haskell, le tout récent livre Real World Haskell, le wikibook ou, un peu plus abrupte mais traduite en français sur DVP, la gentle introduction
- pour Erlang, tu peux regarder la page de documentation; il me semble que la référence pour le débutant est un livre de Armstrong.
Si ton but est vraiment d'apprendre le paradigme fonctionnel, l'un des meilleurs choix est Haskell, simplement parce que ce langage ne te permet pas facilement de retomber dans tes vieilles habitudes comme un OCaml par exemple. Haskell est un langage fonctionnel pur, ce qui signifie qu'il ne permet pas d'utiliser de variables mutables ou de faire des effets de bord n'importe où (ce genre de chose est extrêmement restreint).
De plus Haskell est un véritable langage, utilisable en pratique, et qui dispose déjà d'un répertoire de librairies Hackage et d'outils facilement installable et couvrant pas mal d'activité courantes en programmation. Comme OCaml, Haskell peut-être compilé ou interprété et GHC est un très bon compilateur optimisateur, tu peux obtenir des performances proches du C sur certains programmes. XMonad est un gestionnaire de fenêtres pour Linux relativement populaire et dont le code tient en moins de 1000 lignes, Himerge est un gestionnaire de paquets écrits entièrement en Haskell, utilisant Gtk2Hs pour l'interface graphique.
Soit averti cependant qu'Haskell est très différent de la plupart des autres langages de programmation, même un langage à la syntaxe et au système de type proche comme OCaml, a fortiori comparé à des langages comme Java ou Python. Pour cette raison l'abord peut être un petit peu difficile au début. Je te conseille d'essayer de lire le récent Real World Haskell (chez O'Reilly, également disponible gratuitement et avec commentaires sur le net) pour une bonne présentation des avantages.
--
Jedaï
Evidemment, il n'y a pas de réponse absolue. Chacun va essayer de vendre son langage préféré. Gageons que quelqu'un vantera les mérites de Lisp ou Scheme et j'ai hésité à parler de F#.
En fait, la majorité des langages fonctionnels peut convenir. Ca dépend de tes connaissances, de ce que tu souhaites faire, etc. Quels langages connais-tu ? Quelle est ta motivation, au fond ?
Pour résumer très grossièrement :
Si tu ne veux pas t'embêter avec le typage et pour quelque chose de dynamique -> Common Lisp ou autre Lisp
Si tu veux faire du fonctionnel pur et changer complètement tes habitudes -> Haskell
Si tu veux quelque chose d'un peu moins déroutant -> OCaml ou F#.
Si tu es habitué à Ruby/Perl/Python, le plus proche est Lisp.
Si tu es habitué à .Net ou Java, le plus proche est F#.
Si tu es habitué à un autre langage impératif, le plus proche est OCaml ou F#.
bonjour , merci beaucoup de ta réponse.
J'ai commencé à apprendre Ocaml. Je connais bien python, ayant étudié le C comme premier langage. J'ai commencé à apprendre Ocaml, qui me paraît simple à aborder. Ce langage contribue à me donner un nouvel éclairage très intéressant de la programmation Python, je ne m'étais pas rendu compte à quel point il emprunte à la programmation fonctionnelle.
Pour l'instant, Ocaml me paraît simple et agréable. Je vais peut être passer à Haskell, qui me paraît un peu plus « costaud » , lorsque j'aurai bien compris Ocaml.
Si vous avez d'autres avis à donner à la lueur de mon témoignage de débutant, n'hésitez pas.
J'avoue que j'irais dans le sens de Jedai, particulièrement si tu apprends seul. Le Haskell t'évitera de tomber dans un travers trop classique (refaire de l'impératif en ocaml/scheme). Et ça c'est fondemental.
En cours, tous les langages se valent sinon. J'aime Scheme pour la facilité de mettre en oeuvre les autres techniques des autres langages. Pour cela il est "unique".
Je ne saurais dire lequel est mon préféré. Pour des applications "sérieuse" j'utilise plutôt OCaml, mais c'est par habitude plus qu'autre chose je pense.
Le mieux en fait c'est que tu trouves un bouquin ou des TP avec des exercices de programmation fonctionnelle dans un langage donné. Si tu choisis Scheme, le livre "Recueil de petits problèmes en Scheme" est très bien. Si tu choisis OCaml, l'avantage c'est que comme les maths sup math spé utilisent ce langage, il y a pas mal de sites avec des TP intéressants, si tu es intéressé je pourrais te fournir des liens (j'avais voulu me mettre à Caml à un moment, mais pas eu le temps d'approfondir...) Pour Haskell ou Erlang, je sais pas trop.
La science est ce que nous comprenons suffisamment bien pour l'expliquer à un ordinateur. L'art, c'est tout ce que nous faisons d'autre.
Donald E. Knuth
Enfin, si on ne cherche que vis-à-vis du matériel d'enseignement, Scheme est probablement gagnant. Pas parce qu'il est meilleur ou quoique ce soit du genre, mais simplement parce que ça fait des décennies qu'il est utilisé (lui ou Lisp) comme langage d'enseignement. Les cours sont donc nombreux et beaucoup sont de qualités et gratuits.
Je voulais dire : j'ai appris d'abord le C, et après le Python.
Merci beaucoup pour vos conseils. J'ai commencé avec Ocaml qui est vraiment sympa. Je ne sais pas ce que vous entendez par « retomber dans la programmation impérative », mais c'est vrai que je n'ai pas écrit de vrais programmes.
J'ai commencé avec ce cours sur ocaml, car de plus, je voudrai en apprendre plus sur l'algorithmie et les tructures de données de manière simple.
Je me suis arrêté à cet exemple :
Je ne suis pas trop avancé, mais je sens que ocaml est puissant sur le plan des structures de données et l'algorithmique (cf le cours donné en exemple) car il n'y a pas d'implémentation à rallonge comme en C avec des accolades et des déclarations de types partout. C'est très agréable (par contre le langage est statiquement typé, et les types sont implicites).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 # let rec pow (x,n) = if n=0 then 1 else x*pow(x,n-1) ;; val pow : int * int -> int = <fun>
Mais je suis d'accord que je n'aime pas trop lesqui rappellent un peu trop la programmation impérative. Cependant, n'ayez crainte, je cherche avant tout à me changer les idées, et j'apprends pour apprendre, pas pour retrouver mes vieilles habitudes. Tous les langages ne se valent pas, au moins ils se concurrencent et permettent d'élargir sa vision de la programmation, ce qui est le plus important.
Code : Sélectionner tout - Visualiser dans une fenêtre à part print_string('bonjour monde') ;
Je pense que lorsque j'aurai bien compris ocaml, je passerai à Haskell, qui a l'air plein de promesses, mais pour l'instant je tiens un bon cours ocaml qui va m'aider à progresser en programmation fonctionnelle. Merci beaucoup pour vos avis.
Certes un affichage est un effet de bord. Mais il est difficile de se passer de celui-ci. Ce n'est pas ça qui est entendu par programmation impérative, mais « changement de valeur d'une variable. » Ce que tu fais quand tu écris
par exemple, ce qui est une aberration mathématique.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 x = 1 y = 2 x = x + y
Sinon les principes d'algo sont indépendants des langages (donc Ocaml, C, Haskell, Java… même combat). Pour les structures de données, il y a certes plus de rapport, mais les notions sont quand même relativement indépendante du langage.
oui, les valeurs mutables/non mutables. D'après moi, c'est un concept difficile à passer lorsque l'on passe de l'impératif au fonctionnel. C'est d'ailleurs la principale différence il me semble.
Mais c'est vrai que l'affectation existe bel et bien en Caml, notamment avec les types composés :
S'en passer quand c'est possible, oui, mais parfois je ne vois pas comment faire autrement.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 # type complexe = { re: float ; im : float } ;; type complexe = { re : float; im : float; } # let z1 = {re=0. ; im =3.14 } ;; val z1 : complexe = {re = 0.; im = 3.14}
C'est sûr, mais je trouve que l'écriture de fonctions récursives en Ocaml est quand même plus agréable et lisible qu'en C.Envoyé par Garulfo
refEnvoyé par Boileau
En algorithmie, je crois que c'est le plus important.
Pas que, il y a aussi la manipulation des fonctions (currification)...
Si tu as fait du C++ avec Boost, tu as peut-être du toucher à [std|boost]::function<>.
Ce n'est pas une affectation ici.Mais c'est vrai que l'affectation existe bel et bien en Caml, notamment avec les types composés :
S'en passer quand c'est possible, oui, mais parfois je ne vois pas comment faire autrement.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 # type complexe = { re: float ; im : float } ;; type complexe = { re : float; im : float; } # let z1 = {re=0. ; im =3.14 } ;; val z1 : complexe = {re = 0.; im = 3.14}
Bah, disons que l'écriture des fonctions est plus légère en OCaml, mais c'est tout.C'est sûr, mais je trouve que l'écriture de fonctions récursives en Ocaml est quand même plus agréable et lisible qu'en C.
Après, une fonction récursive est presque toujours courte, que ce soit en OCaml ou en C.
When Colt produced the first practical repeating handgun, it gave rise to the saying God created men, but Colt made them equal.
Pas sûr. Beaucoup d'ouvrage et de documentation on été traduit en Scheme. Avant 1995, caml/ocaml était moins enseigné en France que Scheme.
Pour Haskell, je n'en suis pas du tout convaincu. Le système d'enseignement dispose d'une énorme inertie. Ce qui fait qu'on enseigne encore souvent le C/C++ en premier langage « parce que c'est comme ça ».
Pour en revenir sur la question des langages enseignés dans le supérieur, je ne connais que la France, mais a ma connaissance, scheme est plutot enseigné en université et caml comme je l'ai déja dit en prépa. Pour scheme, je n'ai pas trouvé tant que ça de bons liens avec des bons exercices/TP, mis a part sur la page de Christian Queinnec. J'ai trouvé plus de choses sur OCaml.
La science est ce que nous comprenons suffisamment bien pour l'expliquer à un ordinateur. L'art, c'est tout ce que nous faisons d'autre.
Donald E. Knuth
Ce n'est pas vrai non plus L'expérience personnelle est une mauvaise échelle En math, caml/ocaml a été très tôt et, notamment, à Paris VI/VII où les profs qui ont fait caml/ocaml ont enseigné en général.
De nos jours, ocaml est la norme en université si j'en crois mes confrères français.
Tu ne recherches que des ressources en français ?
Car sinon, en anglais,
http://mitpress.mit.edu/sicp/
http://www.htdp.org/
http://gustavus.edu/+max/concrete-abstractions.html
http://www.scheme.com/tspl3/
ftp://ftp.cs.utexas.edu/pub/garbage/...intro_toc.html
http://www.paulgraham.com/onlisp.html (qui est sur Lisp plus que Scheme, mais c'est pas difficile de faire le lien)
http://www.gigamonkeys.com/book/ (idem, c'est un livre sur CommonLisp, mais le travail se rapproche énormément de Scheme)
http://www.norvig.com/paip.html (AI en CommonLisp… un must)
pour les livres version papier:
The Little Schemer et The Seasoned Schemer (http://www.ccs.neu.edu/home/matthias/BTLS/) sont excellents.
Toutes ces ressources sont de très très bonne qualité. Ce sont des livres qui ont fait leurs preuves sur le point de vue pédagogique. Personnellement, j'aimerais trouver des livres aussi bon pour le C++ par exemple, ou même le ocaml (quand je demande à mes étudiants de maîtrise de l'apprendre -_-). Mais je n'en ai jamais vu. La relative jeunesse d'OCaml est peut-être en cause.
En français, un livre formidable par sa richesse d'exemple et de cas est
Programmer avec Scheme de Chazarain
http://www.amazon.com/Programmer-ave.../dp/2841801314
TU as du trouver ça de Queinnec
http://www.infop6.jussieu.fr/cederoms/li101/
Voici aussi un cours en ligne
http://users.info.unicaen.fr/~marc/ens/deug/
Va voir ce site qui possède des liens et des références de livre papier. Il est très intéressant.
http://deptinfo.unice.fr/~roy/
Il enseigne Scheme et met ses cours sur son site.
Moi les miens ne valent rien si je ne suis pas là pour gesticuler devant les acétates
Sinon, tapes « tutorial scheme » sur google, et choisi un des 8 millions de résultats -_- Tu peux aussi faire cette recherche en sélectionnant « french » en langage. Il reste encore 16000 liens.
pas mal de choses interessantes en effet, y a de quoi faire
La science est ce que nous comprenons suffisamment bien pour l'expliquer à un ordinateur. L'art, c'est tout ce que nous faisons d'autre.
Donald E. Knuth
C'est vrai que OCaml te permet de tout faire quasiment (ce qui ne veut pas dire qu'il te permet de faire n'importe quoi contrairement au C), mais n'ais crainte, il suffit que tu exclus certaines choses et tu seras quasiment assuré de faire bel et bien du fonctionnel.
si tu n'utilises pas de boucles for ni de boucles whiles, et si tu n'utilises pas le caractere '!', le :=, et le mot clef ref, et bien tu es quasiment assuré de faire de la programmation fonctionnelle.
par exemple:
et
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 variable := "truc"
ça ce n'est pas "fonctionnel"
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 !variable
quand tu fais :
c'est une premiere variable x qui vaut 1, et une autre variable x qui vaut 2 et qui occulte la premiere. Ce n'est pas la meme variable qui prend successivement les deux valeurs. La preuve : le compilateur te dis "Warning : unused variable x." tu te dis "mais, c'est bizarre, je l'utilise à la fin ma variabile x", oui, celle qui vaut 2, mais celle qui vaut 1 n'est jamais utilisé. C'est donc bien la preuve que ce n'est pas la même.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 let x=1 in let x=2 in x
C'est "fonctionnel"
quand tu fais :
Ici c'est la meme variable x qui pointe d'abord sur la valeur 1, puis ensuite sur la valeur 2. Là c'est un peu comme tu ferais avec un pointeur en C, tu declares x qui est un pointeur sur l'entier 1, ensuite tu fais pointer x sur l'entier 2, puis ensuite tu récuperes ce sur quoi pointe x.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 let x = ref 1; x:= 2; !x
Ce n'est pas "fonctionnel"
(J'espere que je ne dis pas de bêtises, les autres me corigeront)
Pour éviter de faire de la programmation objet, et bien... il suffit de ne pas utiliser les objets A noté qu'un module n'est pas un objet (pas d'héritage par exemple).
La c'est bien, c'est fonctionnel, c'est pas des champs mutables. Si tu avais fait ceci alors ça aurait été des champs mutables :
La tes champs sont mutable, ce ne sont pas des float, ce sont des réference sur un float.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 # type complexe = { re: float ref; im : float ref} ;; type complexe = { re : float ref; im : float ref; } # let z1 = ref {re= ref 0. ; im = ref 3.14 } ;; val z1 : complexe ref = {contents = {re = {contents = 0.}; im = {contents = 3.14}}}
De même z1 est mutable car c'est maintenant une référence sur ta structure, (ce que tu n'as pas fait). En enlevant le mot clef ref de la seconde ligne, z1 n'est pu mutable.
Tu dis ça comme si le typage statique et les types implicites (inférence de type) n'est pas une bonne chose. Certe je comprends que ça puisse te faire un changement d'habitude, mais tu dois savoir que c'est mieux qu'un langage fasse ces deux choses
le typage statique ça veut dire que si ton programme plante à cause d'une erreure de typage, il plantera seulement à la compilation, et non pas à l'execution quand l'utilisateur (le client, ou la fusée arianne 5 qui est sencé l'utiliser) l'executera.
l'inference de type c'est l'idée que : un programeur humain c'est inteligent, mais il reste un humain et peut faire des erreures, donc si on trouve un moyen de faire la meme chose par un ordinateur alors on est sur que ça marchera toujours. C'est ce qui est fait ici, l'inférence de type s'occupe à ta place de déterminer quel type il faut pour une variable, et l'ordinateur ne se trompe jamais. (en tout cas en OCaml il ne se trompe jamais).
C'est un peu comme le garbage colector, pourquoi laisser l'humain se planter de temps en temps en faisant un free alors qu'il aurait pas du le faire, alors qu'on peut ne jamais se planter en l'automatisant? C'est la même idée.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager