web-dev-qa-db-fra.com

Quel langage de programmation génère le moins de bogues difficiles à trouver?

Quelle langue, à votre avis, permet au programmeur moyen de produire des fonctionnalités avec le moins de bogues difficiles à trouver? C'est bien sûr une question très large, et je suis intéressé par des réponses et des idées très générales et générales.

Personnellement, je trouve que je passe très peu de temps à rechercher des bogues étranges dans les programmes Java et C #, tandis que le code C++ a son ensemble distinct de bogues récurrents, et Python/similaire a son propre ensemble de bogues communs et bogues stupides qui seraient détectés par le compilateur dans d'autres langues.

Je trouve également difficile de considérer les langages fonctionnels à cet égard, car je n'ai jamais vu un programme gros et complexe écrit en code entièrement fonctionnel. Votre contribution s'il vous plaît.

Edit: Clarification complètement arbitraire d'un bug difficile à trouver: prend plus de 15 minutes pour se reproduire, ou plus d'une heure pour trouver la cause et le corriger.

Pardonnez-moi s'il s'agit d'un doublon, mais je n'ai rien trouvé sur ce sujet spécifique.

54
Magnus Wolffelt

Plus le système de type du langage est puissant, plus il y aura de bugs détectés au moment de la compilation.

La figure suivante compare certains des langages de programmation bien connus en termes de puissance, de simplicité et de sécurité de leurs systèmes de type. [ Source ]

alt text

* Prise en compte de la capacité à utiliser des constructions dangereuses.

C # est placé dans la ligne non sécurisée en raison du mot clé "non sécurisé" et de la machinerie de pointeur associée. Mais si vous voulez les considérer comme une sorte de mécanisme de fonction étrangère en ligne, n'hésitez pas à déplacer C # vers le ciel.

J'ai marqué Haskell 98 comme pur, mais GHC Haskell comme non pur en raison de la famille de fonctions non sécurisée *. Si vous désactivez dangereux *, sautez GHC Haskell vers le haut en conséquence.

58
missingfaktor

