En tant que programmeur Java / C # / C ++, j'entends beaucoup parler de langages fonctionnels, mais je n'ai jamais trouvé le besoin d'en apprendre un. J'ai également entendu que le niveau de réflexion plus élevé introduit dans les langages fonctionnels fait de vous un meilleur programmeur de langage POO / procédural.
Quelqu'un peut-il confirmer cela? En quoi améliore-t-il vos compétences en programmation?
Qu'est-ce qu'un bon choix de langue à apprendre dans le but d'améliorer les compétences dans une langue moins sophistiquée?
Réponses:
Je suis fondamentalement d'accord avec la réponse de FrustratedWithFormsDesign , mais vous avez également demandé comment l'apprentissage du nouveau paradigme aide à développer ses compétences. Je peux donner quelques exemples tirés de ma propre expérience.
Depuis l'apprentissage de la programmation fonctionnelle, je suis beaucoup plus conscient des concepts avec lesquels je travaille sont plus naturellement considérés comme des "objets" (généralement où la mutation a du sens) et qui sont plus naturellement considérés comme des "valeurs" immuables (je pense qu'il y a une distinction importante , en abordant où OO a du sens par rapport à quand FP a du sens, mais c'est juste mon opinion).
Je remarque où mon code inclut des effets secondaires, et je fais plus attention à isoler ces endroits, rendant plus de mes fonctions "pures". Cela améliore considérablement la testabilité de mon code OO.
Je suis plus conscient des cycles dans ma représentation des données. (Par exemple, je ne pense pas que vous puissiez écrire une fonction pour convertir une liste chaînée en une liste doublement liée dans Haskell, donc vous remarquez beaucoup plus de cycles dans ce langage.) Éviter les cycles réduit la quantité de synchronisation vous devez effectuer pour que vos structures de données soient cohérentes en interne, ce qui simplifie le partage de ces structures entre les threads.
Je suis plus susceptible de compter sur la récursivité (les constructions en boucle récursive du schéma sont des choses de beauté). Dijkstra a souligné l'importance de cela dans les Notes sur la programmation structurée - les algorithmes récursifs sont très directement liés à l'induction mathématique, ce qui, selon lui, est le seul moyen de prouver intellectuellement que nos boucles sont correctes. (Je ne suggère pas que nous devons prouver que notre code est correct, mais que plus nous le faisons facilement pour nous-mêmes, plus il est probable que notre code est correct.)
Je suis plus susceptible d'utiliser des fonctions d'ordre supérieur. L'article de John Hughes, Why Functional Programming Matters . Il met l'accent sur la composabilité que vous obtenez en utilisant des techniques de programmation fonctionnelles, des fonctions d'ordre supérieur jouant un rôle majeur.
En outre, comme évoqué dans la réponse de Jetti , vous constaterez que de nombreuses idées de PF sont intégrées dans les nouveaux langages OO. Ruby et Python fournissent tous les deux de nombreuses fonctions d'ordre supérieur, j'ai entendu LINQ décrit comme une tentative d'apporter le support des compréhensions monadiques en C #, même C ++ a maintenant des expressions lambda.
la source
1 + 2
est mathématiquement équivalent à2 + 1
, mais1.+(2)
est implémenté différemment de2.+(1)
. Il existe un certain nombre de problèmes SW qui peuvent être compris plus naturellement en utilisant des opérations qu'en utilisant des interfaces d'objet.Je ne dirais pas que cela fera de vous un meilleur programmeur de POO, mais cela vous présentera une nouvelle façon de penser, et cela pourrait vous aider à résoudre les problèmes en général, pas seulement en termes de POO.
la source
L'apprentissage d'un langage fonctionnel - Lisp pour moi - aide vraiment lors de la création d'applications parallèles. Les méthodes fonctionnelles (basées sur l'état, sans effets secondaires) sont beaucoup plus faciles à synchroniser et sont plus faciles à sécuriser les threads car elles ne dépendent que de leur entrée. Cela signifie que les seules données dont vous avez besoin pour surveiller une zone de code donnée sont les paramètres que vous transmettez. Cela facilite également le débogage.
la source
Thread
objets anonymes sont ... maladroits.L'apprentissage de tout autre paradigme de programmation améliorera vos compétences en programmation en général. La programmation, quand ce n'est pas du matériel académique (et même souvent, souvent), résout essentiellement les problèmes. Penser, en un mot. Les différents paradigmes sont différentes façons de penser les problèmes et leurs solutions. Alors ne pensez pas seulement à cela comme "l'apprentissage d'un langage fonctionnel". Considérez-le comme «apprendre une façon différente de penser aux problèmes et à leurs solutions». Ensuite, vous verrez les avantages d'apprendre une langue même si vous ne l'utilisez jamais réellement.
Pour répondre à votre question spécifique, j'étais un programmeur C ++ à l'époque d'antan (avant qu'il n'y ait une norme pour C ++). J'ai suivi toutes les choses habituelles avec des objets dont l'état était manipulé par des méthodes, etc. etc. etc. Puis je suis tombé sur Haskell et j'ai appris (une grande partie). (Je ne pense pas que quiconque apprenne vraiment Haskell.) L'exercice semblait un peu gaspillé à l'époque jusqu'à ce qu'un de mes collègues, le testeur affecté à mon groupe, fasse un commentaire désinvolte que mon code devenait plus facile à tester.
Ce qui s'était passé, c'est que j'avais commencé à rendre mes objets de plus en plus immuables. Les classes avec un état mutable complexe ont commencé à être remplacées par des classes qui se clonaient avec des modifications, renvoyant les nouveaux objets. Les objets partagés ont commencé à être remplacés par des objets qui avaient une sémantique de copie sur écriture (donnant ainsi l'illusion de beaucoup de clones d'objets sans surcharge de mémoire). Les fonctions n'ont eu d'effets secondaires que si elles étaient absolument nécessaires; la définition mathématique pure de la «fonction» est de plus en plus la norme. Tout cela a commencé à se produire naturellement dans mon code - aucune pensée consciente n'a été impliquée - alors que j'explorais de plus en plus l'espace de programmation fonctionnel.
Maintenant, je me fais un objectif d'apprendre au moins un nouveau paradigme de programmation tous les deux ans (même s'il ne s'agit que d'un paradigme d'extension mineur comme AOP) et d'au moins deux nouveaux langages au sein de chaque paradigme (un aussi pur que possible, un de plus hybride / pratique ). Chacun m'a donné de nouveaux outils intellectuels à appliquer à l'ensemble de ma programmation dans n'importe quelle langue, donc le temps passé à les apprendre n'a pas, à mon avis, été même un peu perdu.
la source
Je l'ai déjà dit et je le répète, l'apprentissage des langages fonctionnels a définitivement amélioré mon C #. Cela m'a aidé à comprendre les lambdas (et m'a aidé à les aimer). Cela m'a également fait réaliser à quel point je préfère la programmation fonctionnelle (F #) lorsque je travaille avec des opérations asynchrones!
la source
Le code machine n'est rien d'autre qu'une liste d'effets secondaires - des commandes qui sont directement exécutées par le processeur. Les effets secondaires en C sont différents, plutôt que de gérer les registres et le matériel physique, vous traitez un ensemble d'abstractions et laissez le compilateur faire tout le sale boulot. C vous permet également de structurer vos effets secondaires en boucles et en instructions if then. C ++ améliore le C en ajoutant la POO et certaines fonctionnalités indispensables au langage. Java et C # ajoutent un ramasse-miettes et Python ajoute un typage dynamique.
Même avec toutes ces fonctionnalités - typage dynamique, garbage collection, etc. les programmes dans ces langages sont toujours entièrement basés sur des effets secondaires. Les langages de programmation fonctionnels, comme Scheme, Clojure, Haskell et ML sont quelque chose de complètement différent, ces langages sont plus proches des mathématiques que du code machine. Plutôt, en utilisant des effets secondaires, vous transmettez des valeurs autour des fonctions.
Je recommande Scheme , il est minimal et il a été utilisé dans les anciennes classes de programmation d'introduction du MIT. Les autres langages de programmation fonctionnels sont beaucoup plus difficiles à apprendre. Clojure apporte toutes les subtilités de Java avec lui, ML apporte un système de type statique compliqué, Haskell est parfois appelé un langage académique - il n'est pas idéal pour les débutants, etc. Le schéma, d'autre part, est facile à apprendre et à comprendre.
Presque tous les langages de programmation de haut niveau ont des fonctions et une récursivité - les concepts sur lesquels la programmation fonctionnelle est basée. En tant que tel, votre connaissance de la PF devrait être utile presque partout, cependant, si vous voulez vraiment programmer de manière fonctionnelle, vous devez utiliser un langage où il est naturel et efficace plutôt que d'essayer de plier la conception du langage de quelqu'un d'autre à votre goût, c'est-à-dire vous devez utiliser un langage de programmation fonctionnel pour faire de la programmation fonctionnelle.
la source