Réponse courte: non, car équivalence de Turing.
Réponse longue: Ce mec est un troll. S'il est vrai que les systèmes de types "vous limitent à un sous-ensemble", les éléments extérieurs à ce sous-ensemble sont, par définition, des éléments qui ne fonctionnent pas.
Tout ce que vous êtes capable de faire dans n'importe quel langage de programmation complet de Turing (qui est un langage conçu pour la programmation à usage général, et beaucoup d'autres qui ne le sont pas; c'est une barre assez basse à effacer et il existe plusieurs exemples d'un système qui devient Turing- terminé involontairement) que vous pouvez faire dans n'importe quel autre langage de programmation Turing-complete. C'est ce qu'on appelle «l'équivalence de Turing» et cela ne signifie exactement que ce qu'elle dit. Surtout, cela ne signifie pas que vous pouvez faire l'autre chose tout aussi facilement dans l'autre langage - certains diront que c'est tout l'intérêt de créer un nouveau langage de programmation en premier lieu: pour vous donner une meilleure façon de faire certains des choses que les langues existantes sucent.
Un système de type dynamique, par exemple, peut être émulé au-dessus d'un système de type OO statique en déclarant simplement toutes les variables, paramètres et valeurs de retour comme Object
type de base , puis en utilisant la réflexion pour accéder aux données spécifiques à l'intérieur, donc quand vous vous rendez compte vous voyez qu'il n'y a littéralement rien que vous puissiez faire dans un langage dynamique que vous ne pouvez pas faire dans un langage statique. Mais le faire de cette façon serait un énorme gâchis, bien sûr.
Le gars de la citation a raison: les types statiques limitent ce que vous pouvez faire, mais c'est une fonctionnalité importante, pas un problème. Les lignes sur la route restreignent ce que vous pouvez faire dans votre voiture, mais les trouvez-vous restrictives ou utiles? (Je sais que je ne voudrais pas conduire sur une route très fréquentée et complexe où rien ne dit aux voitures qui vont dans la direction opposée de rester à leurs côtés et de ne pas venir où je conduis!) En établissant des règles qui définissent clairement ce qui est considéré comme un comportement invalide et en veillant à ce qu'il ne se produise pas, vous réduisez considérablement les risques de survenue d'un crash indésirable.
En outre, il dénature l'autre côté. Ce n'est pas que "tous les programmes intéressants que vous voulez écrire fonctionneront comme des types", mais plutôt "tous les programmes intéressants que vous voulez écrire nécessiteront des types". Une fois que vous avez dépassé un certain niveau de complexité, il devient très difficile de maintenir la base de code sans un système de type pour vous maintenir en ligne, pour deux raisons.
Premièrement, parce que le code sans annotations de type est difficile à lire. Considérez le Python suivant:
def sendData(self, value):
self.connection.send(serialize(value.someProperty))
À quoi pensez-vous que les données ressembleront que le système à l'autre extrémité de la connexion recevra? Et s'il reçoit quelque chose qui semble complètement faux, comment déterminez-vous ce qui se passe?
Tout dépend de la structure de value.someProperty
. Mais à quoi ça ressemble? Bonne question! Qu'est-ce qui appelle sendData()
? Qu'est-ce que ça passe? À quoi ressemble cette variable? D'où vient-il? Si ce n'est pas local, vous devez retracer l'historique complet de value
pour retrouver ce qui se passe. Peut-être que vous passez quelque chose d'autre qui a également une someProperty
propriété, mais il ne fait pas ce que vous pensez qu'il fait?
Maintenant, regardons-le avec des annotations de type, comme vous pouvez le voir dans le langage Boo, qui utilise une syntaxe très similaire mais qui est typé statiquement:
def SendData(value as MyDataType):
self.Connection.Send(Serialize(value.SomeProperty))
S'il y a quelque chose qui ne va pas, tout à coup, votre travail de débogage est devenu plus simple: recherchez la définition de MyDataType
! De plus, la possibilité d'obtenir un mauvais comportement parce que vous avez passé un type incompatible qui a également une propriété avec le même nom passe soudainement à zéro, car le système de type ne vous laissera pas faire cette erreur.
La deuxième raison s'appuie sur la première: dans un projet vaste et complexe, vous avez très probablement plusieurs contributeurs. (Et sinon, vous le construisez vous-même sur une longue période, ce qui est essentiellement la même chose. Essayez de lire le code que vous avez écrit il y a 3 ans si vous ne me croyez pas!) Cela signifie que vous ne savez pas ce qui était passer par la tête de la personne qui a écrit presque n'importe quelle partie du code au moment où ils l'ont écrit, parce que vous n'étiez pas là, ou ne vous souvenez pas si c'était votre propre code il y a longtemps. Avoir des déclarations de type vous aide vraiment à comprendre quelle était l'intention du code!
Les gens comme le gars dans la citation décrivent fréquemment les avantages du typage statique comme étant "d'aider le compilateur" ou "tout sur l'efficacité" dans un monde où les ressources matérielles presque illimitées rendent cela de moins en moins pertinent chaque année. Mais comme je l'ai montré, bien que ces avantages existent certainement, le principal avantage réside dans les facteurs humains, en particulier la lisibilité et la maintenabilité du code. (L'efficacité supplémentaire est certainement un bon bonus!)