Je suis intéressé par la programmation fonctionnelle et j'ai décidé de me confronter à Haskell. Ma tête me fait mal ... mais je finirai par l'obtenir ... J'ai une curiosité cependant, pourquoi la syntaxe est-elle si cryptique (en l'absence d'un autre mot)?
Y a-t-il une raison pour laquelle il n'est pas plus expressif , plus proche du langage humain?
Je comprends que FP est bon en modélisation de concepts mathématiques et il a emprunté certains de ses moyens d'expression concis, mais ce n'est toujours pas des mathématiques ... c'est un langage.
Réponses:
Les langages fonctionnels comme Haskell et son antécédent Miranda sont nés du concept mathématique du calcul lambda . Depuis la page Wikipedia:
En raison de cette histoire, les syntaxes de ces langages fonctionnels (et des éléments fonctionnels des langages plus impératifs) sont fortement influencées par la notation mathématique utilisée par le calcul lambda.
La précision avec laquelle les notations mathématiques et les langages informatiques peuvent décrire les exigences et la précision avec laquelle les ordinateurs exigent que leurs instructions soient écrites sont bien corrélées entre elles. L'imprécision du langage naturel crée cependant un énorme obstacle à son utilisation pour la programmation des ordinateurs. Même les environnements de programmation en langage naturel les plus réussis (sans doute) tels que Wolfram Alpha nécessitent une expérience de domaine significative pour être utilisés efficacement.
la source
La syntaxe Haskell est proche du langage humain. Il est spécifiquement conçu pour ressembler à la notation mathématique, qui est un langage conçu par les humains (donc un langage humain ) pour exprimer précisément les concepts sur lesquels Haskell est construit.
Vous pouvez montrer un morceau de code Haskell à n'importe quel mathématicien ou logicien, et il pourra le comprendre, même s'il n'a jamais entendu parler de Haskell et ne sait absolument rien de la programmation, de l'informatique ou même des ordinateurs.
D'un autre côté, vous pouvez montrer à n'importe quel mathématicien ou logicien un morceau de code comme celui-ci:
et il sera complètement confus, en disant: "Cela n'a pas de sens, il n'y en a pas
x
quix
soit égal àx
plus1
."Qu'une notation spécifique soit ou non «cryptique» est une question d'opinion et de familiarité.
la source
where
permet de condenser l'essentiel de une fonction sur une seule ligne.x = infinity
cela résout bien l'équation.Je pense qu'une chose que vous rencontrez probablement est quelque chose que j'ai rencontré aussi lors de l'apprentissage de la programmation fonctionnelle, c'est qu'avec la programmation fonctionnelle vous pouvez (et presque devez) penser / travailler à un niveau plus élevé que vous ne le faites avec la programmation impérative.
Ce que vous trouvez moins expressif, je pense qu'il est en fait plus expressif: vous n'avez pas besoin d'énoncer chaque petit détail et pouvez faire plus avec moins de code dans la programmation fonctionnelle - il y a plus de puissance dans ce que vous écrivez.
Par exemple, je pourrais écrire impérativement:
qui est totalement lisible en anglais.
Une version Haskell pourrait être (et ce n'est pas Haskell valide, mais c'est juste pour une comparaison syntaxique):
ce qui nécessite moins de code et moins de détails - je n'ai pas à décomposer les choses en boucle et ses variables (
for each (...)
), lamap
fonction s'en charge pour moi.Travailler à ce niveau peut prendre un certain temps pour s'y habituer. Si cela peut aider, Haskell a probablement été le moment le plus difficile pour moi d'apprendre une nouvelle langue depuis que j'ai commencé la programmation, et je connais> 10 langues (dont Lisp). Cela valait vraiment la peine d'apprendre.
la source
Je m'attaque actuellement à Scala en ce moment, donc je peux sympathiser. Au moins avec Scala, je peux revenir à un style impératif lorsque les choses deviennent trop difficiles.
Je pense qu'il y a plusieurs forces en jeu ici:
Les concepteurs de langages fonctionnels ont nécessairement une solide formation en mathématiques, ils empruntent donc la notation mathématique qui leur est naturelle.
Une plus grande expressivité (c.-à-d. La puissance des déclarations, plutôt que la proximité de l'anglais) de n'importe quelle langue a (IMO) un prix correspondant dans la pente de la courbe d'apprentissage. La concision est une qualité très appréciée à Scala, beaucoup de choses étant facultatives.
Les langages fonctionnels font juste les choses très différemment, donc les opérations de base ne correspondent pas aux constructions impératives.
la source
Si j'ai bien compris votre dernier commentaire, votre question est pourquoi Haskell utilise souvent des opérateurs symboliques dans des endroits où il pourrait également utiliser des mots-clés alphanumériques (ou des noms de fonction)?
En ce qui concerne les mots clés, une réponse serait que les mots clés vous empêchent d'utiliser certains mots comme noms de variables. Par exemple, je suis toujours ennuyé quand je veux appeler mes variables
from
etto
dans une langue où l'un d'eux est un mot-clé - comme en Python.Une autre raison des opérateurs symboliques en général est la concision. Cela ne s'applique pas vraiment dans vos exemples spécifiques de compréhension de liste (
<-
n'est pas plus court quein
), mais dans de nombreux cas, c'est le cas.Encore une autre raison est la lisibilité. Cela peut sembler contre-intuitif car les opérateurs symboliques sont souvent plus difficiles à apprendre car leurs "noms" ne vous disent vraiment rien de ce qu'ils font (alors que le nom d'une fonction le fera généralement), mais une fois que vous savez ce que fait un opérateur donné, les expressions avec des opérateurs symboliques infixes sont souvent plus faciles à analyser pour un humain que celles avec beaucoup d'appels de fonction de préfixe alphanumérique car les opérateurs sont plus facilement distingués visuellement des opérandes de cette façon. Par exemple, la plupart des gens conviendraient que
2 * 3 + 4
c'est plus facilement lisible queadd (mult 2 3) 4
ouadd(mult(2, 3), 4)
.la source
Les langages informatiques impératifs ne sont généralement pas plus proches des langages naturels que, disons, Haskell.
Cependant, certains sont conçus pour ressembler davantage à l'anglais: Cobol et Hypercard, par exemple. Les leçons que je tirerais de ces exemples sont:
Le langage informatique Perl aurait été conçu en gardant à l'esprit certains aspects plus subtils du langage naturel . Je dirais que Perl fait mieux que Cobol ou Hypercard sur la convivialité générale, mais les gens ont des opinions divergentes sur Perl.
la source
Je pense que Haskell devient aussi similaire au langage humain que l'on peut obtenir sans introduire une syntaxe folle. Cela va vraiment très loin, par exemple avec la
where
clause de reporter une définition et avec la syntaxe de compréhension de liste qui est exactement ce que j'écrirais sur un tableau noir. Il évite également les caractères étrangers comme les accolades et a une utilisation libérale de l'indentation. L'exemple typique est le tri rapide:Certes, c'est un exemple simple, mais je ne connais aucun autre langage qui le rende aussi lisible.
Faire des choses plus compliquées peut devenir difficile à lire dans Haskell, mais cela a à voir avec le système de type, les entrées-sorties contraintes et pas du tout avec la syntaxe.
Si quoi que ce soit, je dirais que Haskell a sacrifié la simplicité syntaxique afin d'accommoder une syntaxe plus proche du langage humain. Un schéma de type langage a une syntaxe très éloignée de ce qu'un humain écrirait, mais il est vraiment simple d'expliquer ses règles.
la source
++ [p] ++
?Je pense que la différence a à voir avec la façon dont la programmation fonctionnelle / déclarative fait des déclarations sur un problème comme s'il s'agissait d'un problème mathématique, alors que la programmation impérative décrit un processus . Dans le monde des affaires, les programmes informatiques enveloppent ou remplacent les processus physiques, vous pouvez donc trouver un langage qui reflète cela pour être plus intuitif.
Il s'avère que le style fonctionnel se prête à l'utilisation sûre de plusieurs processeurs (car il minimise la mutabilité et les effets secondaires) - quelque chose que nous verrons plus à l'avenir. De plus, la plupart des langages fonctionnels modernes ont des collections avec des itérateurs auxquels vous pouvez transmettre des fonctions. Ces méthodes peuvent répartir leur charge de travail sur plusieurs processeurs de manière très efficace sans même que vous le sachiez.
la source