[Nitération] Nouvelles de février 2015

11 views
Skip to first unread message

Jean Privat

unread,
Mar 3, 2015, 10:08:08 AM3/3/15
to nit...@googlegroups.com

Nous avons le plaisir de vous présenter le deuxième numéro de l'année de « Nitération », la lettre d’information du projet Nit.

Les statistiques combinées pour le mois de février 2015 donnent:

$ git diff --shortstat v0.7.1..v0.7.2
587 files changed, 9396 insertions(+), 4472 deletions(-)
$ git log --first-parent v0.7.1..v0.7.2 | grep 'Pull-Request: #' | wc -l
40

Ont contribué (ou ont eu des patchs intégrés): Jean Privat, Alexandre Terrasa, Alexis Laferrière et Lucas Bajolet

NitRPG

Grâce à la bibliothèques d'accès à l'API de Github, un service de ludification du développement de Nit est proposé sous le nom denitrpg.

Le service est accessible en ligne http://nitlanguage.org/rpg/games/privat/nit

Il fonctionne en traquant les événements émis par github (hooks) et attribue des points (nitcoins) en fonction des contributions des joueurs telles que proposer des commits ou relire des pull-requests.

Le logiciel est en cours de développement, des fonctionnalités supplémentaires sont attendues avec impatience par les joueurs.

  • Merge: GitHub misc 67c594b
  • Merge: contrib: Introduce nitrpg 37da033
  • Merge: GitHub merge: some improvements 372a61b
  • Merge: nitrpg: more statistics 4c690dc
  • Merge: Nitrpg: minor fixes 4b38798
  • Merge: Nitrpg: minor fixes 8b3a48b
  • Merge: Nitrpg: introduce game events 40d7753
  • Merge: Nitrpg: add achievements 4514e22

Un userscript est même disponible pour interfacer directement nitrpg depuis github.

  • Merge: nitrpg: add nitrpg.user.js for enhanced user experience 2e9e267

Langage Nit

Constructeurs, la suite

La TODO list des constructeurs est bientôt complétée.

Il est maintenant possible de (re-)définir l'ordre des initialiseurs du constructeur d'une classe.

Bien que rarement nécessaire (par design des nouveaux constructeurs), cela est utile dans trois cas : en cas de conflit d'initialiseurs, pour ordonner des initiateurs, ou pour désactiver/réactiver des initialiseurs dans des sous-classes spécifiques.

Cela se fait par l'annotation de classe autoinit (on réutilise ainsi la même annotation que pour marquer les méthodes comme initialiseurs) suivi de la liste des initialiseurs.

class A
   var a: Int
   var b: String
end

class B
   super A
   var c: Bool
   autoinit c, b, a
end

var a = new A(10, "foo")
var b = new B(true, "foo", 10)

Pour vider la liste des initialiseurs, il faut utiliser l'annotation noautoinit sans argument (choix qui a été préféré à un autoinitsans argument).

class C
   super B
   noautoinit
end
var c = new C
print c.b # BOOM! `b` pas initialisé

Indépendamment noautoinit est devenu synonyme de noinit sur les attributs, le nouveau nom est plus clair et no(auto)initsur les attributs est sémantiquement l'opposé de autoinit sur les méthodes.

class D
   var s: String is noautoinit
end
var d = new D
print d.s # BOOM! `s` pas initialisé
  • Merge: class annotation autoinit to explicitly list initializers. 31ade8f

Notez que, comme dans les exemples précédents, les annotations de classe peuvent enfin être placées où l'on veut dans la classe. Un effet de bord est que cela devient également vrai pour la clause super, ce que plusieurs identifient comme pratique car cela permettrait de regrouper les propriétés par super-classes, en cas d'héritage multiple, pour aider la lecture.

  • Merge: Generalized class members 8c2a37f

Disparition de l'annotation cached

cached sur les méthodes fut l'une des premières annotations à voir le jour, toutefois elle était fragile et posait des problèmes de compréhension au programmeur débutant. L'annotation lazy sur les attributs, apparue plus tard, a été recommandée en replacement car elle est implémentée de façon robuste et plus simple à comprendre.

L'annotation cached a enfin disparue et les quelques cas qui restaient ont été trivialement convertis vers lazy.

Android, portabilité et compagnie

Le travail pour offrir des API de qualité sous Android continue.

  • Merge: Clean up to prepare for NitActivity 4c2b63c
  • Merge: lib/glesv2: intro framebuffer related services and try a new style 80f3b19
  • Merge: Misc commits to android, json::dynamic and more_collections 909e5a8
  • Merge: jwrapper: interfaces, "Compiled from" line and output file without .nit a525b05

