IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

La version 1.4.0 du langage de programmation Nim est disponible avec les fonctions strictes
Ainsi que plusieurs ajouts et modifications dans la bibliothèque standard

Le , par Bill Fassinou

53PARTAGES

3  0 
Nim (anciennement Nimrod) est un langage de programmation compilé et typé statiquement. Nim combine des concepts réussis de langages matures comme Python, Ada, C++ et Modula. La première version stable de Nim est parue en septembre 2019 avec de nombreuses fonctionnalités. L’équipe vient de livrer une nouvelle version, Nim 1.4.0, avec de nouvelles fonctionnalités, dont les fonctions strictes, un nouveau GC, ainsi que quelques changements et modifications dans la bibliothèque standard “stdlib”. Voici un aperçu de ce dont il s’agit dans cette version.

GC : ORC

Un nouvel algorithme de comptage de référence appelé ARC a d'abord été livré avec Nim 1.2. Selon l’équipe Nim, ARC fonctionne avec la totalité de la bibliothèque standard, à l'exception de l'implémentation actuelle de la fonction async, car elle introduit des cycles que ARC ne gère pas. Il y a toutefois d'autres implémentations d'async en cours de développement qui n'introduisent pas de cycles. Pour résoudre ce problème, l’équipe a introduit ORC. Il s’agit de l'algorithme ARC existant plus un collecteur de cycles. Selon l’équipe, --gc:orc constitue la principale nouveauté de cette version.

Les fonctions strictes

Une fonction f est dite stricte si, lorsqu'elle est appliquée à une expression non terminale, elle ne se termine pas non plus. Une fonction stricte dans la sémantique de dénotation des langages de programmation est une fonction f, où f(v)=v . L'entité v, appelée bottom, désigne une expression qui ne renvoie pas une valeur normale, soit parce qu'elle bouge sans fin, soit parce qu'elle s'interrompt en raison d'une erreur telle que la division par zéro. Une fonction qui n'est pas stricte est appelée non stricte. Intuitivement, les fonctions non strictes correspondent à des structures de contrôle.


Sur le plan opérationnel, une fonction stricte est une fonction qui évalue toujours son argument ; une fonction non stricte est une fonction qui pourrait ne pas évaluer certains de ses arguments. Les fonctions ayant plus d'un paramètre peuvent être strictes ou non strictes dans chaque paramètre indépendamment, ainsi que conjointement strictes dans plusieurs paramètres simultanément. Un langage de programmation strict est un langage dans lequel les fonctions définies par l'utilisateur sont toujours strictes.

Selon l’équipe, il ne s’agit ici que d’une fonctionnalité expérimentale. Elle est disponible via le commutateur {.experimental: "strictFuncs".}--experimental:strictFuncs ou via pragma dans votre code. Elle introduit une définition plus stricte d'un “effet secondaire" : si un objet est accessible via un paramètre qui n'est pas déclaré comme paramètre var, toute mutation de cet objet compte comme un effet secondaire.

Ajouts et modifications de la bibliothèque standard

  • ajout de quelques améliorations au module std/jsonutils ;
  • ajout d'une possibilité de désérialiser les tableaux JSON directement en types HashSet et OrderedSet et respectivement de sérialiser ces types en tableaux JSON via les procédures jsonutils.fromJson et jsonutils.toJson ;
  • ajout d'une possibilité de désérialiser les objets nuls JSON en objets d'option Nim et respectivement de sérialiser l'objet d'option Nim en objet JSON “if isSome” ou en objet JSON null “if isNone” via les procédures jsonutils.fromJson et jsonutils.toJson ;
  • ajout d'un paramètre Joptions à jsonutils.fromJson contenant actuellement deux options booléennes allowExtraKeys et allowMissingKeys ;
  • si allowExtraKeys est True, alors l'objet de Nim vers lequel JSON est analysé n'a pas besoin d'avoir un champ pour chaque clé JSON ;
  • si allowMissingKeys est True, alors l'objet de Nim sur lequel le JSON est analysé est autorisé à avoir des champs sans clés JSON correspondantes ;
  • ajout de bindParams, bindParam à db_sqlite pour lier les paramètres dans une instruction SqlPrepared ;
  • ajout de tryInsert,insert procs à db_*libs qui accepte le nom de la colonne de la clé primaire ;
  • ajout du support xmltree.newVerbatimText pour créer des styles et du texte de script ;
  • ajout de “DOM Parser” au module “dom” pour la cible JavaScript ;
  • le hachage par défaut pour Ordinal a changé pour quelque chose de plus brouillé. import hashes ; proc hash(x: myInt) : Hash = hashIdentity(x) récupère l'ancien dans un contexte d'instanciation tandis que -d:nimIntHash1 le récupère globalement ;
  • les descripteurs de fichiers créés à partir d'abstractions de haut niveau dans la stdlib ne seront plus hérités par les processus enfants. En particulier, ces modules sont affectés : asyncdispatch, asyncnet, system, nativesockets, net et selectors ;
  • les descripteurs de fichiers créés pour la comptabilité interne par ioselector_kqueue et ioselector_epoll ne seront plus divulgués aux processus enfants ;
  • etc.

