Excursion dans le typage fort et dynamique

- D'après ce que tu m'as dit la dernière fois, je comprends que tu veux laisser tomber Python pour C# sous prétexte qu'il gère mieux les types dynamiques à l'exécution ?
- 🤨 Non, il n'y a pas de meilleur langage. Il n'y a que des contextes différents. Il faut apercevoir les limites de chaque langage.
- Si on visite tous les langages, ça va durer un moment. ⏳️
- Non, juste le typage dynamique. L'inférence de type en typage statique est un sujet différent. Ça a le goût du typage dynamique mais ce n'en est pas.
- Mais c'est quoi le sujet alors ?
- Le typage dynamique, qu'on l'aime ou pas, c'est une façon différente de coder. Beaucoup de personnes la trouvent utile et cela suffit à ne pas négliger la question des garde-fous disponibles contre les erreurs d'exécution.

- Alors, on continue comment ?
- Il y a des langages qui sont, par essence, dynamiques. Les types ne sont qu'une notion interne.
- Python, JavaScript, Ruby...
- Oui, en Python, on a ces hints pour les types mais on a vu qu'il faut une discipline de dingue pour les mettre partout et en faire quelque chose de vérifiable.
- Et TypeScript ?
- Il a plusieurs avantages sur Python : la vérification est dans le compilateur, pas dans un outil externe et, surtout, la disponibilité des librairies JavaScript courantes sous forme typée est gigantesque. Mais, si on code le même programme en TypeScript...
- Déjà fait.

 1function pgcd(p: bigint, q: bigint): bigint {
 2  while (q != 0n) {
 3    [p, q] = [q, p % q];
 4  }
 5  return p;
 6}
 7
 8function affiche_pgcd(p, q) {
 9  console.log(`PGCD = ${pgcd(p, q)}`);
10}
11
12affiche_pgcd(48n, 18n);
13affiche_pgcd(48.0, 18.0);
14affiche_pgcd(48.0+0.3-0.1-0.2, 18.0);

- Et ça donne quoi ?
- Pareil qu'en Python 🐍

PGCD = 6
PGCD = 6
PGCD = 7.105427357601002e-15

- Pourquoi q != 0n ? Pourquoi pas q !== 0n ?
- Parce qu'avec une égalité stricte, la condition n'est jamais vérifiée, un number ne peut pas être égal à un bigint et on part en boucle infinie. 🤷‍♂️
- Donc, quelque part, c'est pire que Python. Si on n'a pas la discipline de mettre des types partout, on s'expose à des comportements qui seront très difficiles à débugger. 🧨

- Donc C# serait une exception ?
- C# combine typage dynamique et statique. C'est assez rare.
- Il y a Dart 🎯 aussi.
- Ok, essayons de voir...
- Déjà fait.

 1int pgcd(int p, int q) {
 2  while (q != 0) {
 3    var temp = q;
 4    q = p % q;
 5    p = temp;
 6  }
 7  return p;
 8}
 9
10void affichePgcd(dynamic p, dynamic q) {
11  print("PGCD = ${pgcd(p, q)}");
12}
13
14void main() {
15  affichePgcd(48, 18);
16  affichePgcd(48.0, 18.0);
17}

- Et ça donne quoi ?
- Pareil qu'en C#

6
Unhandled exception:
type 'double' is not a subtype of type 'int'
#0 affichePgcd (pgcd.dart:11:14)
#1 main (pgcd.dart:16:3)
#2 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#3 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

- Mais ce n'est peut être pas spécifique aux langages qui proposent un typage dynamique en complément du typage statique.
- 🤨
- Avec C# et Dart, on a des langages qui ont été pensés pour le typage statique et où le typage dynamique est un plus. Il faut donner un type, même si celui-ci est dynamic. D'ailleurs, en C# la surcouche Dynamic Language Runtime n'existait pas au départ.
- Et ?
- Et on trouve aussi des langages où le typage dynamique est présenté comme étant le plus naturel. Par exemple, avec Groovy. Le typage statique existe mais il y est généralement secondaire.

 1static def pgcd(int p, int q) {
 2  while (q != 0) {
 3    (p, q) = [q, p % q]
 4  }
 5  return p
 6}
 7
 8def affichePgcd(p, q) {
 9  println "PGCD = ${pgcd(p, q)}"
10}
11
12static void main(String[] args) {
13  affichePgcd(48, 18)
14  affichePgcd(48.0, 18.0)
15}

- Et ça donne pareil qu'en C# et Dart ?
- What else ? ☕

PGCD = 6
Caught: groovy.lang.MissingMethodException: No signature of method: static Main.pgcd() is applicable for argument types: (BigDecimal, BigDecimal) values: [48.0, 18.0]
Possible solutions: pgcd(int, int), find(), wait(), run(), run(), any()
groovy.lang.MissingMethodException: No signature of method: static Main.pgcd() is applicable for argument types: (BigDecimal, BigDecimal) values: [48.0, 18.0]
Possible solutions: pgcd(int, int), find(), wait(), run(), run(), any()
at Main.affichePgcd(Main.groovy:9)
at Main.run(Main.groovy:14)

- Mmmm... Je ne sais pas quoi penser de tout ça.
- On tentera une conclusion mais là c'est l'heure de la pause.

[TO BE CONTINUED]

Une réaction ? Un commentaire ? Rejoignez la discussion.   linkedin   twitter