L'apprentissage d'un langage fonctionnel fait-il un meilleur programmeur OOP? [fermé]

28

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?

GavinH
la source
3
Si vous codez en C #, vous en connaissez déjà un. LINQ est une chose assez fonctionnelle.
SK-logic
Je pense que la POO est meilleure pour modéliser des objets de la vie réelle.
Tulains Córdova
1
@ user61852 La plupart des modèles de conception OO ne modélisent rien sur les objets "réels", mais en réalité des concepts très abstraits.
Andres F.
Soyez plus qu'un programmeur Java / C # (+ C ++). Il y a une différence entre un gigantesque couteau de l'armée suisse avec un dépliant pas si petit qui explique pourquoi vous choisiriez la lame X sur 40 et une lame que vous pouvez tailler à peu près tout ce que vous voulez car c'est à la fois sacrément pointu et courbes juste droit de telle sorte que vous pouvez appliquer son pouvoir de coupe à une grande variété de circonstances sans trop y penser. (avec un ouvre-bouteille dans la poignée bien sûr)
Erik Reppen

Réponses:

32

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.

Aidan Cully
la source
@Aidan: wrt lambdas en C ++ 0x, en tout cas les nouveaux compilateurs C ++ les ont déjà incorporés.
Matthieu M.
1
«Objet» en tant que «chose qui détient un état mutable» est très courant, mais le modèle d'objet de valeur existe depuis de nombreuses années.
Frank Shearar
@Matthieu, merci, j'ai mis à jour le texte pour refléter cela.
Aidan Cully
@Frank: merci pour le pointeur. Je n'ai pas inclus cela dans la réponse, mais l'objection principale que j'ai à faire des valeurs en objets a à voir avec la distinction des interfaces d'objet n / b (qui appartiennent à des objets) et des opérations (dans lesquelles les relations entre les objets sont plus primaire que les objets eux-mêmes). 1 + 2est mathématiquement équivalent à 2 + 1, mais 1.+(2)est implémenté différemment de 2.+(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.
Aidan Cully
1
@Aidan Avez-vous lu «Sur la compréhension de l'abstraction des données, revisité» de William Cook? Il explore les différences entre les objets et les ADT, ce à quoi vous faites allusion.
Frank Shearar
32

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.

FrustratedWithFormsDesigner
la source
3
Étant donné que les objets sont en fait des fonctions d'ordre supérieur, j'ai trouvé que l'apprentissage des choses FP m'a aidé directement avec mon POO. C'est, comme vous le dites, plus généralement applicable / utile.
Frank Shearar
12

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.

Michael K
la source
Vous constaterez que cela aide également les bibliothèques de threads, qui ont tendance à attendre des fonctions pures comme tâches. Cela peut aussi aider indirectement, il y a des endroits où j'écrirai du code OO dans une sorte de "style fonctionnel" où il y a un "paramètre propriétaire" qui a un verrou implicite sur un tas d'objets qu'il référence et qui sont utilisés par la fonction . Tant que vous documentez vos attentes (et les testez à l'unité), cela peut vous donner un meilleur code multithread avec peu de problèmes de verrouillage. Et quelques verrous explicites.
Je n'ai jamais entendu parler de Prolog comme un langage fonctionnel. Si je plisse les yeux, je peux vaguement voir comment (certaines parties de) Prolog pourraient aider avec la PF.
Frank Shearar
1
Prolog n'est pas un langage fonctionnel. C'est un langage logique. Si vous voulez un langage logique de type Prolog qui intègre également une programmation fonctionnelle, sachez que vous pouvez vous intéresser à Mercury . Attention: cela vous fera un peu mal au cerveau même si vous connaissez déjà Prolog.
JUSTE MON AVIS correct le
@JUST MON AVIS correct: Oui, je pense que vous avez raison. Je dois certainement en savoir plus sur les langages fonctionnels!
Michael K
1
@moz: Oui, je souhaite que Java ait des lambdas. Les Threadobjets anonymes sont ... maladroits.
Michael K
9

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.

JUSTE MON AVIS correct
la source
3

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!

Jetti
la source
3

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.

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?

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.

En quoi améliore-t-il vos compétences en programmation?

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.

jhuni
la source