Générer du C standard plutôt que générer du code machine pour les différentes architectures matérielles a comme avantage la portabilité, c'est pourquoi le support de 4 architectures Android est maintenant en place.

  • Merge: Support Android on 2 different ARMs, x86 and even MIPS 018974f

Bibliothèques

Ce mois-ci, on observe plusieurs améliorations intéressantes de la bibliothèque standard en terme de robustesse, performance et élégance de l'API.

Map et Set

Suivant l'exemple des Map du mois dernier, c'est au tour des Set d'accepter null comme élément. Rien de fondamental mais c'est plus élégant.

Le service Map::get_or_null a été optimisé dans les HashMap et, tant qu'à faire, utilisé là où cela semblait pertinent. L'intérêt du service est double : il est plus rapide qu'un has_key suivi d'un [] et il évite au programmeur de répéter la valeur du map et celle de la clé.

  • Merge: Optimize get_or_null d81bebe

Strings

Les types virtuels de string, dont l'objectif est de maintenir une symétrie entre les services de String et ceux de Buffer, ont été figés ce qui permet d'éviter les erreurs de redéfinitions qui brisent l'API. Le comportement des services dans Buffer reste toutefois peu intuitif, du travail de design reste encore à faire.

  • Merge: Fix virtual types in string 4b52524

Moins de fuites mémoire dans les services de String.

  • Merge: String memory fixes e61c0af

Flots

Les noms des classes de la hiérarchie des flots, tels que IFStream, faisaient l'unanimité contre eux. C'est pourquoi, la plupart ont été renommées avec des identifiants que l'on espère plus KISS et POLA.

Ainsi, les classes de base sont nommées Reader pour les flots d'entrée, Writer pour les flots de sortie et Duplex pour les flots d'entrée-sortie ; la superclasse commune s'appelle Stream et ne contient (pour l'instant?) que les services de fermeture (close) et d'interrogation d'erreur (last_error). Les sous-classes spécifiques suivent un schéma régulier tel que FileReader,FileWriterFileDuplex et FileStream.

La classe Streamable a été renommée en Writable qui représente mieux l'idée d'un objet qui peut être écrit (efficacement) dans un fichier (write_to_file), sous forme de chaîne (write_to_string) ou refilé à un Writer qui saura en faire quelque chose (write_to).

Vim

Le plugin Vim a été amélioré au niveau de l'auto-complètement.

D'une part les modules importés sont scannés ce qui améliore le complètement de base (ctrl-P). D'autre part, un omnifunc (ctrl-x ctrl-o) a été développé pour Nit ce qui permet un complètement plus syntaxique/sémantique et affiche la documentation des entités suggérées.

  • Merge: Better Vim autocomplete by scanning all imported modules 526e24b
  • Merge: Vim omnifunc for Nit ade7bf3
  • Merge: Vim omnifunc diffentiate between types, class declaration and instanciation 104c5e8

Compilateur, outils et trucs internes

Régénération du bootstrap

Sous la pression populaire, le compilateur primitif résidant dans c_src a été régénéré.

L'ancien a servi pendant 3 mois, le précédent 3 mois aussi, et celui d'avant 4 mois. On note une certaine régularité, rendez-vous dans quelques mois pour voir si cela se confirme.

Une nouveauté cette fois, le compilateur primitif ne dépend plus de libunwind ce qui permet de boostrapper manuellement sur les architectures ne disposant pas de la bibliothèque comme le Raspberry Pi.

  • Merge: Regen c_src without libunwind 5e632af

Le make initial en profite également pour compiler les outils avec l'option --semi-global. Cela allonge un petit peu la durée dumake mais produit des binaires plus efficaces. Les utilisateurs devraient y gagner au final.

  • Merge: Makefile: initial make use --semi-global 2e96c12

Projets dans le path

Le loader sait chercher les projets dans le path des bibliothèques de Nit. Cela permet, par exemple, à la commande nitls standard de lister les modules de la bibliothèque standard sans avoir besoin de lister le chemin exact. Cette fonctionnalité est utilisée par le plugin Vim pour nourrir l'auto-complètement.

  • Merge: loader: get_mgroup look in path 372e462

Re-mise en service de l'option --log

L'option --log fournie par les outils était utilisée par l'ancien compilateur nitc mais a été oubliée dans la conversion vers le nouveau compilateur. Cet oubli a été en partie réparé et les outils commencent maintenant à produire divers fichiers d'information si on leur demande gentiment.

