Modèles mentaux ou métaphores du monde réel pour la programmation fonctionnelle

16

Quelqu'un a-t-il un bon modèle mental ou une bonne métaphore pour la programmation fonctionnelle qui fait référence à quelque chose dans le monde réel?

La programmation orientée objet a un sens intuitif pour moi. Il y a des choses qui ont des propriétés et parfois elles peuvent aussi faire des choses ou effectuer des calculs sur leurs propriétés (méthodes). (Ex: voiture, forme, chat).

Je ne supporte aucune programmation fonctionnelle et je ne suis pas intéressé par un débat sur les vertus des deux. J'ai juste besoin d'une métaphore ou d'un modèle mental pour travailler comme je l'ai fait avec la programmation orientée objet.

Quels sont les bons modèles mentaux ou les métaphores du monde réel pour la programmation dans un paradigme fonctionnel? Il y a quelque chose dans les fonctions composées de fonctions de traitement de fonctions qui laisse une personne sans place ferme pour se tenir debout et cogiter.

Guido Anselmi
la source
À quelle signification concrète de «programmation fonctionnelle» faites-vous référence, «pas d'effets secondaires / déclaratifs» ou «fonctions de première classe / composition de fonctions»? Ou les deux?
acelent
Question interessante. Avec ma petite connaissance actuelle et ma faible expérience de la programmation en «programmation fonctionnelle», je ne peux pas répondre de manière significative à cette question. Si je devais deviner une supposition, je dirais les deux.
Guido Anselmi
13
Le modèle "du monde réel" est souvent donné comme motivation pour une programmation orientée objet. Je pense que c'est une approche que vous devriez éventuellement dépasser, car les objets dans la POO ne doivent pas toujours correspondre à des objets du monde réel, et même lorsqu'ils le font, la correspondance est souvent incomplète; par exemple, les relations «est-un» ne sont pas toujours les mêmes. D'un autre côté, une fois que vous dites que vous voulez un modèle ou une métaphore pour un langage de programmation basé sur quelque chose dans le "monde réel", je pense que vous vous êtes essentiellement limité à cette forme limitée de POO.
David K
Un très bon modèle mental, si vous avez de l'expérience en utilisant des systèmes de type Unix (ou le PowerShell dans Windows moderne) est le shell one-liners. Ils ne sont pas exactement les mêmes, car les tubes shell sont une programmation basée sur les flux au lieu de fonctionnels, mais ils ont la même "sensation" qu'un programmeur.
slebetman
1
De plus, vous trouverez au fur et à mesure que vous apprendrez des langages fonctionnels, en programmation fonctionnelle orientée objet est traitée comme un outil, comme les expressions régulières par exemple. Quelque chose que vous pouvez utiliser si vous le souhaitez mais que vous n'avez pas à le faire. Dans certaines langues comme lisp et tcl et-vient OO n'est pas une fonctionnalité intégrée à la langue mais une bibliothèque que vous pouvez utiliser (ou vous pouvez même écrire votre propre OO si vous vous sentez courageux). Ainsi, les problèmes qui ont naturellement une solution OO peuvent être résolus en utilisant OO dans la plupart des langages fonctionnels. Les gens ne considèrent tout simplement pas l'OO comme une religion.
slebetman

Réponses:

32

La programmation fonctionnelle consiste à coller des fonctions plus petites pour obtenir vos résultats. Un modèle mental décent (pour moi, au moins) est une chaîne de montage. Chaque fonction qui est composée est une étape de plus dans le processus d'assemblage. Considérez cette fonction ici:

smallest  = head . sort

