Les adeptes de la frappe statique et dynamique ne se comprendront jamais. Et TypeScript ne les aidera pas



Quand mon ami et moi sommes allés à l'école et ne rêvions que de devenir développeurs, nous avons pensé comment créer quelque chose ensemble - un jeu ou un programme super utile.

J'ai commencé à apprendre les pros et C #, c'est JavaScript. Nous avons obtenu un diplôme d'études secondaires, étudié à l'université, servi dans l'armée, obtenu un emploi. Nous avons été criblés de développement industriel ici et là, et quand nous en avons tous les deux été fatigués, nous nous sommes souvenus par où commencer.

Après avoir rassemblé des développeurs déjà chevronnés, nous avons finalement décidé de créer notre propre projet - un jeu vidéo en deux dimensions. Puisque l'ami était un front propre et que j'étais plein, le navigateur est devenu la plate-forme évidente pour nous. J'avais l'habitude de développer le front uniquement sur TypeScript, et nous n'avons pensé à aucun problème, TS n'est qu'un sur-ensemble de JavaScript. Prenez-le et tout se passe bien. Peu importe comment. Lorsque nous avons commencé à discuter du travail, nous avons été confrontés à un abîme incroyable de malentendus.

J'ai donc vu la tâche de faire un jeu. Je suis comme ça - oui, nous avons un type de "jeu", un type d '"inventaire", un type de "chose", un type de "carte", un type de "lieu". Je peux à peu près imaginer comment ils fonctionnent ensemble, les décrire, assembler un projet et tout fonctionne. Le compilateur m'a vérifié, j'ai tout fait correctement. Ensuite, je commence à écrire du code qui utilise ces types. Du fait qu'ils le sont, c'est beaucoup plus facile pour moi. L'IDE me le dit et vérifie les erreurs. Si le projet va - très probablement, il fonctionne. J'ai passé beaucoup de temps sur les descriptions de types et c'était bien. Voici mon approche.

Mon ami voulait faire le contraire - écrire immédiatement du code et ne décrire aucun type. Il n'était pas prêt à définir le problème comme une famille type. Je ne voulais pas m'appuyer dessus, je ne voyais pas la tâche comme un ensemble de classes, de types, d'enregistrements, ou quoi que ce soit d'autre. Cela me semblait tout simplement impensable. Nous avions tous les deux raison à bien des égards, la justesse de chacun de nous excluait l'autre.

Sérieusement, nous avons parlé pendant des heures, mais chacun a parlé de la sienne, comme dans différentes langues. Et vous ne pouvez pas écrire que nos cerveaux ne sont pas flexibles. Il y a tout juste un an, je suis passé sans douleur au monde fonctionnel de l'orienté objet, et vice versa. De plus, j'ai passé beaucoup de temps à apprendre JS, et il apprenait plusieurs langages typés statiquement.

Mais la technologie, qui est devenue la première technologie de «combat» pour les développeurs, les définit si fortement que deux personnes expérimentées adultes ne sont tout simplement pas prêtes à s'écouter. Au fil des années d'étude du développement, notre vision a évolué trop différemment et les approches pour résoudre les problèmes n'ont pas du tout fonctionné ensemble.

En conséquence, nous avons abandonné l'idée de travailler ensemble. La pensée vient immédiatement à l'esprit que le problème ne concerne que nous deux. Peut-être, mais j'ai vu cela avec d'autres personnes de l'industrie.

Le typage statique et dynamique a une différence fondamentale inconciliable


Mon code répond à la question "Comment travailler avec cela", et en tant que code pour les développeurs habitués à la frappe dynamique - "Comment ça marche". Les deux approches ont droit à la vie, et il existe des outils pour les deux, mais une seule peut être en première ligne.

Statique est bon pour les grands projets qui ont fait des centaines d'années de développement et dynamique pour les petites équipes, pour les tâches où du code en écriture seule est souvent nécessaire. Avec Dynamic, vous gagnez du temps et des efforts au début du développement et avec Static à la fin.

L'idée de mettre les types au premier plan a sérieusement influencé ma pensée du développeur.
En choisissant C # au début du voyage, j'ai cloué la typification statique à ma vision du monde, dont je souffre maintenant. Ayant vu un problème, j'essaie de présenter sa solution comme un ensemble de types et de principes de leur interaction. Lorsque je développe un module, je détermine d'abord sur quels types il fonctionne et qui interagit avec son environnement. Je ne me souviens même pas comment j'avais abordé la résolution de problèmes auparavant.

Toute la formation en programmation Java est une formation à la conception et à l'utilisation des types. .NET CLR - Runtime C # - construit sur des types et pour des types. Le typage statique est au centre de la conception de la programmation orientée objet (bonjour, classes de JS, j'ai décidé que vous n'en aviez pas besoin). Les implémentations canoniques de la plupart des modèles OOP sont remplies d'Interface, qui n'a aucun sens dans un langage typé dynamiquement.

Les modèles eux-mêmes sont quelque chose de cross-langage, mais quelqu'un peut-il me dire pourquoi le modèle "état" est nécessaire dans un langage typé dynamiquement? Et le constructeur? Ces modèles ne concernent pas le développement, ils concernent les types. Les types et la POO sont inextricablement liés.

Vous ne pouvez pas construire votre logique métier en fonction des types, mais vous ne savez rien à leur sujet dans le processus de développement. C'est pourquoi il existe des fournisseurs frontaux qui couvrent leur code avec un nombre inimaginable de tests unitaires, qui vérifient simplement la base de code pour l'absence d'erreurs de type.
Nous savons tous très bien que la sécurité grâce à la couverture est une illusion. Les tests sont écrits à la main, ils sont, par définition, moins fiables que le système de vérification de type intégré au langage.

