Question

Il me semble que la chose la plus précieuse d'un langage de programmation statique / fortement typé est qu'il aide refactoring. Si / quand vous modifiez l'API, le compilateur vous dira ce que le changement a cassé

Je peux imaginer le code d'écriture dans un runtime / langage faiblement typé ... mais je ne peux pas imaginer refactoring sans l'aide, et je ne peux pas imaginer écrire des dizaines de milliers de lignes de code sans refactoring du compilateur.

Est-ce vrai?

Était-ce utile?

La solution

Je pense que vous êtes quand amalgamant types sont contrôlés par la façon dont ils sont contrôlés. typage Runtime est pas nécessairement faible.

Le principal avantage des types statiques est exactement ce que vous dites: ils sont exhaustifs. Vous pouvez être sûr tous les sites d'appel sont conformes au type tout en laissant le compilateur le faire est chose.

La principale limitation des types statiques est qu'ils sont limités dans les contraintes qu'ils peuvent exprimer. Cela varie selon la langue, avec la plupart des langues ayant des systèmes de type relativement simples (c, java), et d'autres avec des systèmes de type extrêmement puissants (haskell, poivre de Cayenne).

En raison de ce type de limitation de leur propre chef ne sont pas suffisantes. Par exemple, dans les types java sont plus ou moins limité à la vérification correspondent les noms de type. Cela signifie que le sens de toute contrainte que vous voulez vérification doit être codé dans un schéma de nommage d'une sorte, d'où la pléthore de indirections et plaque de la chaudière commune au code java. C ++ est un peu mieux que les modèles en permettent un peu plus d'expressivité, mais ne viennent pas à ce que vous pouvez faire avec des types dépendants. Je ne sais pas ce que les inconvénients aux systèmes de type plus puissants sont, si bien qu'il doit y avoir certaines personnes ou plus seraient les utiliser dans l'industrie.

Même si vous utilisez le typage statique, les chances sont il ne suffit pas d'expression pour vérifier tout ce que vous aimez, vous aurez donc besoin d'écrire des tests aussi. Que typage statique vous permet d'économiser plus d'effort que nécessite dans boilerplate est un débat qui fait rage depuis des siècles et que je ne pense pas a une réponse simple pour toutes les situations.

Quant à votre deuxième question:

Comment peut-on re-facteur en toute sécurité dans une langue tapée d'exécution?

La réponse est des tests. Vos tests doivent couvrir tous les cas qui comptent. Les outils peuvent vous aider à évaluer le degré de vos tests sont exhaustifs. outils de vérification de couverture vous permettent de connaître les lignes de code castrés sont couvertes par les tests ou non. Outils de mutation de test (bouffon, Heckle) peuvent vous faire savoir si vos tests sont logiquement incomplètes. des tests d'acceptation vous permettent de savoir ce que vous avez écrit les exigences de matchs, et enfin des tests de régression et de performance vous assurer que chaque nouvelle version du produit conserve la qualité du dernier.

L'une des grandes choses au sujet d'avoir des tests appropriés en place contre compter sur indirections de type élaborée est que le débogage devient beaucoup plus simple. Lors de l'exécution des tests que vous avez échoué affirmations spécifiques dans les tests qui expriment clairement ce qu'ils font, plutôt que des déclarations obtus d'erreur du compilateur (c ++ pensent les erreurs de modèle).

Peu importe les outils que vous utilisez: le code d'écriture que vous êtes confiant dans exigera un effort. Il est fort probable, il faudra écrire beaucoup de tests. Si la peine pour les bugs est très élevé, comme l'aéronautique ou le logiciel de contrôle médical, vous devrez peut-être utiliser des méthodes mathématiques formelles pour prouver le comportement de votre logiciel, ce qui rend ce développement extrêmement coûteux.

Autres conseils

Je suis totalement d'accord avec votre sentiment. La souplesse qui Les langages typés dynamiquement sont censés être bon à est en fait ce qui rend le code très difficile à maintenir. Vraiment, est-il une telle chose comme un programme qui continue de travailler si les types de données sont modifiés d'une manière non trivial sans modifier le code?