Dans Haskell, cette fonction renverra le plus petit élément d'une liste. La chaîne d'assemblage trie d'abord l'entrée, puis retourne le premier élément (en supposant qu'il est trié du moins au plus grand.) Si nous voulions obtenir uniquement la plus petite valeur paire, nous pouvons changer la ligne d'assemblage pour ressembler à ce qui suit:

smallestEven = head . sort . filter even

Ce n'est qu'un pas de plus sur la bande transporteuse.

En un mot, les fonctions décrivent simplement les étapes prises pour convertir l'entrée brute (les pièces) en bien traité (la sortie).

bstamour
la source
2
Dans un langage fonctionnel pur sans variables globales, alors une ligne d'assemblage ne peut pas affecter l'autre (sauf si elle alimente l'autre entrée de ligne.) Théoriquement, toutes les lignes d'assemblage qui ne dépendent pas les unes des autres peuvent être exécutées en parallèle, mais je ne le suis pas sûr si des compilateurs le font.
bstamour
3
@GuidoAnselmi Une façon d'y penser est que la chaîne de montage dans la programmation fonctionnelle crée de nouvelles sorties tout en laissant les entrées intactes, tandis que la ligne de montage dans la POO traditionnelle transforme l'entrée.
Doval
2
Cette métaphore n'a de sens que dans le sens de "fonctions de première classe / composition de fonctions" de "programmation de fonctions", et non dans "pas d'effets secondaires / déclaratifs". De plus, la programmation orientée objet n'a pas nécessairement d'effets secondaires, vous pouvez donc implémenter une chaîne de montage destructrice ou constructive avec OOP ou cette signification de FP. La POO concerne plus l'encapsulation, le passage de messages et le polymorphisme que les effets secondaires, cela dépend de la façon dont vous modélisez les choses. Par exemple, avez-vous besoin d'une identité référentielle du début à la fin?
acelent
3
@bstamour: Pour être précis, il faut écrire que des (f . g) (x)moyens f(g(x))ou des f . gmoyens \x -> f (g (x)).
Giorgio
3
@MarjanVenema Les choses restent à gauche dans cet exemple uniquement parce que c'est comme cela que l' .on définit; ce n'est pas ainsi que fonctionne Haskell en général . Vous pourriez tout aussi bien définir l'opérateur de tuyau avant de F # ( |>) dans Haskell et écrire smallest x = (sort x) |> headet les données circuleraient correctement. Je pensais juste le souligner.
Doval
18

Quelqu'un a-t-il un bon modèle mental pour la programmation fonctionnelle?

Mathématiques. La programmation fonctionnelle est inspirée et modelée sur les mathématiques. Les fonctions mathématiques n'ont pas d'état, n'ont pas d'effets secondaires, etc., et il en est de même avec FP. Si vous pensez à FP en termes de fonctions mathématiques plutôt que d'utiliser une approche de type OO "comment puis-je faire cela", vous serez en bonne forme. Cependant, si vous essayez d'apporter des sensibilités OO à la PF, vous nagerez à contre-courant.

Caleb
la source
1
Merci. Cependant, j'ai besoin d'une métaphore du monde réel (par exemple pas des ordinateurs ou des mathématiques).
Guido Anselmi
3
@GuidoAnselmi: Une fonction est une boîte noire. Vous mettez quelque chose d'un côté, puis quelque chose de nouveau sort de l'autre côté. Si vous mettez les mêmes éléments, vous en retirez toujours les mêmes. Vous pouvez prendre beaucoup de ces petites boîtes et les combiner dans différentes commandes pour construire une usine qui pourrait absorber des métaux bruts et produire une voiture. À l'intérieur, le processus est divisé en plusieurs morceaux, mais de l'extérieur, c'est juste une autre fonction.
Daenyth
16

Que diriez-vous d'un flip book ?

Dans un flip book, chaque page représente le monde tel qu'il existe à un moment donné. Dans notre programme, le monde est représenté comme une structure de données composée (par exemple, nous avons une banane qui est dans la main d'un gorille qui est dans un arbre qui est dans une jungle). Chaque page suivante fait avancer l'histoire en modifiant légèrement la représentation précédente. Dans FP, les structures de données persistantes ont été conçues pour réutiliser efficacement les structures précédentes afin qu'un changement ne fournisse qu'un delta et non un rendu complètement nouveau.

Ce qui peut ne pas être évident, c'est qu'une page de notre flip book représenterait également des actifs incorporels. Par exemple, si le gorille laisse tomber la banane, nous pourrions commencer à appliquer les effets de la gravité sur sa décente et son accélération vers le sol de la jungle. Pour s'adapter à cela, nous attacherions des attributs tels que la vitesse et la trajectoire à notre banane.

Dans notre programme, il y aurait une fonction qui accepte une page de flip book (alias l'état du monde) comme argument et génère une nouvelle page . De cette manière, notre histoire est racontée sans jamais réellement changer l'état des objets existants. Nous remplaçons simplement chaque page par une nouvelle en utilisant ce qui est effectivement un calcul.

Mario T. Lanza
la source
3

Des relations.

Ami: Étant donné deux personnes, une relation d'ami suit ces lois générales

  1. Ayez de la bonne volonté les uns envers les autres
  2. Pense que l'autre est un ami pour eux (donc les lois doivent être respectées par les deux membres dans cette relation)
  3. Aime passer du temps ensemble

Monoïde: étant donné plusieurs éléments et une fonction qui prend 2 des éléments et renvoie 1, une relation monoïde suit ces lois générales

  1. Il y a un de ces éléments (un seul, appelé identité) qui est passé à la fonction avec tout autre élément garantira que la fonction renvoie toujours l' autre élément (0 + 1 = 1, donc 0 est l'identité lorsque les éléments sont des nombres et le la fonction est l'addition)
  2. La fonction ne peut pas fonctionner ou renvoyer des éléments qui ne sont pas dans l'ensemble avec lequel elle a une relation monoïdale.
  3. La fonction est associative et peut être utilisée avec les éléments d'une manière quelque peu indépendante de l'ordre, cela signifie a * (b * c) = (a * b) * c qui dit que vous pouvez multiplier a par le résultat de b * c ou c par le résultat de a * b et le résultat sera le même que vous fassiez en premier.

La programmation fonctionnelle est une question de généralisation, l'ami est une relation très générale qui peut être vue dans de nombreux scénarios, mais dans tous les différents formats, elle suit généralement les lois ci-dessus.

En reconnaissant les lois qui régissent les relations entre les choses, vous pouvez créer des implémentations générales qui fonctionnent sur n'importe quel format de choses ayant ce type de relation. Dans la programmation fonctionnelle, vous essayez d'identifier les relations entre les choses afin qu'elles puissent être classées et traitées en général.

Vous voulez une métaphore du monde réel? Regardez comment les choses sont liées et essayez d'identifier les lois générales (comme cela s'applique à plusieurs scénarios où des choses autres que les lois peuvent varier). Il y a une relation entre un commis au registre et un acheteur dans un magasin, il a des lois générales, un logiciel a été développé pour faciliter les objectifs des personnes dans cette relation générale à la manière des systèmes de point de vente. De même, lorsque vous commencez à voir ces lois générales dictant la façon dont les choses sont liées, vous pouvez commencer à vous fier aux lois de ces relations pour écrire votre logiciel plutôt qu'aux détails spécifiques d'une instance de relation.

Jimmy Hoffa
la source
2

Tout est une valeur, et vous appliquez des fonctions à des valeurs (qui peuvent être des fonctions) pour produire de nouvelles valeurs, de préférence sans produire d'effets secondaires.

Doval
la source
Merci. Malheureusement, cela ressemble plus à une description qu'à un modèle mental ou à une métaphore. J'ai besoin d'une métaphore du monde réel (pas d'ordinateurs).
Guido Anselmi
1
Comme le souligne Caleb , la programmation fonctionnelle modélise les mathématiques, pas le monde réel. Il peut modéliser le monde réel à travers la lentille des mathématiques, mais vous ne trouverez probablement pas de métaphore qui vous satisfasse, car FP évite le concept des choses avec une identité persistante et un état mutable. Si vous le souhaitez, je peux indiquer comment les constructions OOP sont mappées sur FP, mais ce ne sera toujours pas la réponse que vous souhaitez.
Doval
Mais les mathématiques sont basées sur le monde réel. 1 soleil, 9 planètes. 2 pommes plus 2 pommes font quatre pommes.
Guido Anselmi
Et dans la programmation fonctionnelle, vous pouvez également avoir un type pour les soleils, les planètes et les pommes, puis créer une valeur de type soleil, 9 valeurs de type planète et définir l'addition pour le type de pomme.
Doval
3
@GuidoAnselmi vous l'avez complètement à l'envers, les gens analysent le monde réel avec les mathématiques, il n'a aucune base sur le monde réel. Les mathématiques sont utilisées pour analyser et définir les relations entre toutes sortes de choses, réelles et non. 9 planètes consiste à appliquer une construction mathématique (l'ensemble des nombres naturels) à une construction du monde réel (planètes) avec une fonction d'analyse mathématique (nombre). Le monde réel n'a pas 9 planètes, il a ce qu'il a, les mathématiques parlent simplement de représentations symboliques des choses dans lesquelles les symboles ont des relations entre eux.
Jimmy Hoffa
1