Cela ne signifie pas que les langages typés dynamiquement ne sont pas nécessaires (en fait, je pense vraiment qu'ils ne sont pas nécessaires). Cela signifie que lorsque vous les utilisez, vous devez abandonner la POO comme paradigme dominant. Toute cette unité de données et d'opérations sur eux est destinée aux gars qui ont un contrôle statique.

Les développeurs avec lesquels j'ai eu affaire ne croient pas que la présence de typage statique change l'approche du développement, et ils écrivent le même code que dans les langages dynamiques, en ajoutant la vérification de type. Je pense que c'est fondamentalement faux. Et cela est plus visible précisément dans le cas d'un frontal moderne.
Je sais que critiquer les fronts est un sujet tabou. Un jour, mon ami et moi avons commencé une IA, qui troll tout le monde sur Twitter, et Brendan Ike l'a cassé. Sérieusement, le créateur du javascript s'est battu avec notre réseau de neurones dans les commentaires.



Pour une raison inconnue, ces gars-là ne sont tout simplement pas prêts à vivre dans un monde où leur vision contient de graves lacunes. Par conséquent, je ne critique que ceux d'entre eux qui se précipitent dans mon projet définitivement typé et y placent leurs propres commandes.

Nous aurions vécu dans nos petits mondes, mais TypeScript nous a poussés


J'écris donc du code qui, en raison des types, ne peut pas être utilisé incorrectement. Dans le projet, je m'attends à ce que d'autres utilisent également des types. Ensuite, mon code fonctionnera comme je le souhaitais. Et je ne couvre pas sciemment tous les cas d'utilisation abusive de ce code (car la frappe exclut cela). Mais un surnom JS entre dans le projet, prend ce type de mine, l'enveloppe dans n'importe quel et commence à l'utiliser de manière incorrecte, ce qui conduit à des bogues subtils.

Les développeurs JavaScript sont convaincus que Typescript est toujours le même JS, mais avec la possibilité d'ajouter parfois une vérification de type statique s'ils en ont besoin. Ce n'est pas le cas. Le script est cent fois plus puissant, et ils ne s'intéressent qu'à trois pour cent de ses capacités.

L'argument le plus dommageable est que TypeScript n'est qu'un sur-ensemble de JS. Mais dans la pratique, vous ne pouvez pas vous empêcher de considérer Typescript comme un langage indépendant, même si vous êtes le putain de roi des rendus. Parce qu'ici, nous avons besoin d'une approche différente - statique, pas dynamique.

Le principal avantage du typage statique est la garantie. Si vous l'utilisez dans un module, mais pas dans un autre, vous venez de consacrer du temps et des efforts à la description et au développement des types, mais vous n'avez reçu aucune garantie.

Il semble à beaucoup que TypeScript est un compromis entre les systèmes de type entre JS et Java. Il n'est pas un compromis, son système de caractères est juste spécial.

Tout est aggravé par le fait qu'aujourd'hui, chaque deuxième emploi sur le front nécessite une connaissance de TS. Cela conduit au fait que les développeurs JS étudient superficiellement les capacités de Typescript et commencent à écrire du code dessus, créant un grand nombre de pratiques nuisibles. Une situation survient quand ils n'ont vraiment pas besoin de vérification de frappe statique, mais ils l'ont imposée et ils l'ont ruinée. Il faut enfin reconnaître que les approches de développement avec typage dynamique et statique se contredisent, ce ne sont pas des choses qui peuvent être mélangées.

JavaScript, comme je le vois, est un très bon outil pour écrire du code qui résout le problème sans mettre en évidence les abstractions inutiles. Le cas le plus flagrant est le modèle de l'usine de glace. Vous pouvez alimenter cette instance vos instances, et il les couvre avec l'immunité d'exécution. Si je traite mon objet avec cette usine, cela me donnera la même chose, mais lorsque j'essayerai de changer la valeur d'une des propriétés, j'obtiendrai une exception. Juste WAT?!?

Le motif a surgi parce que les fronts lisent quelque part sur l'immuabilité cool, et ont décidé de le faire glisser dans leur propre langue, qui n'était en aucun cas destinée à l'immunité. Dans Typescript, je peux faire la même usine, mais avec une interdiction de temps de compilation des mutations, et sans aucune exception.

En revanche, cela n'est pas nécessaire, car il existe une programmation fonctionnelle pure. Prenez F #, Haskell, OCaml, je vais le dire, ReasonML - là les mutations sont interdites hors de la boîte. Mais je crains que si vous donnez le front-end à un langage fonctionnel, il commencera immédiatement à le moderniser et à faire ressembler le comportement à JS.

Parce que le choix de la frappe est un chemin sans retour. Toutes les solutions de compromis ne donnent que l'illusion d'un compromis. Vous mettez les types au premier plan ou non. Je ne sais pas comment tout se passerait, commencez à apprendre C # et JavaScript simultanément et parallèlement les uns aux autres. Mais maintenant, je suis tellement cloué dans ma pensée que je ne vois pas et ne veux pas voir les avantages de la frappe dynamique. Ils le sont, mais hors de ma vue, et tout ce qui me reste à faire est de les fermer les yeux, quant à toutes les manifestations du monde étranger à moi avec lesquelles je dois vivre. Je comprends que je me trompe, mais je dois travailler ici et maintenant, et il n'y a pas de budget précipité entre les pôles.

Par conséquent, je ne veux pas chercher de compromis, mais je parle directement. Si vous commencez tout juste à apprendre le développement, commencez par la frappe statique.

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


All Articles