Comment concevez-vous des programmes en Haskell ou dans d'autres langages de programmation fonctionnels?

52

J'ai de l'expérience dans les langages de programmation orientés objet comme c # ou ruby. Je sais concevoir un programme dans un style orienté objet, créer des classes et des objets et définir des relations entre eux. Je connais aussi certains modèles de design.

Comment les gens écrivent-ils des programmes fonctionnels? Comment commencent-ils? Existe-t-il des modèles de conception pour les langages fonctionnels? Les méthodologies telles que la programmation extrême ou le développement agile sont-elles applicables aux langages fonctionnels?

Luke
la source
1
question connexe: stackoverflow.com/questions/3077866/…
HaskellElephant

Réponses:

24

J'écris ma réponse principalement en pensant à Haskell, bien que de nombreux concepts s'appliquent également à d'autres langages fonctionnels comme Erlang, Lisp (s) et ML. Certains s'appliquent même (dans une certaine mesure) à Ruby, Python, Perl et Javascript.

Comment les gens écrivent-ils des programmes fonctionnels? Comment commencent-ils?

En écrivant des fonctions. Lorsque vous effectuez une programmation fonctionnelle, vous écrivez mainou vous écrivez une fonction d'assistance. Parfois, votre objectif principal peut être d’écrire un type de données avec diverses fonctions pertinentes qui l’opèrent.

La programmation fonctionnelle est très bien adaptée aux approches descendante et ascendante. Haskell vous encourage fortement à écrire vos programmes dans un langage de haut niveau, puis à définir simplement les détails de votre conception de haut niveau. Voir minimumpar exemple:

minimum    :: (Ord a) => [a] -> a
minimum xs =  foldl1 min xs

La fonction permettant de trouver le plus petit élément d'une liste s'écrit simplement comme une traversée de la liste, en utilisant la fonction min pour comparer chaque élément avec "l'accumulateur" ou la valeur minimale actuelle.

Existe-t-il des modèles de conception pour les langages fonctionnels?

Il y a deux choses qui pourraient être assimilées à des "modèles de conception": imho, fonctions d'ordre supérieur et monades . Parlons de l'ancien. Les fonctions d'ordre supérieur sont des fonctions qui prennent d'autres fonctions en entrée ou produisent des fonctions en sortie. Toute langue fonctionnelle fait généralement un usage intensif de map, filteretfold(fold est souvent appelé "réduire"): trois fonctions très basiques d'ordre supérieur qui appliquent une fonction à une liste de différentes manières. Ceux-ci remplacent d'une manière magnifique les boucles pour boucles. Le fait de passer des fonctions sous forme de paramètres est un avantage extrêmement puissant pour la programmation; de nombreux "modèles de conception" peuvent être réalisés plus simplement en utilisant des fonctions d'ordre supérieur, en étant capable de créer les vôtres et en exploitant la puissante bibliothèque standard, qui regorge de fonctions utiles.

Les monades sont le sujet "plus effrayant". Mais ils ne sont pas si effrayants. Ma façon préférée de penser aux monades est de les considérer comme enveloppant une fonction dans une bulle et donnant à cette fonction des super pouvoirs (qui ne fonctionnent que dans la bulle). Je pourrais élaborer, mais le monde n’a pas vraiment besoin d’une autre analogie monade. Je vais donc passer à des exemples rapides. Supposons que je veuille utiliser un "modèle de conception" non déterministe. Je veux exécuter le même calcul pour différentes entrées différentes en même temps. Je ne veux pas choisir une seule entrée, je veux toutes les choisir. Ce serait la liste monade:

allPlus2 :: [Int] -> [Int]
allPlus2 xs = do x <- xs
                 return (x + 2)

Maintenant, la manière idiomatique d’exécuter cela est en fait map, mais pour des raisons d’illustration, pouvez-vous voir comment la monade de liste m’a permis d’écrire une fonction qui ressemble à une seule valeur, mais qui lui a donné le pouvoir de travailler sur chaque élément de une liste? Les autres superpuissances incluent l'échec, l'état, l'interaction avec le "monde extérieur" et l'exécution parallèle. Ces superpuissances sont très puissantes et la plupart des langages de programmation permettent à des fonctions dotées de superpuissances de se déchaîner. La plupart des gens disent que Haskell n'autorise pas du tout ces superpuissances, mais en réalité, Haskell les contient simplement en monades afin que leur effet puisse être limité et observé.

tl; dr Les fonctions d’ordre supérieur et les monades de Grokking sont l’équivalent Haskell des modèles de conception Grokking. Une fois que vous avez appris ces concepts Haskell, vous commencez à penser que les "modèles de conception" sont essentiellement des solutions de contournement peu coûteuses permettant de simuler la puissance de Haskell.

Les méthodologies telles que la programmation extrême ou le développement agile sont-elles applicables aux langages fonctionnels?

Je ne vois rien qui relie ces stratégies de gestion à un paradigme de programmation particulier. Comme Phynfo l'a déclaré, la programmation fonctionnelle vous oblige pratiquement à effectuer une décomposition de fonction, divisant un gros problème en sous-problèmes, de sorte que les mini-jalons devraient être un jeu d'enfant. Il existe des outils tels que QuickCheck et Zeno pour tester ou même prouver les propriétés des fonctions que vous écrivez.

Dan Burton
la source
"Je pourrais élaborer, mais le monde n'a pas vraiment besoin d'une autre analogie de monade." - Nous avons toujours besoin de plus d'analogies pour les monades et le tien est l'un des meilleurs que j'ai vu.
Adam Gent
1
Excellente réponse, mais je pense que votre discussion sur les modèles de conception est un peu trompeuse. Même si vous n'avez pas besoin de modèles de conception de style OO / GOF dans Haskell - en fait, il serait ridicule de les essayer - les modèles eux-mêmes sont simplement le moyen par lequel une communauté communique des solutions aux types de problèmes qui se posent encore et encore. La communauté Haskell est encore très jeune, il n'y a donc pas encore beaucoup de modèles à mentionner, mais si vous me demandiez des exemples de modèles Haskell, je mentionnerais des éléments tels que GADT ou FRP (Arrowized).
Personne