Changements au niveau du compilateur

  • les avertissements spécifiques peuvent désormais être transformés en erreurs via --warningAsError[X]:on|off ;
  • les pragmatismes define et undef ont été dévalorisés ;
  • ajout d’une nouvelle commande : “nim r main.nim [args...]” qui compile et exécute main.nim, et implique --usenimcache de sorte que la sortie est enregistrée dans $nimcache/main$exeExt, en utilisant la même logique que nim c -r pour éviter les recompilations lorsque les sources ne changent pas ;
  • ajout du nouveau hint --hint:msgOrigin qui montre où un message de compilation (hint|warning|error) a été généré ; cela aide en particulier lorsqu'il n'est pas évident de savoir d'où il vient, soit parce que plusieurs endroits génèrent le même message, soit parce que le message implique un formatage d'exécution ;
  • ajout du nouveau drapeau --backend:js|c|cpp|objc (ou -b:js etc), pour modifier le backend ; peut être utilisé avec n'importe quelle commande (par exemple nim r, doc, check etc.) ;
  • ajout du nouveau drapeau --doccmd:cmd pour passer des drapeaux supplémentaires pour les RunnableExamples, par exemple : --doccmd:-d:foo --threads use --doccmd:skip pour passer les RunnableExamples et les premiers snippets de test ;
  • etc.


Source : Note de version Nim 1.4.0

Et vous ?

Qu'en pensez-vous ?

Voir aussi

La première version finale de Nim, le langage doté d'un transcompilateur vers C, C++, JavaScript est disponible, avec des ajouts

Nim 1.2 est disponible, le langage de programmation introduit plusieurs nouvelles macros pour gérer certaines tâches courantes

Nim 0.12 : un langage multiparadigme rapide qui s'approche de sa première version finale avec l'inclusion d'une machine virtuelle

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de JPLAROCHE
Membre expérimenté https://www.developpez.com
Le 19/10/2020 à 11:49
pour vous aidez ... référence https://nim-lang.org/blog/2020/10/15/introduction-to-arc-orc-in-nim.html

