Question

Lors de ma deuxième année d'université, on nous a "appris" Haskell, je n'y connais presque rien et encore moins en programmation fonctionnelle.

Qu'est-ce que la programmation fonctionnelle, pourquoi et/ou où voudrais-je l'utiliser à la place de la programmation non fonctionnelle et ai-je raison de penser que C est un langage de programmation non fonctionnel ?

Était-ce utile?

La solution

Une caractéristique clé d’un langage fonctionnel est le concept de fonctions de première classe.L'idée est que vous pouvez transmettre des fonctions en tant que paramètres à d'autres fonctions et les renvoyer sous forme de valeurs.

La programmation fonctionnelle consiste à écrire du code qui ne change pas d'état.La principale raison en est que les appels successifs à une fonction produiront le même résultat.Vous pouvez écrire du code fonctionnel dans n'importe quel langage prenant en charge des fonctions de première classe, mais certains langages, comme Haskell, ne vous permettent pas de changer d'état.En fait, vous n'êtes pas censé créer d'effets secondaires (comme l'impression de texte) - ce qui semble complètement inutile.

Haskell utilise plutôt une approche différente des IO :monades.Ce sont des objets qui contiennent l'opération IO souhaitée à exécuter par le niveau supérieur de votre interpréteur.À tout autre niveau, ils ne sont que des objets dans le système.

Quels avantages offre la programmation fonctionnelle ?La programmation fonctionnelle permet de coder avec moins de risques de bugs car chaque composant est complètement isolé.De plus, l'utilisation de fonctions de récursion et de première classe permet d'obtenir des preuves simples d'exactitude qui reflètent généralement la structure du code.

Autres conseils

Qu'est-ce que la programmation fonctionnelle

Il existe deux définitions différentes de la « programmation fonctionnelle » couramment utilisées aujourd’hui :

L'ancienne définition (provenant de Lisp) est que la programmation fonctionnelle consiste à programmer à l'aide de fonctions de première classe, c'est-à-direoù les fonctions sont traitées comme n'importe quelle autre valeur afin que vous puissiez transmettre des fonctions comme arguments à d'autres fonctions et que la fonction puisse renvoyer des fonctions parmi leurs valeurs de retour.Cela aboutit à l’utilisation de fonctions d’ordre supérieur telles que map et reduce (vous en avez peut-être entendu parler mapReduce comme une opération unique largement utilisée par Google et, sans surprise, c'est un proche parent !).Les types .NET System.Func et System.Action rendre les fonctions d'ordre supérieur disponibles en C#.Bien que le curry ne soit pas pratique en C#, les fonctions qui acceptent d'autres fonctions comme arguments sont courantes, par ex.le Parallel.For fonction.

La définition la plus jeune (popularisée par Haskell) est que la programmation fonctionnelle consiste également à minimiser et contrôler les effets secondaires, y compris la mutation, c'est-à-direécrire des programmes qui résolvent des problèmes en composant des expressions.C'est ce qu'on appelle plus communément « programmation purement fonctionnelle ».Ceci est rendu possible par des approches très différentes des structures de données appelées « structures de données purement fonctionnelles ».L’un des problèmes est que la traduction d’algorithmes impératifs traditionnels pour utiliser des structures de données purement fonctionnelles rend généralement les performances 10 fois moins bonnes.Haskell est le seul langage de programmation purement fonctionnel qui ait survécu, mais les concepts se sont glissés dans la programmation grand public avec des bibliothèques comme Linq Sur internet.

où voudrais-je l'utiliser à la place d'une programmation non fonctionnelle

Partout.Les Lambdas en C# ont désormais démontré des avantages majeurs.C++11 a des lambdas.Il n'y a aucune excuse pour ne pas utiliser de fonctions d'ordre supérieur maintenant.Si vous pouvez utiliser un langage comme F#, vous bénéficierez également de l'inférence de type, de la généralisation automatique, du curry et de l'application partielle (ainsi que de nombreuses autres fonctionnalités du langage !).

ai-je raison de penser que C est un langage de programmation non fonctionnel ?

Oui.C est un langage procédural.Cependant, vous pouvez bénéficier de certains avantages de la programmation fonctionnelle en utilisant des pointeurs de fonction et void * en C.

Cela vaut peut-être la peine de consulter cet article sur Fa# "101" sur CoDe Mag récemment publié.

Aussi, Dustin Campbell a un super blog où il a publié de nombreux articles sur ses aventures pour se familiariser avec F#.

J'espère que vous les trouverez utiles :)

MODIFIER:

De plus, juste pour ajouter, ma compréhension de la programmation fonctionnelle est la suivante tout est une fonction, ou des paramètres d'une fonction, plutôt que des instances/objets avec état.Mais je peux me tromper. F# est quelque chose dans lequel je meurs d’envie de me lancer, mais je n’ai tout simplement pas le temps !:)

L'exemple de code de Jean le Statisticien ne montre pas la programmation fonctionnelle, car lorsque vous faites de la programmation fonctionnelle, l'essentiel est que le code ne fait AUCUNE ASSIGNATION ( record = thingConstructor(t) est une mission), et il n'y a AUCUN EFFET SECONDAIRE (localMap.put(record) est une déclaration avec un effet secondaire).Du fait de ces deux contraintes, tout ce qu'un fonction Does est entièrement capturé par ses arguments et sa valeur de retour.Réécrire le code du statisticien tel qu'il devrait ressembler, si vous vouliez émuler un langage fonctionnel en utilisant C++ :