La chose clé à réaliser à propos de la programmation fonctionnelle est que tout est une valeur - même le code lui-même est des «valeurs».

Le meilleur exemple d'un environnement de programmation fonctionnel simple est celui de l'outil professionnel préféré de tous - la feuille de calcul. Chaque cellule de la feuille de calcul est soit des données, soit le résultat d'une fonction. De plus, cette fonction ne peut pas désactiver et modifier une autre cellule.

Quand on passe à un langage fonctionnel, au lieu d'une grille cartésienne de A1et B42, les fonctions ont des noms. C'est vraiment tout.

Il y a d'autres aspects que l'on peut ajouter au-delà de cela ... mais c'est la programmation fonctionnelle à la base. Il ne faut pas se soucier de la structure des listes ou du regroupement des choses. La programmation fonctionnelle consiste à transmettre une valeur à une fonction et à récupérer une valeur sans avoir à nettoyer ailleurs dans la mémoire.

C'est ça. La programmation fonctionnelle est une feuille de calcul avec des noms plutôt qu'une grille.


la source
0

Vous pouvez penser à la programmation fonctionnelle comme à des comportements . Un programme est une description du comportement que vous souhaitez que l'ordinateur applique. Les fonctions sont l'unité de base du comportement, et la composition des fonctions est un moyen de construire de plus grands comportements à partir de plus petits.