Dans le même temps, vous pouvez vérifier le type de variable étant passé, et ne parviennent pas en quelque sorte si ce ne est pas le type attendu. Vous auriez encore exécuter votre code pour déraciner ces cas, mais au moins quelque chose diriez-vous.

Je pense que les outils internes de Google font en fait une compilation et tapez probablement vérifier leur Javascript. Je voudrais avoir ces outils.

Pour commencer, je suis un programmeur Perl natif donc d'une part, je ne l'ai jamais programmé avec le filet de types statiques. OTOH Je ne l'ai jamais programmé avec eux donc je ne peux pas parler à leurs avantages. Ce que je peux dire à ce que son goût à factoriser.

Je ne trouve pas le manque de types statiques pour un problème WRT refactoring. Ce que je trouve un problème est l'absence d'un refactoring navigateur . Les langages dynamiques ont le problème que vous ne savez pas vraiment ce que le code va vraiment faire jusqu'à ce que vous exécutez réellement. Perl a ce plus que la plupart. Perl a le problème supplémentaire d'avoir une très compliquée, presque non analysable, la syntaxe. Résultat: aucun outil de refactoring (si ils travaillent très rapidement sur cette ). Le résultat final est que je dois factoriser à la main. Et c'est-ce que présente les bogues.

J'ai des tests pour les attraper ... en général. Je ne me trouve souvent devant une pile de cuisson à la vapeur code invérifiable non testé et proche avec le problème de la poule / oeuf d'avoir à factoriser le code afin de le tester, mais avoir à le tester afin de le refactoriser. Ick. À ce stade, je dois écrire un niveau très stupide, haute « fait la sortie du programme de la même chose qu'il a faite avant » sorte de tests juste pour que je ne casse quelque chose.

types statiques, comme prévu en Java ou C ++ ou C #, vraiment résoudre seulement une petite classe de problèmes de programmation. Ils garantissent vos interfaces sont transmises bits de données avec l'étiquette droite. Mais juste parce que vous obtenez une collection ne signifie pas que la collection contient les données que vous pensez. Parce que vous obtenez un entier ne signifie pas que vous avez l'entier droit. Votre méthode prend un objet utilisateur, mais est-ce l'utilisateur connecté?

Exemple classique: public static double sqrt(double a) est le signature de la fonction racine carrée Java. Racine carrée ne fonctionne pas sur les nombres négatifs. Où est-il dire que dans la signature? Il ne fonctionne pas. Pire encore, où est-il dire que cette fonction ne même? La signature ne dit que ce type qu'il faut et ce qu'il retourne. Il ne dit rien sur ce qui se passe entre les deux et c'est où vit le code intéressant. Certaines personnes ont essayé de capturer l'API complète en utilisant conception par contrat , qui peut généralement être décrit comme l'intégration des tests d'exécution des entrées de votre fonction, les sorties et les effets secondaires (ou son absence) ... mais c'est un autre spectacle.

Une API est beaucoup plus que les signatures de fonction (si ce n'était pas, vous ne seriez pas besoin de toute cette prose descriptive dans le Javadocs) et refactoring est beaucoup plus même que juste changer l'API.

Le plus grand avantage de refactoring un statiquement typé, compilé statiquement, langue non dynamique vous donne est la possibilité d'écrire des outils de refactoring pour faire refactorisations assez complexes pour vous parce qu'il sait où tous les appels à vos méthodes. Je suis jaloux de IntelliJ IDEA .

Je dirais que refactoring va au-delà ce que le compilateur peut vérifier, même dans les langues statiquement typé. Refactoring est juste en train de changer une structure interne des programmes sans affecter le comportement extérieur. Même dans les langages dynamiques, il y a encore des choses que vous pouvez vous attendre à passer et test, vous perdez un peu d'aide du compilateur.

L'un des avantages de l'utilisation var en C # 3.0 est que vous peut changer souvent le type sans casser le code. Le type a besoin de regarder toujours les mêmes propriétés - avec les mêmes noms doivent exister, méthodes avec la signature identique ou similaire doit toujours exister. Mais vous pouvez vraiment changer à un type très différent, même sans utiliser quelque chose comme ReSharper.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top