RT getOrCreate(const T thing, 
                  const Function<RT<T>> thingConstructor, 
                  const Map<T,RT<T>> localMap) {
    return localMap.contains(t) ?
        localMap.get(t) :
        localMap.put(t,thingConstructor(t));
}

En raison de la règle d'absence d'effets secondaires, chaque instruction fait partie de la valeur de retour (d'où return vient d'abord), et chaque affirmation est une expression.Dans les langages qui appliquent la programmation fonctionnelle, le return le mot-clé est implicite, et le si l'instruction se comporte comme celle du C++ ?: opérateur.

De plus, tout est immuable, donc localMap.put doit créer une nouvelle copie de LocalCarte et renvoyez-le, au lieu de modifier l'original LocalCarte, comme le ferait un programme C++ ou Java normal.Selon la structure de localMap, la copie pourrait réutiliser des pointeurs vers l'original, réduisant ainsi la quantité de données à copier.

Certains des avantages de la programmation fonctionnelle incluent le fait que les programmes fonctionnels sont plus courts, qu'il est plus facile de modifier un programme fonctionnel (car il n'y a pas d'effets globaux cachés à prendre en compte), et qu'il est plus facile de mettre le programme directement dans le bon sens. première place.

Cependant, les programmes fonctionnels ont tendance à s'exécuter lentement (en raison de toutes les copies qu'ils doivent effectuer) et ils n'ont pas tendance à interagir correctement avec d'autres programmes, processus du système d'exploitation ou systèmes d'exploitation, qui gèrent les adresses mémoire, le petit-boutiste. blocs d'octets et autres bits non fonctionnels spécifiques à la machine.Le degré de non-interopérabilité a tendance à être inversement corrélé au degré de pureté fonctionnelle et à la rigueur du système de types.

Les langages fonctionnels les plus populaires ont des systèmes de types vraiment très stricts.En OCAML, vous ne pouvez même pas mélanger les mathématiques entières et à virgule flottante, ni utiliser les mêmes opérateurs (+ pour ajouter des entiers, +.sert à ajouter des flotteurs).Cela peut être un avantage ou un inconvénient, selon la valeur que vous accordez à la capacité d'un vérificateur de type à détecter certains types de bogues.

Les langages fonctionnels ont également tendance à avoir de très grands environnements d'exécution.Haskell est une exception (les exécutables GHC sont presque aussi petits que les programmes C, à la fois au moment de la compilation et de l'exécution), mais les programmes SML, Common Lisp et Scheme nécessitent toujours des tonnes de mémoire.

Oui, vous avez raison de penser que C est un langage non fonctionnel.C est un langage procédural.

Je préfère utiliser la programmation fonctionnelle pour m'éviter un travail répété, en créant une version plus abstraite puis en l'utilisant à la place.Laissez-moi vous donner un exemple.En Java, je me retrouve souvent à créer des cartes pour enregistrer des structures, et donc à écrire des structures getOrCreate.

SomeKindOfRecord<T> getOrCreate(T thing) { 
    if(localMap.contains(t)) { return localMap.get(t); }
    SomeKindOfRecord<T> record = new SomeKindOfRecord<T>(t);
    localMap = localMap.put(t,record);
    return record; 
}

Cela arrive très souvent.Maintenant, dans un langage fonctionnel, je pourrais écrire

RT<T> getOrCreate(T thing, 
                  Function<RT<T>> thingConstructor, 
                  Map<T,RT<T>> localMap) {
    if(localMap.contains(t)) { return localMap.get(t); }
    RT<T> record = thingConstructor(t);
    localMap = localMap.put(t,record);
    return record; 
}

et je n'aurais plus jamais besoin d'en écrire un nouveau, je pourrais en hériter.Mais je pourrais faire mieux qu'hériter, je pourrais dire dans le constructeur de cette chose

getOrCreate = myLib.getOrCreate(*,
                                SomeKindOfRecord<T>.constructor(<T>), 
                                localMap);

(où * est une sorte de notation "laisser ce paramètre ouvert", qui est une sorte de curry)

et puis le getOrCreate local est exactement le même que ce qu'il aurait été si j'avais écrit le tout, sur une seule ligne, sans dépendances d'héritage.

Si vous cherchez un bon texte sur F#

Expert F# est co-écrit par Don Syme.Créateur de F#.Il a travaillé spécifiquement sur des génériques dans .NET afin de pouvoir créer F#.

F# est calqué sur OCaml, donc tout texte OCaml vous aiderait également à apprendre F#.

je trouve Qu'est-ce que la programmation fonctionnelle ? Être utile

La programmation fonctionnelle consiste à écrire des fonctions pures, à supprimer les entrées et les sorties cachées aussi autant que possible, de sorte qu'une grande partie de notre code possible décrit simplement une relation entre les entrées et les sorties.

Préférez les explicites when paramètre

public Program getProgramAt(TVGuide guide, int channel, Date when) {
  Schedule schedule = guide.getSchedule(channel);

  Program program = schedule.programAt(when);

  return program;
}

sur

public Program getCurrentProgram(TVGuide guide, int channel) {
  Schedule schedule = guide.getSchedule(channel);

  Program current = schedule.programAt(new Date());

  return current;
}

Un langage fonctionnel est activement hostile aux effets secondaires.Les effets secondaires sont la complexité et la complexité est constituée de bugs et les bugs sont le diable.Un langage fonctionnel vous aidera également à être hostile aux effets secondaires.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top