Plusieurs fois, on m'a demandé pourquoi je préfère utiliser des langages de programmation tels que Haskell et Rust, car ce ne sont pas les outils les plus utilisés et les plus populaires. Cet article est écrit dans le but de démystifier ce qui se passe dans ma tête lorsque je pense aux choix technologiques.
Le développement de logiciels avec des exigences de fonctionnement à long terme et un certain niveau de fiabilité s'apparente en un sens à une partie d'échecs. Les variantes du développement des événements dans les deux sont assez difficiles à comprendre pour le cerveau humain, le rôle de l'expérience est d'une grande importance et chaque mouvement / choix peut être critique. La similitude se poursuit dans le sens où, comme les échecs, le développement est très "positionnel" - toute une série de mouvements peut viser à préparer une manœuvre qui mènera à une victoire sur un pion. Il peut sembler qu'il ne s'agit que d'un seul pion, mais pour un jeu sérieux, cela peut être un avantage significatif. Semblable au jeu de position de l'échiquier, lors de la conception et du développement de grands projets, nous prenons constamment des décisions visant à résoudre des problèmes plus importants ou à répondre aux exigences du projet.L'effet de chaque solution, même minime, a tendance à s'accumuler vers la fin du jeu ou au moment où le logiciel est en fonctionnement. La différence, ce qui aggrave la situation, est que le développement de logiciels, contrairement aux échecs, n'est pas résolu sur un ordinateur, et vous ne pouvez pas simplement prendre et trouver les meilleurs coups en exécutant un moteur informatique. Par conséquent, il est nécessaire de prendre de nombreuses décisions qui nous mènent progressivement vers cet objectif, et tous les moyens qui améliorent notre «position» stratégique sont bons.et vous ne pouvez pas simplement aller chercher les meilleurs mouvements en exécutant un moteur informatique. Par conséquent, il est nécessaire de prendre de nombreuses décisions qui nous mènent progressivement vers cet objectif, et tous les moyens qui améliorent notre «position» stratégique sont bons.et vous ne pouvez pas simplement aller chercher les meilleurs mouvements en exécutant un moteur informatique. Par conséquent, il est nécessaire de prendre de nombreuses décisions qui nous mènent progressivement vers cet objectif, et tous les moyens qui améliorent notre «position» stratégique sont bons.
Les solutions peuvent être simplifiées en plusieurs catégories: architecturales, méthodologiques et instrumentales. Les architectes parlent de la manière dont nous structurons un projet. Les méthodes déterminent comment nous organisons le processus de travail, s'assurent de la qualité et de l'exactitude de la mise en œuvre. Les outils déterminent ce avec quoi l'équipe de développement doit travailler pour obtenir le résultat. Pour un cycle de développement complet, un grand nombre d'outils sont utilisés aujourd'hui: il faut formaliser les exigences, le processus de développement, il faut écrire du code programme et le tester, construire une release, etc. Malgré une telle abondance de tâches, le le choix d'un langage de programmation peut jouer le rôle le plus important, car il détermine un ensemble des paramètres suivants:
- Base de référence sur la vitesse du logiciel.
- , .
- , . , .
- // , .
- , , .
- .
En outre, le choix d'un langage de programmation peut également affecter de manière significative les problèmes méthodologiques, par exemple, les outils de l'écosystème du langage peuvent déterminer comment et dans quelle mesure les tests unitaires sont écrits. Une bonne infrastructure pour les tests de propriétés peut donner un coup de pouce dans cette direction, et le manque d'une bonne infrastructure pour les tests unitaires peut les rendre difficiles à écrire et à maintenir.
Les outils affectent également les problèmes d'architecture - la réutilisation des modules dans le système est liée à la commodité de diviser conceptuellement les blocs et de structurer le code. Par exemple, travailler explicitement avec des systèmes d'effets vous permet de généraliser davantage le code et de vous assurer que le module de code n'effectue pas d'opérations d'E / S, comme travailler avec le réseau et le disque, ce qui vous permet de raisonner sur la sécurité et l'architecture.
Sur cette base, vous devez être conscient que le choix du bon langage de programmation pour un projet et une équipe peut avoir des conséquences considérables. En gardant à l'esprit l'analogie des échecs, nous gardons à l'esprit que chaque petit plus ira à la tirelire de la langue et peut jouer un rôle important dans un grand développement. Il convient également de mentionner que nous parlons de choisir un outil de développement pour des situations où il n'y a pas de restrictions strictes sur le choix des technologies en relation, par exemple, avec un grand écosystème déjà écrit sur quelque chose. Chez Typeable, nous sommes guidés par les considérations suivantes pour les langages à usage général:
- . . , , .
- — , , . . - , , , .
- . GIL (Global Interpreter Lock) . .
- , . , , , .
- . , CS . « » , IT , .
- , .
En raison de tout ce qui précède, il y a suffisamment de blocs dans notre boîte à outils qui nous permettent de prendre une position confiante dans de nombreux projets. Pour en revenir à l'analogie des échecs, ce sont nos principes qui nous permettent de jouer un jeu positionnel. Le jeu positionnel est un jeu visant à créer une position à long terme qui ouvre des opportunités pour le joueur et minimise ses faiblesses. Il s'oppose à un jeu offensif, «pointu», où il y a une grande part de risque, et l'attaquant essaie de terminer ce jeu avant que son adversaire puisse prendre une bonne position défensive. Le développement «pointu» est la programmation Olympiade, MVP pour les expériences marketing, de nombreuses tâches en science des données et souvent la création de logiciels qui accompagnent les publications en informatique. Ils sont unis par le fait qu'ils n'ont souvent pas besoin de soutien à long terme,ils n'ont besoin de travailler qu'à un moment donné. Le jeu positionnel est un jeu à long terme, où la maintenabilité et l'évolutivité sont des indicateurs clés. C'est ce que nous faisons, et nous avons besoin d'une bonne base pour être confiants dans les performances à long terme des logiciels que nous écrivons et mettons à jour. De tels projets peuvent également démarrer avec MVP, mais ils sont réalisés avec des prérequis complètement différents.
Pourquoi la liste de considérations pour le choix des technologies est-elle exactement comme ça? Il y a plusieurs raisons à cela. Premièrement, il est souhaitable d’exclure les questions de mode et d’évolution de la technologie afin d’accroître la prévisibilité sur une longue période. Un compilateur avec une longue histoire et une communauté active est, certes un choix conservateur, mais fiable, par opposition aux nouvelles choses brillantes qui apparaissent d'année en année. Certains d'entre eux passeront sûrement de la dernière catégorie à la première, mais nous le saurons plus tard, probablement dans des années. Au lieu de tendances, nous essayons d'utiliser l'informatique fondamentale et un grand nombre de recherches sur ce sujet qui ont trouvé une application dans les langages de programmation que nous utilisons. Par exemple: la théorie des types est une discipline connexe des mathématiques et de la CS qui traite des questions fondamentales de la formalisation des exigences. C'est exactement ce quece dont nous avons besoin pour écrire un logiciel. De plus, c'est l'expérience cumulative d'autres personnes engagées dans les sciences exactes, et il est en quelque sorte stupide, à mon avis, de négliger cette expérience. Il vaut mieux prendre une telle discipline comme base que ne rien prendre ou prendre une opinion subjective basée sur l'expérience de vie d'une seule personne.
Deuxièmement, nous recherchons la mise en œuvre du plus grand nombre de principes que nous avons pris dans les langages de programmation et les compilateurs. Pour cette raison, en plus de notre bien-aimé Haskell, Rust a commencé à apparaître dans notre boîte à outils. Avec des exigences en temps réel et des limites strictes d'utilisation de la mémoire, nous avons besoin de quelque chose d'assez bas niveau. La rigueur de frappe en C laisse encore beaucoup à désirer, donc s'il est possible d'utiliser Rust pour une telle tâche, nous préférerions le faire.
Troisième raison: nous fabriquons des logiciels principalement pour nos clients, et nous souhaitons qu'ils soient protégés de nos préjugés. Par conséquent, lors du choix d'un instrument, le risque ne peut pas dépasser un certain niveau, qui doit être convenu avec le client. Mais même dans de telles conditions, nous avons des technologies assez marginales comme GHCJS, car avec l'analyse combinée des forces et des faiblesses, le tableau était toujours attractif pour nous et nos clients. Nous avons déjà écrit sur la façon dont nous en sommes arrivés à cette décision: Elm vs Reflex .
Lorsque vous travaillez avec de grandes bases de code et des logiciels complexes, tous les moyens et justifications théoriques sont bons, car vous devez d'une manière ou d'une autre être en mesure de maîtriser cette complexité. Notre idée de la bonne approche est de défendre chaque pion, d'améliorer sa position en douceur et avec précision, afin que le projet puisse survivre en bon état jusqu'au moment où il peut jouer un rôle décisif pour l'activité de nos clients. Nous vous souhaitons la même chose.