Commençons par un peu d'histoire: Nim a traditionnellement été un langage de récupération de place (GC). La plupart de la bibliothèque standard repose sur le GC pour fonctionner. Bien sûr, vous pouvez désactiver le GC et faire une gestion manuelle de la mémoire, mais vous perdez alors l'accès à la plupart des stdlib (ce qui est https://nim-lang.org/docs/lib.html ).
Le GC par défaut dans Nim a été refc(reporté comptage de référence avec une phase de marquage et de balayage pour la collecte du cycle) pendant une longue période, avec d' autres options disponibles, telles que markAndSweep, boehm et go.
Mais au cours des dernières années, il y a eu de nouvelles idées pour Nim, liées aux destructeurs, aux refs possédés (newruntime), etc.
https://nim-lang.org/araq/destructors.html
https://nim-lang.org/araq/ownedrefs.html
Certaines de ces différentes idées ont émergé dans l'ARC.
Qu'est-ce que l'ARC?
À la base, ARC est un modèle de gestion de la mémoire basé sur le comptage automatique de références avec des destructeurs et une sémantique de déplacement. Certaines personnes confondent l'ARC de Nim avec l'ARC de Swift, mais il y a une grande différence: l'ARC dans Nim n'utilise pas le RC atomique.
Le comptage de références est l'un des algorithmes les plus populaires pour libérer les ressources inutilisées du programme. Le nombre de références pour toute référence gérée (contrôlée par le runtime) correspond au nombre de fois où cette référence est utilisée ailleurs. Lorsque ce nombre devient zéro, la référence et toutes ses données sous-jacentes sont détruites.
La principale différence entre les GC ARC et Nim est que l'ARC est entièrement déterministe - le compilateur injecte automatiquement des destructeurs lorsqu'il estime qu'une variable (une chaîne, une séquence, une référence ou autre) n'est plus nécessaire. En ce sens, il est similaire au C ++ avec ses destructeurs (RAII). Pour illustrer, nous pouvons utiliser l' expandArc introspection de Nim (est disponible dans Nim 1.4).
Considérons un code simple:

proc main =
let mystr = stdin.readLine()

case mystr
of "hello":
echo "Nice to meet you!"
of "bye":
echo "Goodbye!"
quit()
else:
discard

main()
main()
#Et puis utilisez l'ARC IR de Nim sur la main procédure en exécutant nim c --gc:arc --expandArc:main example.nim.
var mystr
try:
mystr = readLine(stdin)
case mystr
of "hello":
echo ["Nice to meet you too!"]
of "bye":
echo ["Goodbye!"]
quit(0)
else:
discard
finally:
`=destroy`(mystr)

Ce que nous voyons ici est vraiment intéressant - le compilateur Nim a enveloppé le corps du main proc dans une try: finally instruction (le code finally s'exécute même lorsqu'une exception est levée dans le try bloc) et a inséré un =destroy appel à la variable mystr (qui est initialisé au moment de l'exécution). qu'il est détruit lorsqu'il n'est plus nécessaire (à la fin de sa durée de vie).
Cela montre l'une des principales fonctionnalités de l'ARC: la gestion de la mémoire basée sur l'étendue .
Une étendue est une région de code distincte dans le programme.
Le MM basé sur la portée signifie que le compilateur insérera automatiquement des appels de destructeur pour toutes les variables qui ont besoin d'un destructeur après la fin de la portée.
De nombreuses constructions Nim introduisent de nouvelles portées: procs, funcs, convertisseurs, méthodes, block instructions et expressions, for et while boucles, etc.

ARC a également des soi-disant hooks - des procédures spéciales qui peuvent être définies pour les types afin de remplacer le comportement par défaut du compilateur lors de la destruction / déplacement / copie de la variable. Celles-ci sont particulièrement utiles lorsque vous souhaitez créer une sémantique personnalisée pour vos types, traiter des opérations de bas niveau impliquant des pointeurs ou faire FFI.
Les principaux avantages de l'ARC par rapport au refc GC actuel de Nim sont (y compris ceux dont j'ai parlé ci-dessus):
• Gestion de la mémoire basée sur l'étendue (les destructeurs sont injectés après l'étendue) - réduit généralement l'utilisation de la RAM des programmes et améliore les performances.
• Déplacer la sémantique - la capacité du compilateur à analyser statiquement le programme et à convertir les copies de mémoire en mouvements lorsque cela est possible.
• Tas partagé - différents threads ont accès à la même mémoire et vous n'avez pas besoin de copier des variables pour les transmettre entre les threads - vous pouvez à la place les déplacer. Voir aussi une RFC sur l'isolement et l'envoi de données entre les threads )
• FFI plus facile ( refc nécessite que chaque thread étranger configure le GC manuellement, ce qui n'est pas le cas avec ARC). Cela signifie également que ARC est un bien meilleur choix pour créer des bibliothèques Nim à utiliser à partir d'autres langages (.dll, .so, extensions Python , etc.).
• Convient pour la programmation en temps réel difficile .
• L'élision de copie (inférence de curseur) réduit les copies à de simples curseurs (alias) dans de nombreux cas.

Généralement, ARC est une étape incroyable pour que les programmes deviennent plus rapides, utilisent moins de mémoire et ont un comportement prévisible.
Pour activer ARC pour votre programme, tout ce que vous avez à faire est de compiler avec le –gc:arc commutateur, ou de l'ajouter au fichier de configuration de votre projet ( .nims ou .cfg).
Problème avec les cycles

Pour trouver et collecter ce cycle, nous avons besoin d'un collecteur de cycles - une partie spéciale du runtime qui trouve et supprime les cycles qui ne sont plus nécessaires dans le programme.
Dans Nim cycle, la collecte a été effectuée par la phase de marquage et de balayage du refc GC, mais il est préférable d'utiliser l'ARC comme base pour améliorer quelque chose. Cela nous amène à:
ORC - Collecteur de cycles de Nim
ORC est le tout nouveau collecteur de cycle de Nim basé sur ARC.
Il peut être considéré comme un GC à part entière car il comprend une phase de traçage local (contrairement à la plupart des autres GC de traçage qui font un traçage global). ORC est ce que vous devez utiliser lorsque vous travaillez avec l'asynchrone de Nim car il contient des cycles qui doivent être traités.
ORC conserve la plupart des avantages d'ARC à l'exception du déterminisme (partiellement) - par défaut, ORC a un seuil adaptatif pour la collecte des cycles, et le temps réel dur (partiellement), pour la même raison. Pour activer ORC, vous devez compiler votre programme avec --gc:orc, mais ORC deviendra probablement le GC par défaut de Nim à l'avenir.
2  0