L'utopie du typage fort et dynamique

- Alors, ça avance ta quête des types dynamiques qui sont vérifiés sans pour autant être déclarés partout ? 😏
- Ça avance pas mal. Je crois que je tiens une piste mais il va falloir laisser tomber Python.
- Et pour prendre quoi ? TypeScript ? Ça ne sera pas mieux.
- Presque. Un langage qui a un parent en commun avec TypeScript.
- 🤨 ?
- Ne fais pas cette tête et regarde plutôt le code.

 1int Pgcd(int p, int q)
 2{
 3  while (q != 0)
 4    (p, q) = (q, p % q);
 5  return p;
 6}
 7
 8void AffichePgcd(dynamic p, dynamic q) =>
 9  Console.WriteLine($"PGCD = {Pgcd(p, q)}");
10
11AffichePgcd(48, 18);

- C'est du C#. C'est un langage à typage statique. Ça n'a rien à voir.
- Ah ? Et le type dynamic pour les paramètres de la fonction AffichePgcd ? 🙄
- De toutes façons, en C#, si tu appelles la fonction Pgcd avec des nombres à virgule, ça ne va même pas compiler.
- On parie ? 😜

 1int Pgcd(int p, int q)
 2{
 3  while (q != 0)
 4    (p, q) = (q, p % q);
 5  return p;
 6}
 7
 8void AffichePgcd(dynamic p, dynamic q) =>
 9  Console.WriteLine($"PGCD = {Pgcd(p, q)}");
10
11AffichePgcd(48.0+0.3-0.1-0.2, 18.0);

- Ça compile ce truc ? 🤔
- Oui. On peut même l'exécuter.
- Donc ça va faire la même erreur de calcul qu'en Python.
- Ou pas. 😁

Unhandled exception. Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot implicitly convert type 'double' to 'int'. An explicit conversion exists (are you missing a cast?)
at CallSite.Target(Closure, CallSite, Object)
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
at Program.<<Main>$>g__AffichePgcd|0_1(Object p, Object q)
at Program.<Main>$(String[] args)

- Ah ! Mais il y a de la vérification à l'exécution. Oui. On peut faire ça en Python. Mais ça vaut rien, ça plombe les perfs. Au mieux, c'est utilisable pour les tests, mais pas en prod. Regarde, je peux l'écrire comme ça.

 1from typeguard import typechecked
 2
 3@typechecked
 4def pgcd(p: int, q: int) -> int:
 5  while q != 0:
 6    p, q = q, p % q
 7  return p
 8
 9def affiche_pgcd(p, q):
10  print(f"PGCD = {pgcd(p, q)}")
11
12affiche_pgcd(48.0, 18.0)

Et on a une erreur similaire à ce que tu as en C#.

typeguard.TypeCheckError: argument "p" (float) is not an instance of int

- Mais pourquoi tu n'utilises pas ça pour ta fonction PGCD, alors ? 😲
- Parce que au niveau perfs, c'est pas jouable. J'ai fait l'essai avec ce code :

1start = time.time()
2for _ in range(1000000):
3  pgcd(48, 18)
4print(f"Durée : {time.time() - start} secondes")

Sur ma machine, ça donne presque 23 secondes avec @typechecked contre 0.2 secondes sans la vérification à l'exécution. Ya pas photo.
Mais ça va être pareil avec ton C#. La vérification des types à l'exécution, ça ne pardonne pas.

- Ok. J'ai la même machine que toi. J'essaie tout de suite. 🏃

1var start = DateTime.Now;
2for (var i = 0; i < 1000000; i++)
3  Pgcd(48, 18);
4Console.WriteLine($"Durée : {(DateTime.Now - start).TotalSeconds} secondes");

On est à 0.05 secondes.

- Normal, mais là tu as du code compilé avec un typage statique, donc c'est logiquement plus rapide.
- Pour forcer l'utilisation de variables dynamiques, je rajoute une fonction intermédiaire.

1dynamic DynamicPgcd(dynamic p, dynamic q) => Pgcd(p, q);
2
3var start = DateTime.Now;
4for (var i = 0; i < 1000000; i++)
5  DynamicPgcd(48, 18);
6Console.WriteLine($"Durée : {(DateTime.Now - start).TotalSeconds} secondes");

- Ne te précipite pas. Ça va prendre un peu plus longtemps pour s'exécuter. ⏳
- Non, c'est déjà fini en 0.1 secondes. 🚀
- 😶
- Je te laisse encaisser le choc et on reprend plus tard.

[TO BE CONTINUED]

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