«Ma lumière est un miroir! - dites-moi, montrez-moi mon double ... ": concevez un bon cadre et obtenez le second en cadeau

Les pierres des temples antiques savent parler, mais peu les entendent. L'univers est rempli de sons que nous, les humains, n'entendons pas; des couleurs que nous ne voyons pas: ce sont parfois les limites objectives du corps et de l'esprit, mais il y a aussi des raisons subjectives - manque de connaissances et de compétences ou incapacité à les utiliser dans la pratique quotidienne. Un exemple vivant de la seconde dans le monde de la programmation - les signatures de fonctions. Les enfants du monde OO pensent au mieux dans les interfaces - c'est proche, mais «pas tout à fait ça» et plus vous devenez attentif, plus il se transforme en «pas du tout». Et les signatures de fonction savent aussi parler.

Honnêtement, je voudrais partir du côté des abstractions vraiment de haut niveau, mais mon expérience précédente montre que même les vérités mathématiques les plus simples dans un langage non mathématique «ne sonnent pas». Au passage, je constate que tout ce dont je parle est né de la pensée mathématique - et, par conséquent, peut être formalisé strictement.
Et maintenant - les détails. Probablement tous plus ou moins "fouillant" se donnent la peine de lire au moins une fois le travail historique du GoF; même ceux qui ne collent pas savent probablement qu'il existe un tel modèle - itérateur. Et certainement tout le monde l'utilise tous les jours. Donc (en maintenant le C # conditionnel):

bool MoveNext(); T Current { get; } 

... et maintenant la même chose, mais sans bruit syntaxique (c'est indicatif qu'en fait "sans bruit syntaxique" signifie en Haskell):

 MoveNext :: () -> Bool Current :: () -> t 

... oubliant les types pendant un certain temps et se concentrant sur la flèche elle-même (->), vous vous posez involontairement la question de ce qui se passera si elle est "inversée"? Il s'avère alors:

 MoveNext' :: Bool -> () Current' :: t -> () 

Un léger sentiment de disharmonie, non? S'il n'y a aucun problème avec t -> () , alors Bool -> () semble plus que suspect. Et en effet - ce drapeau a été utilisé pour signaler la fin de la séquence, non? Dans la forme inversée, le cas True -> () n'a aucun sens - seul False -> () suffit. L'incertitude binaire fournie par le type Bool est perdue - et devrait donc ressembler à ceci:

 completed :: () -> () next :: t -> () 

Ressemble-t-il à quelque chose? Qu'en est-il des extensions réactives ?
Ouah! La signature (enfin, plus précisément, les signatures, mais l'approche elle-même fonctionne à un niveau individuel) de la fonction d'un (presque) cool (mini) framework nous a parlé d'un autre non moins cool, non? Vous avez juste besoin d'être prudent et d'entendre.

Bonnes nouvelles au monde de la théorie des catégories
Qui dans le sujet, bien sûr, sait que l'exemple avec IEnumerator <-> IObserver n'est pas nouveau.
Il est surprenant que rarement personne ne sache que c'est loin d'être le seul exemple (même si nous devons rendre hommage, en particulier celui-ci est très brillant).

Les personnes curieuses peuvent prendre les modèles restants du GoF et regarder leurs duels. Souvent, un non-sens complet se révélera - c'est normal: en soi, la «dualité» est plus élevée que le monde terrestre et ne se considère pas obligée de compter avec une utilisation pratique: mais après tout, le Soleil n'a également besoin de rien pour briller.

Pourquoi alors "presque cool"? Oui, en raison de la discordance qui a conduit à la nécessité de moudre et de couper davantage. À proprement parler, en tournant les flèches en arrière, il s'est avéré quelque chose de pas très utile, qui peut être interprété comme un inconvénient de la signature originale. Pour l'avenir, je dirai que cette signature même peut être redéfinie de telle sorte que la disharmonie disparaît et il sera assez simple de se tourner vers son double. Mais je ne vais pas m'embêter avec ça ... du moins - pas dans cette note.

Mieux vaut résumer, basé entièrement sur mon expérience:

  1. Les signatures de fonction peuvent parler, mais les programmeurs sont souvent sourds.
  2. Chaque fois que vous rencontrez une fonction bien conçue, demandez-vous quel est son double et s'il peut être utile pour n'importe quelle tâche.
  3. Si un double existe, mais nécessite une «légère modification» comme dans l'exemple ci-dessus, alors la signature originale a très probablement des défauts implicites; peut-être qu'il est logique de le redéfinir afin qu'il n'y ait pas un tel problème?

Source: https://habr.com/ru/post/fr437520/


All Articles