Covariance

L'outil d'analyse des cas d'utilisation de la covariance a été nettoyé et intégré à nitmetrics. L'interprétation des résultats reste toutefois à refaire sur le nouveau code.

Les chiffres bruts, sans analyse, sont disponibles grâce à Jenkins pour qui ça intéresse (cherchez Detection of the usage of covariance static type conformance dans le fichier).

Optimisations à l'édition de liens

Le compilateur séparé gagne --substitute-monomorph, une nouvelle optimisation globale à l'édition de liens (inspirée de ce que faisait le vénérable PRM). L'idée est de remplacer les appel polymorphes via VFT de la compilation séparée classique par un appel direct à un symbole.

Ainsi, au lieu de coder l'appel de méthode par

(RECV->VFT[COLOR])(ARGS)

on a plutôt

SYMBOL(ARGS)

Lors de l'édition de liens, une analyse globale est effectuée : si l'appel est monomorphe, le symbole est résolu directement vers la méthode cible ; sinon le symbole est résolu vers une courte fonction (appelée trampoline) qui effectue un appel polymorphe traditionnel via VFT.

Au final, et par rapport au comportement par défaut du compilateur séparé, les appels monomorphes sont optimisés (appel direct, vs. appel via VFT) mais les appels polymorphes sont plus lents (appel du trampoline en plus de l'appel via VFT). Le pari est que le gain sur les appels monomorphes compense la perte sur les appels polymorphes.

Pour l'instant, les évaluations préliminaires ne montrent pas un gain spectaculaire. Toutefois l'application du monomorphisme est améliorable car actuellement elle se fait au niveau de la propriété globale et non au niveau du site d'appel. En effet, actuellement un seul symbole est utilisé par propriété globale, donc la substitution vers le monomorphisme se fait seulement si tous les sites d'appels de cette propriété globale sont monomorphes.

Enfin, une nouvelle option --link-boost active toutes les optimisations globales à l'édition de liens (c'est-à-dire celle présenté ci-dessus ainsi que --colors-are-symbols introduite précédemment)

Une implémentation alternative (option --call-gard) évite l'utilisation d'un trampoline mais utilise une garde sur le symbole et inline l'appel via VFT si la garde échoue.

if SYMBOL != null then
   SYMBOL(ARGS)
else
   (RECV->VFT[COLOR])(ARGS)
end

On a un coût systématique supplémentaire à cause du test mais un call (un jump en fait) de moins si la garde échoue. Les résultats montrent que la garde est bien pire (jusqu'à 10% de perte) que l'approche originale qui est de faire des appels systématique via VFT.

Compilation encore plus séparée

Dans les fichiers C générés, les chemins des fichiers utilisés pour afficher les erreurs dynamiques (tels que cast et assert échoués) ne sont plus des littéraux mais des variables globales. Cela à l'avantage d'alléger les fichiers C mais surtout de les rendre plus indépendants du répertoire de compilation.

En effet, les chemins des fichiers sont la plupart du temps relatifs donc dépendent du répertoire de compilation ce qui n'est pas optimal dans un contexte de compilation indépendante des modules. Maintenant, la plupart des fichiers C produits ne dépendent que du module compilé et non plus du programme client ou du répertoire de travail.

De plus, l'outil ccache est capable de réutiliser les produits de compilation même provenant de répertoire de compilation distincts. Ceci accélère le temps de recompilation même quand plusieurs répertoires .nit_compile sont utilisés.

  • Merge: Global for filenames 606eedf

Nitdoc

nitdoc a été fortement refactorisé et différents modules créés en fonction des différentes préoccupations de l'outil d'auto-documentation.

De plus, le framework développé permet de manipuler les éléments de documentation indépendamment de leur rendu ce qui augmente la modularité de l'outils et permettra à terme un développement plus simple.

Ce travail s'est fait sans modification fondamentale du HTML généré. On attend donc la suite.

  • Merge: nitdoc: introduces phases 0dc7c7d
  • Merge: Nitdoc: HTML templates related cleaning d9a8631

Divers

  • Merge: parser: slight improvement of the README e9cf564
  • Merge: Generalize instance creation service so FFI can use it f9c9c25
  • Merge: nitunit: fix running last test of a module, it was previously ignored b74de4e
  • Merge: parser: add ASTDump and ANode::dump_tree 48bbbbc
  • Merge: Add tasks in benchmark/bench_engines 8dd99e0
Reply all
Reply to author
Forward
0 new messages