À mon avis, Haskell vous aide à éviter certaines sources d'erreur courantes:

  • c'est purement fonctionnel: les fonctions ne peuvent pas avoir d'effets secondaires (involontaires) et cela rend la programmation multicœur plus facile et moins sujette aux erreurs
  • il est fortement tapé: vous ne pouvez pas par exemple mélanger accidentellement les valeurs bool, char, int et float
  • il est typé statiquement: de nombreuses erreurs de programmation sont détectées au moment de la compilation
  • null ne fait pas partie des définitions de type de valeur: vous évitez ainsi erreur d'un milliard de dollars
  • il existe de nombreuses fonctions prédéfinies d'ordre supérieur que vous pouvez réutiliser au lieu d'écrire vos propres implémentations, éventuellement défectueuses.
  • il a un garbage collector: les erreurs de mémoire sont presque éliminées (sauf pour les "fuites d'espace" dues à sa stratégie d'évaluation paresseuse)
20
LennyProgrammers

Traditionnellement, les bogues les plus difficiles à trouver sont les conditions de concurrence dans les applications multithreads telles qu'elles sont.

  • presque impossible à reproduire
  • peut être très subtil

Par conséquent, vous avez besoin de langages qui gèrent le parallélisme pour vous autant et discrètement que possible. Ceux-ci ne sont pas encore courants. Java en fait, mais vous laisse avec la partie difficile.

À ma connaissance, vous avez besoin d'un langage fonctionnel puisque le "pas d'effets secondaires" est la chose qui, en premier lieu, fait disparaître les deux puces. J'ai vu que le travail se poursuit pour faire de Haskell un langage multi-thread efficace et je crois que Fortress est conçu dès le départ pour être un langage parallèle efficace.


Edit: In Java Executors gère encore plus de parties dures. Vous devez rendre les tâches individuelles conformes à l'interface Callable.

18
user1249

Ada est conçu pour que le plus possible soit capturé au moment de la compilation plutôt qu'au moment de l'exécution. Cela signifie qu'il faut souvent environ 10 fois plus de temps pour compiler un programme dans Ada que l'équivalent en Java disons, mais quand il compile, vous pouvez être beaucoup plus confiant que des classes entières des bogues ne se manifesteront pas lors de l'exécution du programme.

13
Mark Pim

Tout d'abord une définition: un bug difficile à trouver, si je comprends bien, est un bug qui peut être reproduit mais la cause est difficile à trouver.

L'aspect le plus important est probablement ce que j'appellerais étroitesse, c'est-à-dire jusqu'où un bug peut-il s'échapper, quelle est la portée qu'un bug peut potentiellement influencer. Dans des langages comme C, un bug, par exemple un index de tableau négatif ou un pointeur non initialisé peut affecter littéralement tout partout dans tout le programme, donc dans le pire des cas, vous devez vérifier tout partout pour trouver la source de votre problème.

De bonnes langues à cet égard prennent en charge les modificateurs d'accès et les appliquent d'une manière qui rend difficile ou impossible de les contourner. De bons langages vous encouragent à limiter la portée de vos variables, au lieu de rendre trop facile d'avoir des variables globales (par exemple "tout ce qui n'est pas explicitement déclaré est une variable globale avec un type et une valeur par défaut").

Le deuxième aspect important est simultanéité. Les conditions de course sont généralement difficiles à reproduire et donc difficiles à trouver. Les bons langages offrent des mécanismes de synchronisation faciles à utiliser, et leurs bibliothèques standard sont thread-safe lorsque cela est nécessaire.

Cela complète déjà ma liste; d'autres choses comme une frappe forte aident à détecter les bogues au moment de la compilation, mais ces bogues ne seront probablement pas difficiles à trouver plus tard.

Compte tenu de tout cela, je dirais que Java et C #, et de nombreux autres langages dans le monde JVM et .net, sont adaptés pour éviter les bogues difficiles à trouver.

7
user281377

Étant donné qu'Excel est le DSL le plus largement utilisé, j'irai avec Excel. (hors VBA bien sûr)

Cela correspond au projet de loi:

  • C'est toujours facile à reproduire (voici une feuille de calcul - ça ne marche pas)
  • Il est assez facile de trouver le bogue, car il est totalement "fonctionnel" - commencez par la cellule qui ne va pas et retracez toutes ses dépendances.
7
Scott Whitlock

C'est une question difficile parce que la plupart des bogues ne sont pas la faute du langage lui-même - c'est plutôt la faute des développeurs qui font des erreurs dans la façon dont ils utilisent le langage.

Je crois que plusieurs aspects des fonctionnalités du langage affectent la probabilité de bugs:

  • Interactivité - les langages dynamiques avec REPL encouragent l'interaction/l'expérimentation avec les programmes en cours d'exécution et les cycles de code/test beaucoup plus petits. Si vous pensez que l'itération est un bon moyen de découvrir des solutions simples et propres et de détecter/éliminer les bogues, cela aurait tendance à favoriser les langages interactifs.

  • Expressivité - si le code est plus court et a moins de complexité passe-partout/incident, alors il est plus facile de voir les bogues/erreurs logiques.

  • Sécurité du type - plus le temps de compilation est vérifié, plus le compilateur détecte de bogues, donc en général, la sécurité des types est une bonne chose. Cependant, ceux-ci ne sont généralement pas difficiles à trouver bogues - même dans un langage entièrement dynamique, le mauvais type dans une structure de données provoquera généralement une erreur d'exécution très évidente, et TDD reprend presque toujours ce type de bugs.

  • Immuabilité - beaucoup de bogues durs sont dus à des interactions complexes d'état mutable. Les langages qui mettent l'accent sur l'immuabilité (Haskell, Clojure, Erlang) ont un énorme avantage en évitant la mutabilité

  • Programmation fonctionnelle - les approches fonctionnelles pour écrire du code ont tendance à être plus "prouvablement correctes" que le code orienté objet avec des séquences complexes d'effets/interactions. Mon expérience est que FP aide à éviter les bugs délicats - je crois qu'il y a des recherches académiques quelque part que je ne trouve pas actuellement qui corroborent cela.

  • Prise en charge de la concurrence - les problèmes de concurrence sont particulièrement difficiles à détecter et à déboguer, c'est pourquoi cela est si important. Tout ce qui nécessite un verrouillage manuel est finalement voué à l'échec (et cela inclut à peu près chaque approche orientée objet de la concurrence). Le meilleur langage que je connaisse à cet égard est Clojure - il a une approche unique de gestion de la concurrence qui combine la mémoire transactionnelle logicielle avec des structures de données immuables pour obtenir un cadre de concurrence nouveau, fiable et composable. Voir http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey pour plus d'informations

7
mikera

Moins une langue est puissante, moins elle vous offre d'options pour tirer votre propre pied.

Les langages de haut niveau comme Java et C # produiront moins de bogues que les langages de bas niveau comme C++.

Cela dit, je crois que Java est plus sûr que C #. Java est artificiellement limité de sorte qu'un programmeur moyen sans connaissances avancées puisse le maîtriser et produire des programmes stables.

5
user8685

Quelle langue, à votre avis, permet au programmeur moyen de produire des fonctionnalités avec le moins de bogues difficiles à trouver?

À mon avis, Delphi. Étant basé sur Pascal, le langage est assez simple et intuitif pour que le programmeur moyen (ou même des codeurs inexpérimentés) puisse les détecter facilement, et son riche outil et son support de bibliothèque rendent la plupart des bogues faciles à trouver.

  • Typage fort et compilateur strict qui détecte de nombreuses erreurs courantes.
  • Syntaxe intuitive qui n'encourage pas les erreurs courantes. ("Le dernier bogue du monde", if (alert = RED) {LaunchNukes;}, ne se compilera pas, par exemple.)
  • Un modèle d'objet bien conçu qui élimine la plupart des erreurs C++ OOP) courantes.
  • Vérification des limites et vérification des plages intégrées dans la langue, réduisant considérablement les risques de problèmes de sécurité.
  • Probablement le compilateur le plus rapide connu de l'homme, ce qui augmente votre productivité et rend plus difficile de perdre le fil de vos pensées en attendant une version.
  • Le débogueur du débogueur de Visual Studio veut être comme quand il grandit.
  • Suivi des fuites intégré directement au gestionnaire de mémoire, rendant la recherche et la correction des fuites de mémoire triviales.
  • Une grande bibliothèque standard mature fournissant des moyens préconstruits et pré-testés pour accomplir des tâches courantes sans avoir à créer vos propres implémentations, éventuellement boguées.
  • Livré avec des outils utiles, tels qu'un puissant système de journalisation et un profileur, pour faciliter le suivi des problèmes.
  • Prise en charge solide de la communauté pour les problèmes courants qui ne sont pas dans la bibliothèque standard, y compris ne puissante bibliothèque de concurrence tierce .
3
Mason Wheeler

Une chose à prendre en compte est le délai d'exécution.

Au cours des cinq dernières années, j'ai principalement développé des applications Web en Java (JSF, Seam, etc.). Récemment, j'ai obtenu un nouveau travail, et nous utilisons Perl (avec Catalyseur et orignal).

Je suis bien plus productif en Perl qu'en Java.

Ne pas avoir besoin de compiler et de déployer (à chaud), est une des raisons. Je trouve également que l'écriture de cas d'utilisation est plus facile, car cela peut être fait de manière plus itérative. Et les frameworks de Java semblent complexes et inutiles, du moins pour les projets auxquels j'ai participé.

Je suppose que le nombre de bogues dans mon code Perl est plus ou moins le même que le nombre de bogues dans mon Java, il pourrait même être plus élevé. Mais, je trouve et plus facile et plus rapide de trouver et corriger ces bugs.

2
slu

Peut-être qu'une étude du nombre d'outils disponibles pour l'analyse de code statique et dynamique pour chaque langage de programmation pourrait donner une idée. Plus il y a d'outils pour une langue, plus il est probable que la langue soit très populaire parmi les utilisateurs ou très populaire pour générer des bogues difficiles à trouver. Mais je ne parviens pas à faire en sorte que Google me pointe vers une étude réalisée à ce sujet. Il convient également de noter que certains langages tels que C peuvent être utilisés pour contourner les bogues matériels sous-jacents ainsi que pour contourner l'usure du matériel à mesure qu'il vieillit.

1
vpit3833

Au lieu de parler de langues, qu'en est-il des fonctionnalités linguistiques

  • Java vous oblige à penser aux exceptions (throws ...) et vous devez soit publier, soit gérer ces exceptions. Est-ce que cela m'empêche vraiment d'oublier les situations d'erreurs ou est-ce que j'utilise plus d'exceptions dérivées de SystemException qui n'ont pas besoin de cette gestion?
  • qu'en est-il de la "conception par contrat" ​​(http://en.wikipedia.org/wiki/Design_by_contract) qui m'oblige à penser aux pré et postconditions. J'ai lu que c'est maintenant possible avec c # -4.0.
1
k3b