OK, donc le titre est un peu clickbaity mais sérieusement je suis sur un tell, ne demande pas un coup de pied pendant un moment. J'aime la façon dont cela encourage les méthodes à être utilisées comme messages de manière réellement orientée objet. Mais cela pose un problème récurrent qui me trotte dans la tête.
Je suis venu pour suspecter qu'un code bien écrit peut suivre les principes d'OO et les principes fonctionnels en même temps. J'essaie de réconcilier ces idées et le gros problème que j'ai rencontré est le suivant return
.
Une fonction pure a deux qualités:
L'appeler de manière répétée avec les mêmes entrées donne toujours le même résultat. Cela implique que c'est immuable. Son état n'est défini qu'une fois.
Il ne produit aucun effet secondaire. Le seul changement causé en l'appelant produit le résultat.
Alors, comment peut-on être purement fonctionnel si vous avez juré d'utiliser return
votre méthode de communication des résultats?
Le tell, ne demande pas idée fonctionne en utilisant ce que certains considèrent un effet secondaire. Lorsque je traite un objet, je ne lui pose pas de question sur son état interne. Je lui dis ce que je dois faire et il utilise son état interne pour comprendre quoi faire avec ce que je lui ai dit de faire. Une fois que je le dis, je ne demande pas ce que ça a fait. Je m'attends juste à ce qu'il ait fait quelque chose à propos de ce qu'il a été dit de faire.
Je pense à Tell, Don't Ask, à plus qu’un nom différent pour l’encapsulation. Quand j'utilise return
je n'ai aucune idée de ce qui m'a appelé. Je ne peux pas parler de protocole, je dois le forcer à gérer mon protocole. Ce qui, dans de nombreux cas, est exprimé par l'état interne. Même si ce qui est exposé n’est pas exactement l’état, c’est généralement juste quelques calculs effectués sur des arguments d’état et d’entrée. Le fait de disposer d'une interface permettant de répondre offre la possibilité de transformer les résultats en quelque chose de plus significatif que l'état ou les calculs internes. C'est un message qui passe . Voir cet exemple .
Il y a bien longtemps, lorsque les disques durs contenaient des disques et qu'une clé USB correspondait à ce que vous faisiez dans la voiture lorsque le volant était trop froid pour être touché, on m'a appris à quel point les personnes agaçantes considèrent les fonctions sans paramètres. void swap(int *first, int *second)
semblait si pratique, mais nous avons été encouragés à écrire des fonctions renvoyant les résultats. J'ai donc pris cela à cœur avec foi et j'ai commencé à le suivre.
Mais maintenant, je vois des gens qui construisent des architectures où les objets laissent leur fabrication contrôler le lieu où ils envoient leurs résultats. Voici un exemple d'implémentation . L'injection de l'objet de port de sortie ressemble un peu à l'idée de paramètre out. Mais c'est comme ça que les objets qui disent ne pas demander disent aux autres objets ce qu'ils ont fait.
Lorsque j'ai découvert les effets secondaires, j'ai tout de suite pensé au paramètre de sortie. On nous disait de ne pas surprendre les gens en leur faisant effectuer une partie du travail de manière surprenante, c'est-à-dire en ne suivant pas la return result
convention. Maintenant, bien sûr, je sais qu’il existe une pile de problèmes de threads asynchrones parallèles qui entraînent des effets secondaires, mais le retour n’est en réalité qu’une convention selon laquelle vous laissez le résultat affiché sur la pile afin que tout ce qui est appelé puisse être supprimé ultérieurement. C'est tout ce que c'est vraiment.
Ce que j'essaie vraiment de demander:
Est-ce return
le seul moyen d'éviter toute cette misère d'effets secondaires et d'obtenir la sécurité du fil sans serrures, etc. Ou puis-je suivre , ne pas demander de manière purement fonctionnelle?