Serais-je d'accord si je décidais d'écrire tout mon Ruby comme si c'était Haskell?

10

Étant donné que Ruby a une bonne liste des capacités de fonctionnement en construction - réduire, carte, sélectionnez, recueillez etc. Il a procs, blocs et lambdas, et a beau support d'itération (la eachfamille), serait - il une mauvaise décision de conception si je tente de écrire tous mes trucs Ruby de la manière la plus fonctionnelle possible? Surtout pour le code qui a peu ou pas d'E / S (donc des effets secondaires moins évidents)?

J'ai appris le Haskell (appelé le `` vrai '' langage de Hacker), et je suis amoureux de sa façon de faire les choses - j'aime Ruby, mais je pense que cela peut être encore plus amusant quand plus d'esprit Haskell y pénètre (enfin, didn 't Ruby emprunter / apprendre beaucoup de lui en premier lieu?)

Une orientation constructive est la bienvenue ...

nemesisfixx
la source
13
Pourquoi ne pas simplement écrire à Haskell alors?
1
J'écrirais uniquement en Haskell, mais Ruby n'est pas si méchante qu'elle mérite d'être complètement jetée. J'aime le fait que je puisse l'utiliser lors de l'écriture de scripts, et pour les nombreuses expériences rapides, j'aime pirater ensemble lorsque j'apprends des choses sur l'IA. Mais probablement aussi parce que je viens de commencer à apprendre Haskell, je pourrais éventuellement suivre vos conseils :-)
nemesisfixx
2
Je ne comprends pas pourquoi vous demandez la permission de Stack Overflow. Si vous écrivez du code que vous allez partager avec d'autres membres d'une équipe, vous devrez quand même coordonner vos styles de codage. Sinon, qu'importe?
Mike Daniels
Pourquoi je demande SO? car je respecte l'opinion honnête des hackers et programmeurs expérimentés. Il pourrait être avantageux d'utiliser une approche purement fonctionnelle de la programmation que les esprits expérimentés pourraient partager avec moi (et d'autres comme moi).
nemesisfixx
Étant donné qu'il y a des raisons objectives de «non», c'est une question légitime.
Andrew Grimm

Réponses:

16

Je fais ça avec python. Je trouve qu'il est lourd d'écrire dans un style fonctionnel héréditaire pur dans un langage qui n'a pas été conçu pour cela. Par exemple, contrastez les deux définitions de in_order :

def in_order(xs):
    for i in range(1,len(xs)):
        if xs[i] > xs[i+1]:
            return False
    return True

inOrder :: (Ord a) => [a] -> Bool
inOrder xs = and $ zipWith (<=) xs (tail xs)

L'écriture de in_orderla manière Haskell en python va être à la fois verbeuse (puisque python ne supporte pas très bien les idiomes nécessaires) et lente (espace linéaire au lieu de l'espace constant de Haskell en raison de la paresse).

Cependant, j'ai réussi à créer des programmes python avec une organisation fonctionnelle et une implémentation idiomatique de chaque fonction. L'idée que c'est une bonne façon de programmer est en fait la thèse derrière mon projet de codecatalog . Donc, mes composants sont orientés autour d'abstractions et de fonctions (avec une interface pure ) qui opèrent sur eux, plutôt que de classes avec état, et ça se marie bien. En fait, le code organisé de cette façon semble être plus flexible à réutiliser que le code organisé avec des classes. Cela pourrait toutefois être un parti pris personnel, car je suis toujours un passionné de Haskell.

Je dirais donc que la réponse à votre question est un peu . Utilisez vos racines fonctionnelles pour vous aider à réfléchir, mais n'en faites pas trop. Par exemple. simuler des listes paresseuses dans Ruby juste pour le bien de l'idiome va probablement être plus difficile que cela en vaut la peine.

luqui
la source
D'une certaine manière, votre description m'a fait penser à Pascal.
rasjani
@rasjani, oh? Une raison pourquoi?
Je ne sais pas, peut-être que son manque de bien comprendre l'anglais ou ce que vous avez décrit correspond à la façon dont (au moins) les choses étaient organisées / structurées en unités pascales. Juste une sorte de connexion mentale, peut-être pas de vraie connexion à cause de la première option;)
rasjani
1
L'énoncé «espace linéaire au lieu de l'espace constant de Haskell en raison de la paresse» n'est pas exact. La paresse implique toujours un ordre linéaire. Je comprends cependant votre point.
3
@aromero, je ne comprends pas le vôtre, cependant. Qu'est-ce que l'ordre a à voir avec ça? L'espace constant provient des ordures Haskell rassemblant les têtes de liste des comparaisons après les avoir andconsommées; il se comportera comme une boucle. Alors que la liste des comparaisons de python devra être générée en entier avant que l'analogue de andne les voit (sauf si vous utilisez des générateurs ... ce qui, je suppose, est une possibilité).
7

Vous pouvez écrire du code Ruby dans un style fonctionnel comme s'il s'agissait de Scheme, pas de Haskell. Pour l'écrire comme s'il s'agissait de Haskell, il faudrait un système de type Haskell, plus une évaluation paresseuse omniprésente.

solrize
la source
1

J'ai trouvé que la compréhension de la programmation fonctionnelle, et Haskell en particulier, m'aidait dans certaines situations que j'ai rencontrées dans Ruby. Mais plus j'apprends Haskell, plus je réalise à quel point Ruby est loin de pouvoir ressembler à Haskell.

La situation de chargement de module / code est catastrophique, pour une chose. L'interpréteur actuel n'a pas l'optimisation des appels de queue activée, vous ne pouvez donc pas utiliser la récursion comme vous le faites dans Haskell. Et une fois que vous entrez dans Monads, il n'y a vraiment aucune comparaison des niveaux d'abstraction que vous pouvez atteindre dans Haskell vs Ruby.

Si vous êtes intéressé, j'ai publié un code de comparaison Ruby / Haskell sur gist.github.com pendant que j'apprends.

La technique que j'ai apportée à Ruby qui a fonctionné le mieux a été de trouver des fonctions pures où je peux, c'est ce que vous essayez de faire.


la source
Dans l' un de mes tests Smalltalk: self assert: ((m >>= f) >>= g) equals: (m >>= [:x | (f value: x) >>= g]). Il n'y a aucune raison pour laquelle vous ne pouvez pas utiliser consciemment des monades, au lieu de les utiliser sans même savoir que vous les utilisez (comme des listes).
Frank Shearar
0

Je dirais "oui". Vous parlez (je pense) de l' influence de la programmation fonctionnelle dans le langage rubis. Le paradigme fonctionnel a de très beaux concepts qui complètent ou se chevauchent avec orienté objet (pas d'effets secondaires, en particulier).

La grande chose à propos de ruby ​​est qu'il vous permet de coder dans un style linéaire, orienté objet ou fonctionnel, ou un mélange de ceux-ci. Et votre script simple et linéaire peut se transformer en style OO / fonctionnel si et quand sa complexité augmente.

Robert Brown
la source
0

Cela dépend si vous allez collaborer avec d'autres. Si vous travaillez vous-même sur le code, utilisez le style avec lequel vous vous sentez le plus à l'aise. Cependant, si vous travaillez avec d'autres programmeurs Ruby, ils ne peuvent pas être utilisés pour un style de programmation purement fonctionnel et donc être confondus par votre code. Là encore, si vos collaborateurs sont également des programmeurs Haskell qui ont migré vers Ruby, vous pouvez ne pas avoir ce problème.

Zhehao Mao
la source