Dans la POO, un objet de code est destiné à être l'état d'un objet dans le domaine de problème; il change au fil du temps pour refléter les changements dans cet objet de domaine. Dans FP, une valeur représente l'état d'un objet de domaine; il ne change jamais, vous créez simplement des valeurs différentes pour représenter différents états.

Je trouve le modèle fonctionnel un peu plus honnête sur ce que les ordinateurs font réellement - représenter. Après tout, je ne peux pas simplement évoquer un new Tesla()air hors du commun. :)

Jon Purdy
la source
-5

Les phrases sont plus fonctionnelles qu'orientées aux objets, en supposant que vous les décomposiez plus ou moins comme suit ...

The brown cow is in the meadow across the deep river.

Nous devons donc trouver les phrases de tête, puis le reste:

The cow (brown)
the meadow (across)
the river (deep)

En une fois:

sentence: The cow ((the meadow (the river (deep)) (across)) brown)

Analyser l'arbre:

|                     sentence
|                      /         
|                  The cow
|                 /       \
|            the meadow   brown
|            /         \
|      the river      across
|              \
|              deep

La parcimonie infecte la pensée fonctionnelle;

Chapeau à Gottlieb Frege dans les années 1890, Alan Turing (entschiedungsprobleme) dans les années 1930, Noam Chomsky (dans les années 1960).

KTys
la source
4
C'est une explication déroutante, et je connais la PF pour commencer.
Daenyth
On dirait qu'il imite la forme de Lisp sans en comprendre le sens
Izkata