J'ai lu beaucoup de discussions sur les langages de programmation fonctionnels récemment (presque au cours de la dernière année, en fait). J'aimerais vraiment en choisir un et l'apprendre à fond.
Au cours du dernier semestre, j'ai été initié à Scheme. Je l'ai aimé. J'ai adoré l'extrême simplicité de la syntaxe, le principe homoiconicité , les macros ( hygiénique et non hygiénique), la n-arité des procédures, etc.
Le problème avec Scheme est que c'est une langue académique. Je ne pense pas qu'il soit vraiment utilisé dans des environnements de production. Je ne pense pas non plus qu'il soit particulièrement bon de l'avoir sur notre CV. J'ai donc cherché des alternatives. Il y en a beaucoup et ils semblent tous avoir un niveau de popularité similaire.
Quelques réflexions sur d'autres langages fonctionnels que j'ai encore envisagés:
Ce soir, je me penche vers LISP. Il y a une semaine, c'était Haskell. Avant cela, c'était Clojure. Au cours de la dernière année, je faisais un programme pour le plaisir, sans le pousser pour la raison que vous connaissez. Maintenant, je voudrais être sérieux (en apprendre un, en faire de vrais projets avec lui, peut-être éventuellement en travailler professionnellement). Mon problème est que j'aurais besoin de les apprendre tous en profondeur avant de pouvoir en choisir un.
Puisque vous voulez une langue pratique :
Notez que Haskell et LISP sont plus utilisés que les autres dans l'industrie, bien qu'il y ait eu un certain intérêt récent pour Clojure et F #.
Mais regardez ce qui se passe lorsque nous ajoutons Scheme au mélange:
Hmm, ça ne ressemble plus tellement à une langue académique maintenant, n'est-ce pas?
En fait, le graphique ci-dessus est probablement un mensonge; le mot "schéma" peut apparaître dans les annonces d'aide recherchée dans d'autres contextes que les langages de programmation. :)
Voici donc un autre graphique qui est probablement (un peu) plus représentatif:
Si vous voulez explorer un dialecte vraiment génial de Scheme, jetez un œil à Racket.
Si vous voulez apprendre la programmation fonctionnelle, vous pourriez être mieux servi à apprendre d'abord Haskell, puis utilisez le langage que vous voulez. Vous pouvez apprendre la programmation fonctionnelle en utilisant les autres langages, mais ils permettent toujours un code impératif et orienté objet. Si vous écrivez un vrai programme dans Haskell, vous apprendrez plus rapidement la programmation fonctionnelle car les autres paradigmes ne seront pas disponibles pour se replier.
Après avoir écrit votre programme Haskell, vous aurez des outils comme des monades et des techniques comme le codage sans point à apporter à la langue de votre choix. Les concepts semblent correspondre particulièrement bien à Scheme.
En fait, si vous pouviez implémenter un système raisonnablement complexe dans Scheme, vous seriez assez souhaitable dans les entreprises où vous voudriez probablement travailler. Plus tôt dans ma carrière, j'ai rencontré des étudiants qui avaient effectué une bonne partie du travail dans le cadre du programme, et la seule fois où cela a été un inconvénient, c'est quand ils étaient incapables d'expliquer leur travail ou ne le comprenaient pas assez bien pour mettre en œuvre les données de base. structures et algorithmes dans un délai raisonnable. Je laisse toujours les candidats répondre à ces questions dans leur langue préférée; J'ai rencontré des gens qui pensaient être les meilleurs à Scheme et qui ont réussi à lutter un peu avec des choses qui devraient être faciles, comme ajouter un élément à une liste chaînée, ce qui m'a mystifié.
Mais si vous pouviez "obtenir" assez bien Scheme pour écrire même une application web moyenne, ce serait un très bon argument de vente dans la plupart des sociétés de logiciels sérieuses.
Si vous interviewiez dans une boutique "blub" et que les développeurs pensaient que vous étiez bizarre à cause de votre compétence chez Scheme ou Haskell ou F #, vous ne voudriez probablement pas y travailler. Dans la plupart des cas, les développeurs compétents obtiennent leur choix de concerts, alors ne vous inquiétez pas du "côté pratique" à moins que les seules options que vous puissiez imaginer dans votre avenir soient d'entreprise. Travaillez à être compétent, flexible et à résoudre les problèmes.
Le collège n'est pas une question de pratique. Il s'agit de créer un environnement sûr pour explorer et apprendre. C'est, en fait, utile, même si vous finissez par écrire des logiciels ordinaires pour le reste de votre carrière.
Cela étant dit, je ne vois pas pourquoi vous voudriez vous limiter à un seul de ces choix si tôt. Vous pourriez facilement avoir une idée des quatre langues en environ 4 semaines, puis en choisir une pour vous concentrer sur ce qui correspond le mieux à vos caprices actuels. Revenez ensuite à une autre de vos options et essayez d'implémenter quelque chose de similaire. Passez à quelque chose de plus complexe et réfléchissez à nouveau à vos options. L'expérimentation est bonne. À moins que vous n'essayiez de gagner votre vie le mois prochain, vous n'avez pas encore besoin de devenir spécialiste.
J'en ai écrit en Scheme, F #, Emacs LISP et Common LISP, et j'ai lu au moins un peu de Haskell, au moins occasionnellement au cours des dernières années. Je ne peux pas dire que je suis un expert dans aucun d'entre eux, mais chaque excursion dans ces langages m'a profité dans tous les autres langages dans lesquels je travaille professionnellement (C #, Java, Ruby, et parfois Boo, Perl et Python). La curiosité vous construira une carrière plus durable et épanouissante qu'autre chose.
J'ai plongé dans Haskell pendant un certain temps, mais la conclusion à laquelle j'ai abouti était que c'était un peu trop académique. Il était très difficile de faire quoi que ce soit de pratique. Dans un langage purement fonctionnel, des choses comme IO ne rentrent tout simplement pas dans le modèle, donc vous devez faire face à des monades. J'ai déterminé que je devrais consacrer beaucoup de temps à être à peine compétent, alors je suis parti.
J'ai fait Scheme à l'université. Cela peut sembler trivial, mais toutes les parens sont vraiment distrayantes/ennuyeuses. Difficile d'y revenir après avoir utilisé des langages comme Python.
Récemment, j'ai exploré F #. Il est fonctionnel, mais peut également être impératif et orienté objet lorsque vous le souhaitez. Ceci, en plus de pouvoir utiliser toutes les bibliothèques .NET, permet de mélanger facilement vos parties fonctionnelles pures avec des choses plus pratiques comme les interfaces graphiques, IO et la mise en réseau. Vous pouvez obtenir une version autonome de F#.
J'ai évalué tous les principaux langages fonctionnels il y a un an ou deux, dans la perspective de vouloir un langage de programmation fonctionnel pratique et polyvalent.
J'ai fini par choisir Clojure , ce qui s'est avéré par la suite être un excellent choix.
De manière générale, les principales raisons étaient les suivantes:
Écosystème de bibliothèques - pour qu'une langue soit utile, vous devez avoir accès à de bonnes bibliothèques. Être sur la JVM signifie que vous avez un accès facile à la plus grande bibliothèque open source et à l'écosystème d'outils, donc opter pour un langage JVM était une évidence dans une perspective pragmatique. Scala a également obtenu un score élevé ici.
Macro-métaprogrammation - Cet aspect de LISP m'a toujours séduit, d'autant plus que je prévoyais de faire pas mal de génération de code. J'ai beaucoup apprécié les arguments avancés dans le court essai de Paul Graham " Beating The Averages ". Les différents Lisps ont tous marqué fortement ici.
Les performances étaient "assez bonnes" - Clojure est toujours compilé et bénéficie des avantages de l'optimiseur JVM JIT et d'un excellent GC. Comme toujours, il y a des frais généraux dans l'utilisation d'un langage fonctionnel, mais avec Clojure, il était clair que chacun pouvait se rapprocher de Java vitesse avec un peu d'effort (Clojure prend en charge Java primitives et typage statique optionnel pour les situations où vous en avez besoin.) Mon estimation est que Clojure est approximativement 2 à 5 fois plus lent que ce que vous pourriez obtenir avec un Java ou code C++, qui est cohérent avec ce que vous voyez dans les benchmarks imparfaits , et au fil du temps, je m'attends à ce que cet écart se resserre. De plus, il est assez facile d'écrire simplement du code particulièrement sensible aux performances en pur Java et appelez-le depuis Clojure.
Concurrence - Clojure a une approche assez unique et puissante de la concurrence, en particulier pour la concurrence hautement multicœur. C'est un peu difficile à expliquer, mais cette vidéo est excellente pour donner un avant-goût des principes. Je pense que Clojure a actuellement la meilleure réponse à la question délicate "comment devriez-vous gérer l'état partagé, simultané et mutable dans un langage de programmation fonctionnel?".
Conception de langage - Clojure est IMO une conception de langage très bien pensée. Les exemples incluent les littéraux vector [] et map {} en plus des parenthèses LISP régulières, l'utilisation de structures de données persistantes immuables, la paresse dans toute la langue via l'abstraction de séquence et la fourniture au programmeur d'une variété de fonctionnalités orthogonales pour résoudre différents problèmes . Voir l'art de l'abstraction et simple rendu facile .
Communauté - toujours subjective, mais j'ai aimé ce que j'ai vu dans la communauté Clojure. L'attitude a été très utile, constructive et pragmatique. Il y a une forte emphase sur "faire avancer les choses", reflétant peut-être le fait que beaucoup de gens de Clojure (y compris Rich Hickey lui-même) viennent de la construction de systèmes d'entreprise complexes. Le fait que la communauté Clojure ait des liens étroits avec la communauté Java également était important pour me convaincre que Clojure ne courrait pas le risque de se retrouver coincé dans une "niche".
Si je devais nommer quelques inconvénients mineurs de Clojure, ce serait:
Typage dynamique - souvent c'est un avantage en termes de productivité, mais en moyenne, je pense que je pourrais l'échanger contre une vérification et une inférence de type plus fortes. Généralement, cela est atténué par une bonne suite de tests automatisés, mais si vous aimez vos types validés statiquement par le compilateur, alors Haskell ou Scala peut être plus votre tasse de thé).
Cutting Edge - Clojure se développe très rapidement et il y a beaucoup d'innovation en cours - l'inconvénient est qu'il y a beaucoup d'expérimentation, certaines bibliothèques et les outils sont encore immatures, et il y a des changements de rupture occasionnels entre les principales versions de Clojure que vous devez surveiller.
Dans l'ensemble cependant, je ne pense pas que vous pouvez vous tromper avec Clojure si vous voulez un langage fonctionnel moderne excellent et pragmatique!
Il semble que vous ayez fait vos devoirs, vous le savez probablement déjà, mais Scheme est un dialecte de LISP tout comme Common LISP. Si vous aimez beaucoup de choses sur Scheme, mais que vous n'aimez pas sa nature académique, essayez Common LISP. Selon le indice TIOBE , il s'agit de la 13ème langue la plus populaire par rapport au schéma en position 26.
Peu de langues que vous avez mentionnées apparaissent sur les descriptions de travail que j'ai vues récemment, bien que cela puisse être mon petit échantillon. Personnellement, j'apprendrai Haskell, même si je ne m'attends pas à utiliser cette langue directement dans mon travail. Les concepts de programmation fonctionnelle sont plus précieux pour moi pour la conception de programmes futurs que la commercialisation directe du langage lui-même.