Wikipedia dit que Ruby est un langage fonctionnel, mais je ne suis pas convaincu. Pourquoi ou pourquoi pas?
Wikipedia dit que Ruby est un langage fonctionnel, mais je ne suis pas convaincu. Pourquoi ou pourquoi pas?
Réponses:
Je pense très certainement que vous pouvez utiliser un style fonctionnel dans Ruby.
L'un des aspects les plus critiques pour pouvoir programmer dans un style fonctionnel est de savoir si le langage prend en charge des fonctions d'ordre supérieur ... ce que fait Ruby.
Cela dit, il est également facile de programmer en Ruby dans un style non fonctionnel. Un autre aspect clé du style fonctionnel est de ne pas avoir d'état et d'avoir de vraies fonctions mathématiques qui renvoient toujours la même valeur pour un ensemble donné d'entrées. Cela peut être fait dans Ruby, mais cela n'est pas appliqué dans le langage comme quelque chose de plus strictement fonctionnel comme Haskell.
Donc, oui, il prend en charge le style fonctionnel, mais il vous permettra également de programmer dans un style non fonctionnel.
Is ruby a functional language?
et dans une réponse directe est un simple non. Ruby est un langage orienté objet avec quelques fonctionnalités.
Qu'une langue soit ou non une langue fonctionnelle n'a pas d'importance. La programmation fonctionnelle est une thèse, mieux expliquée par Philip Wadler (The Essence of Functional Programming) et John Hughes (Why Functional Programming Matters).
Une question significative est: «Dans quelle mesure Ruby est-il disposé à réaliser la thèse de la programmation fonctionnelle? La réponse est «très mal».
J'ai fait une présentation à ce sujet tout récemment. Voici les diapositives.
Ruby prend en charge les fonctions de plus haut niveau (voir Array # map, inject, & select), mais c'est toujours un langage impératif orienté objet.
L'une des principales caractéristiques d'un langage fonctionnel est qu'il évite l'état mutable. Les langages fonctionnels n'ont pas le concept de variable comme vous le feriez en Ruby, C, Java ou tout autre langage impératif.
Une autre caractéristique clé d'un langage fonctionnel est qu'il se concentre sur la définition d'un programme en termes de «quoi» plutôt que de «comment». Lors de la programmation dans un langage OO, nous écrivons des classes et des méthodes pour cacher l'implémentation (le "comment") du "quoi" (le nom de la classe / méthode), mais à la fin, ces méthodes sont toujours écrites en utilisant une séquence d'instructions. Dans un langage fonctionnel, vous ne spécifiez pas de séquence d'exécution, même au niveau le plus bas.
Je soutiens que soutenir ou avoir la capacité de programmer dans une langue dans un style fonctionnel ne fait pas un langage fonctionnel.
Je peux même écrire du code Java dans un style fonctionnel si je veux blesser mes collègues et moi-même quelques mois plus tard.
Avoir un langage fonctionnel ne concerne pas seulement ce que vous pouvez faire, comme les fonctions d'ordre supérieur, les fonctions de première classe et le currying. Il s'agit également de ce que vous ne pouvez pas faire, comme les effets secondaires dans les fonctions pures.
Ceci est important car c'est une grande partie de la raison pour laquelle les programmes fonctionnels sont, ou le code fonctionnel en général, est plus facile à raisonner. Et quand le code est plus facile à raisonner, les bogues deviennent moins profonds et flottent à la surface conceptuelle où ils peuvent être corrigés, ce qui à son tour donne moins de code bogué.
Ruby est essentiellement orienté objet, donc même s'il supporte raisonnablement un style fonctionnel, ce n'est pas en soi un langage fonctionnel.
C'est mon opinion non scientifique de toute façon.
Edit: Rétrospectivement et compte tenu des beaux commentaires que j'ai reçus jusqu'à présent sur cette réponse, je pense que la comparaison orientée objet par rapport à la fonction est celle des pommes et des oranges.
Le vrai différenciateur est celui d'être imparatif dans l'exécution, ou non. Les langages fonctionnels ont l'expression comme construction linguistique principale et l'ordre d'exécution est souvent indéfini ou défini comme étant paresseux. Une exécution stricte est possible mais utilisée uniquement en cas de besoin. Dans un langage imparatif, l'exécution stricte est la valeur par défaut et bien que l'exécution paresseuse soit possible, elle est souvent compliquée à faire et peut avoir des résultats imprévisibles dans de nombreux cas extrêmes.
Maintenant, c'est mon opinion non scientifique.
Ruby devra répondre aux exigences suivantes pour être fonctionnel "TRUELY".
Valeurs immuables: une fois qu'une «variable» est définie, elle ne peut pas être modifiée. Dans Ruby, cela signifie que vous devez effectivement traiter les variables comme des constantes. Le n'est pas entièrement pris en charge dans la langue, vous devrez figer chaque variable manuellement.
Pas d'effets secondaires: fois passée une valeur donnée, une fonction doit toujours renvoyer le même résultat. Cela va de pair avec des valeurs immuables; une fonction ne peut jamais prendre une valeur et la modifier, car cela provoquerait un effet secondaire tangentiel au retour d'un résultat.
Fonctions d'ordre supérieur: ce sont des fonctions qui autorisent des fonctions comme arguments ou utilisent des fonctions comme valeur de retour. C'est sans doute l'une des caractéristiques les plus critiques de tout langage fonctionnel.
Currying: activé par des fonctions d'ordre supérieur, le currying transforme une fonction qui prend plusieurs arguments en une fonction qui prend un argument. Cela va de pair avec l'application de fonction partielle, qui transforme une fonction multi-arguments en une fonction qui prend moins d'arguments qu'elle ne le faisait à l'origine.
Récursivité: boucle en appelant une fonction de l'intérieur d'elle-même. Lorsque vous n'avez pas accès aux données mutables, la récursivité est utilisée pour construire et enchaîner la construction des données. En effet, la boucle n'est pas un concept fonctionnel, car elle nécessite la transmission de variables pour stocker l'état de la boucle à un moment donné.
Évaluation paresseuse ou évaluation différée: retarder le traitement des valeurs jusqu'au moment où il est réellement nécessaire. Si, à titre d'exemple, vous avez un code qui a généré une liste de numéros de Fibonacci avec l'évaluation paresseuse activée, cela ne sera pas réellement traité et calculé tant que l'une des valeurs du résultat ne sera pas requise par une autre fonction, telle que put.
Proposition (juste une réflexion)
Je serais bien d'avoir une sorte de définition pour avoir une mode
directive pour déclarer des fichiers avec un paradigme fonctionnel, exemple
mode 'fonctionnel'
Ruby est un langage multi-paradigme qui prend en charge un style de programmation fonctionnel.
Ruby est un langage orienté objet, qui peut prendre en charge d'autres paradigmes (fonctionnel, impératif, etc.). Cependant, puisque tout dans Ruby est un objet, c'est principalement un langage OO.
exemple:
"bonjour" .reverse () = "olleh", chaque chaîne est une instance d'objet de chaîne et ainsi de suite.
Cela dépend de votre définition d'un «langage fonctionnel». Personnellement, je pense que le terme est lui-même assez problématique lorsqu'il est utilisé comme un absolu. Il y a plus d'aspects à être un «langage fonctionnel» que de simples fonctionnalités de langage et la plupart dépendent de l'endroit d'où vous cherchez. Par exemple, la culture entourant la langue est assez importante à cet égard. Encourage-t-il un style fonctionnel? Qu'en est-il des bibliothèques disponibles? Vous encouragent-ils à les utiliser de manière fonctionnelle?
La plupart des gens appelleraient Scheme un langage fonctionnel, par exemple. Mais qu'en est-il de Common Lisp? Mis à part le problème d'espace de noms multiple / unique et l'élimination garantie des appels de queue (que certaines implémentations CL prennent également en charge, en fonction des paramètres du compilateur), il n'y a pas grand-chose qui rend Scheme en tant que langage plus adapté à la programmation fonctionnelle que Common Lisp, et encore, la plupart des lispers n'appelleraient pas CL un langage fonctionnel. Pourquoi? Parce que la culture qui l'entoure dépend fortement des fonctionnalités impératives de CL (comme la macro LOOP, par exemple, que la plupart des Schemers désapprouveraient probablement).
D'un autre côté, un programmeur C peut très bien considérer CL comme un langage fonctionnel. La plupart du code écrit dans n'importe quel dialecte Lisp est certainement beaucoup plus fonctionnel que votre bloc de code C habituel, après tout. De même, Scheme est un langage impératif par rapport à Haskell. Par conséquent, je ne pense pas qu'il puisse jamais y avoir de réponse définitive par oui / non. Le fait d'appeler un langage fonctionnel ou non dépend fortement de votre point de vue.
Ruby n'est pas non plus vraiment un langage multi-paradigme, je pense. Le multi-paradigme a tendance à être utilisé par les personnes qui souhaitent étiqueter leur langue préférée comme quelque chose d'utile dans de nombreux domaines différents.
Je décrirais Ruby est un langage de script orienté objet. Oui, les fonctions sont des objets de première classe (en quelque sorte), mais cela n'en fait pas vraiment un langage fonctionnel. IMO, pourrais-je ajouter.
La récursivité est courante dans la programmation fonctionnelle. Presque tous les langages prennent en charge la récursivité, mais les algorithmes récursifs sont souvent inefficaces s'il n'y a pas d' optimisation des appels de queue (TCO).
Les langages de programmation fonctionnels sont capables d'optimiser la récursivité de la queue et peuvent exécuter un tel code dans un espace constant. Certaines implémentations de Ruby optimisent la récursivité de la queue, d'autres non, mais en général, les implémentations de Ruby ne sont pas obligées de faire le TCO. Consultez Ruby effectue-t - il une optimisation des appels de queue?
Donc, si vous écrivez un style fonctionnel Ruby et que vous comptez sur le TCO d'une implémentation particulière, votre code peut être très inefficace dans un autre interpréteur Ruby. Je pense que c'est pourquoi Ruby n'est pas un langage fonctionnel (pas plus que Python).
À proprement parler, cela n'a pas de sens de décrire un langage comme «fonctionnel»; la plupart des langages sont capables de programmation fonctionnelle. Même C ++ l'est.
Le style fonctionnel est plus ou moins un sous-ensemble de fonctionnalités de langage impératives, pris en charge avec le sucre syntaxique et certaines optimisations du compilateur comme l'immuabilité et l'aplatissement de la récursivité de la queue,
Ce dernier est sans doute une technicité mineure spécifique à l'implémentation et n'a rien à voir avec le langage réel. Le compilateur x64 C # 4.0 optimise la récursivité de la queue, tandis que le x86 ne le fait pas pour une raison stupide.
Le sucre syntaxique peut généralement être contourné dans une certaine mesure, surtout si le langage a un précompilateur programmable (c'est-à-dire #define en C).
Il serait peut-être un peu plus significatif de se demander "est-ce que le langage __ supporte la programmation impérative?", Et la réponse, par exemple avec Lisp, est "non".
S'il vous plaît, jetez un œil au début du livre: "A-Great-Ruby-eBook" . Il traite du sujet très spécifique que vous posez. Vous pouvez faire différents types de programmation dans Ruby. Si vous voulez programmer comme fonctionnellement, vous pouvez le faire. Si vous voulez programmer comme impérativement, vous pouvez le faire. C'est une question de définition à quel point Ruby est fonctionnel à la fin. Veuillez consulter la réponse de l'utilisateur camflan.