URL: https://linuxfr.org/users/vroum/journaux/un-premier-contact-avec-le-langage-nim Title: Un premier contact avec le langage Nim Authors: Vroum Date: 2019年07月03日T17:26:35+02:00 License: CC By-SA Tags: nim, compilation, langage et objective-c Score: 30 Au gré de mes pérégrinations sur Github, j'ai trouvé un [benchmark de serveur Web](https://github.com/christianparpart/WebFrameworkBenchmark) qui date un peu mais qui m'a interpelé. J'avais déjà entendu parlé du [langage Nim](http://nim-lang.org/) mais je le classais plutôt comme projet de recherche. [En regardant de plus près](https://nim-lang.org/documentation.html), je tombe sur une version 0.20 aboutie et un [éco-système](https://nimble.directory/) déjà très riche. Nim se décrit comme un langage compilé statiquement typé qui propose également la méta-programmation (macros), un ramasse-miette, le "pattern-matching" fonctionnel et une compilation vers les langages C, C++, Objective-C ou JavaScript. Le but affiché est d'être aussi rapide que le C, aussi expressif que le python et extensible comme du Lisp. Rien que ça! On est en droit d'être sceptique... Or le langage a véritablement [beaucoup d'attraits](https://en.wikipedia.org/wiki/Nim_(programming_language)) et la prise en main est quasi-immédiate surtout pour des personnes familières avec Python. Je vous propose quelques liens à la fin du journal pour parcourir plusieurs exemples de code. ##Première évaluation## Mon premier objectif de test était de vouloir comparer bêtement la taille d'un exécutable avec une version de référence en C. Pour ce faire, je pars sur un équivalent classique à la commande `/bin/true` de GNU Coreutils. Le code d'exemple ne comprend qu'une seule ligne: ``` % cat ./true.nim quit(QuitSuccess) ``` ##Compilation## La [documentation dédiée à la compilation](https://nim-lang.org/docs/nimc.html) est très bien écrite et la commande de compilation est immédiate: ``` /tmp % nim c true.nim Hint: used config file '/etc/nim/nim.cfg' [Conf] Hint: system [Processing] Hint: widestrs [Processing] Hint: io [Processing] Hint: true [Processing] CC: stdlib_system.nim CC: true.nim Hint: [Link] Hint: operation successful (14111 lines compiled; 0.479 sec total; 16.008MiB peakmem; Debug Build) [SuccessX] % ls --human --size ./true /bin/true 88K ./true 36K /bin/true ``` Résultat plutôt logique pour un premier jet. Je peux améliorer la taille de l'exécutable final avec quelques options: ``` nim c -d:release --newruntime --opt:size true.nim % ls --human --size ./true /bin/true 40K ./true 36K /bin/true ``` De mieux en mieux... et en regardant de plus près avec `strace`, je vois que du code utilise une gestion des signaux désactivable avec l'option `-d:noSignalHandler`. La documentation propose également de désactiver les vérifications "runtime" avec `--checks:off`. Voyons ce que ça donne: ``` nim c --verbosity:2 -d:release --checks:off -d:noSignalHandler --newruntime --opt:size true.nim % ls --human --size ./true /bin/true % 20K ./true 36K /bin/true ``` Impressionnant! Nous sommes maintenant arrivés à une taille largement inférieure à ma version de référence. Mais nous pouvons même faire encore mieux avec un dernier appel à la commande `strip`... ``` % ls --size --human ./true =true 16K ./true 36K /bin/true ``` ##Dernier détail## Cependant un dernier détail me chiffonne avec la sortie de `ldd` qui fait apparaître la librairie `libdl.so.2 ` dans ma version. J'ai beau chercher avec les options de linkage `passL:` mais je n'arrive pas à l'éviter. Il ne me reste plus qu'à reprendre la ligne du compilateur présentée avec le mode verbose et ne pas établir manuellement ce lien: ``` % gcc -o /tmp/true .cache/nim/true_r/stdlib_allocators.nim.c.o .cache/nim/true_r/stdlib_system.nim.c.o .cache/nim/true_r/true.nim.c.o % ldd ./true linux-vdso.so.1 (0x00007fff5918e000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff1d239e000) /lib64/ld-linux-x86-64.so.2 (0x00007ff1d258a000) ``` ##Conclusion## *Victoire!* Mes sorties `ldd` et `strace` sont maintenant strictement identiques à la version GNU Coreutils mais j'ai gagné 45% sur mon exécutable final ;-) ##Exemples de code Nim## J'ai essayé de classer les sites dans un ordre de progression: - https://nim-by-example.github.io/ - https://narimiran.github.io/nim-basics/ - https://akehrer.github.io/posts/getting-started-with-nim/ - https://xmonader.github.io/nimdays/ - https://arthurtw.github.io/2015/01/12/quick-comparison-nim-vs-rust.html - https://howistart.org/posts/nim/1/ ##Épilogue## La [documentation du module `system`](https://nim-lang.org/docs/system.html) précise que l'appel à `quit` est implicite. Le fichier source `true.nim` peut donc être vide pour le même résultat ! De plus, mon exemple est trop simpliste ici mais sachez que vous pouvez utiliser autre chose que `gcc` très facilement. Par exemple: ``` nim c --gcc.exe:musl-gcc --gcc.linkerexe:musl-gcc ... ```

AltStyle によって変換されたページ (->オリジナル) /