URL:
https://linuxfr.org/news/raku-en-2020
Title: Raku en 2020
Authors: contra-sh
BAud, Davy Defaud, palm123, Bruno Ethvignot, orfenor, Yves Bourguignon, Xavier Claude, Ysabeau, bubar, Pierre Jarillon, Benoît Sibaud et Adrien Dorsaz
Date: 2020-11-09T08:43:44+01:00
License: CC By-SA
Tags: raku et rakudo
Score: 7
~~Perl 6~~ Raku est un langage puissant et mature qui fut assez difficile à mettre en œuvre (ce qui sera abordé dans la deuxième partie de la dépêche).

Raku est né « Perl 6 », mais n’est pas/plus la prochaine version de Perl 5 (qui sera Perl 5.34 ou Perl 7, voire la dépêche [annonce de Perl 7](
https://linuxfr.org/news/annonce-de-perl-7)). Raku a, d’ailleurs, été renommé en 2019 pour clarifier ce positionnement. Raku partage en effet avec Perl 5 :
- des caractéristiques techniques (proche du langage naturel, [sigils](
https://fr.m.wikipedia.org/wiki/Sigil_(informatique))…) ;
- la même fondation ;
- les mêmes conférences ;
- en partie leurs communautés (Damian Conway, Larry Wall…) ;
- certains évènements ([Perl Weekly Challenge](
https://perlweeklychallenge.org/)…).
----
[Tester Raku en ligne](
https://repl.it/languages/raku)
[Raku](
https://www.raku.org/)
[Rakudo](
https://rakudo.org/)
[MoarVM](
https://www.moarvm.org/)
----
# À propos de Raku
## Préambule
Raku est (devenu) bien trop « différent » de Perl 5. On peut à présent dire tout simplement « Perl » pour désigner Perl 5 ou Perl 7 et on préférera « Raku » en toutes circonstances pour parler de Perl 6. Il fut un temps où la communauté Perl 6 était plutôt contre le changement de nom, mais l’opinion générale a changé et le renommage a pu se faire en douceur entre 2018 et 2019 (voir plus loin pour les détails).
Vous pouvez suivre l’actualité du langage en vous abonnant à la newsletter _[Rakudo Weekly News](
https://rakudoweekly.blog/)_.
Raku possède une petite communauté et quelques « _killer apps_ » :
- [Cro](
https://cro.services/), une boîte à outils pour le Web (applications, services) ;
- [Sparrow](
https://github.com/melezhik/Sparrow6) un cadriciel d’automatisation, ainsi que ses [modules](
http://sparrowhub.io/) ;
- son IDE « [Comma](
https://commaide.com/) » ;
- un (petit) [CPAN](
https://modules.raku.org/).
Avant d’aller plus loin, voici quelques liens vers des contenus _LinuxFr.org_ autour du même sujet :
- [dépêche _LinuxFr.org_ sur la première version publique de Raku en 2010](
https://linuxfr.org/news/sortie-de-rakudo-star) ;
- journal _LinuxFr.org_ « [Perl 6 devient Raku](
https://linuxfr.org/users/raum_schiff/journaux/perl6-devient-raku) » ;
- journal _LinuxFr.org_ « [Bientôt Perl 6 pour Noël](
https://linuxfr.org/users/raum_schiff/journaux/bientot-noel-pour-perl6) ».
Une fois n’est pas coutume, parlons un peu de Raku, sa communauté et ses « news » :D.
## Quelques personnalités importantes du monde Raku
Avant de rentrer plus en détail dans le processus de renommage et dans les versions de Raku, mettons à l’honneur quelques personnalités du monde Raku :
- **Jonathan Worthington** : Lead développeur actuel de Rakudo ([interview Jonathan Worthington](
http://www.josetteorama.com/all-about-perl-6-interview-of-jonathan-worthington-part-1-of-3/))
- **Elizabeth Mattijsen** : très impliquée dans Perl 6 ;
- **Patrick Michaud** : ancien lead développeur de Rakudo, NQP, etc. ;
- **Audrey Tang** : actuellement ministre du numérique à Taïwan (!), anciennement développeuse principale de Pugs (implémentation de Perl 6 en Haskell, voir [vieille interview](
http://www.perlcast.com/2006/03/interview-with-audrey-tang.html) ou encore cette [interview](
https://andrewshitov.com/2015/05/05/interview-with-audrey-tang/)) ;
- **Damian Conway** : enseignant, orateur, porte‑parole et développeur prolifique ;
- **Larry Wall** : créateur de Perl (BDFL) et initiateur de Raku. Plus besoin de le présenter ! En 2020, plus vraiment impliqué ;
- **Moritz Lenz** : écrivain et gros contributeur ;
- **Flavio S. Glock** : développeur principal de Perlito.
Tous ne sont pas encore actifs et la liste n’est pas exhaustive !
La communauté Raku a décidé récemment de mettre en place un [comité décisionnaire](
https://github.com/Raku/Raku-Steering-Council/blob/main/announcements/20200720.md).
## Le processus de changement de nom : Perl 6 → Raku
Un langage de programmation qui change de nom, ça n’arrive pas souvent !
Il y a peu, Raku a donc fêté sa première année (ou ses 21 ans !). Voici comment s’est déroulé le renommage :
1. Larry Wall a tout d’abord [proposé un alias](
https://www.youtube.com/watch?v=E5t8qaAGw9w) ;
2. alias demandé par des personnes de la communauté Perl 6 ;
3. validé ensuite par Larry à la conférence Raku à Riga ;
4. plus tard, une des membres de la _core team_ (Elizabeth Mattijsen) ouvre un ticket sur le GitHub officiel de Raku pour un renommage :

5. Elizabeth ouvre ensuite une demande d’intégration sur le dépôt Git officiel de Raku (avec demande de vote des mainteneurs) :

6. les votes sont positifs (ou des abstentions), puis vient la « bénédiction » de Larry Wall :

7. renommage entériné, souhaitons la bienvenue à Raku !
Le processus de renommage en liens :
- août 2017 : _[Original idea for Perl 6 Alias](
https://www.youtube.com/watch?v=E5t8qaAGw9w)_ ;
- octobre 2018 : _[A request to Larry Wall for an alias](
https://perl6.party/post/A-Request-to-Larry-Wall-to-Create-a-Language-Name-Alias-for-Perl-6)_ ;
- novembre 2018 : _[On Raku](
https://liztormato.wordpress.com/2018/11/06/on-raku/)_ ;
- août 2019 : _[Liz issue — Perl in the name is confusing](
https://github.com/Raku/problem-solving/issues/81)_ ;
- août 2019 : _[Liz PR — Path to Raku](
https://github.com/Raku/problem-solving/pull/89)_ ;
- septembre 2019 : _[On renaming Perl 6](
https://andrewshitov.com/2019/09/24/on-renaming-perl-6/)_ ;
- octobre 2019 : _[Blessing of Larry then renaming](
https://github.com/Raku/problem-solving/pull/89#pullrequestreview-300789072)_.
## Versions de Raku(do)
Depuis 2015, l’implémentation de Raku est « complète » et les travaux autour du compilateur et de la VM sont plus orientés vers les performances.
Raku a connu plusieurs versions officielles (dont la plus « marquante » était en 2015) :
- première version publique de Rakudo * en juillet 2010 (version majeure mais incomplète, encore basée sur Parrot donc Rakudo + Parrot) ;
- 6.c « Christmas » en 2015 ([annonce](
https://perl6advent.wordpress.com/2015/12/25/christmas-is-here/)) (Rakudo + MoarVM) ;
- 6.d « Diwali » en novembre 2019 ([détails des nombreux changements](
https://github.com/Raku/roast/blob/master/docs/announce/6.d.md)) (Rakudo + MoarVM) ;
- 6.e sera la prochaine version majeure (Rakudo + MoarVM).
D’où provient ce schéma de versions ?
Tout simplement d’une blague récurrente sur la date de sortie de Raku. Il était coutume de répondre « ça sera prêt pour Noël » comme une blague ou une pirouette :D En plus de ces versions majeures, l’équipe derrière Raku produit des versions mineures mensuelles.
## Quelques livres
Avant d’attaquer les détails du langage, voici quelques livres qui vous permettront d’en apprendre plus sur Raku :
- _[Perl 6 Essentials](
https://www.oreilly.com/library/view/perl-6-essentials/0596004990/)_ ;
- _[Learning Perl 6](
https://www.oreilly.com/library/view/learning-perl-6/9781491977675/)_ ;
- _[Think Perl 6](
https://www.oreilly.com/library/view/think-perl-6/9781491980545/)_ ;
- _[Perl 6 quick syntax reference](
https://www.oreilly.com/library/view/perl-6-quick/9781484249567/)_ ;
- _[Perl 6 deep dive](
https://www.oreilly.com/library/view/perl-6-deep/9781787282049/)_ ;
- _[Raku fundamentals](
https://www.oreilly.com/library/view/raku-fundamentals/9781484261095/)_.
La partie technique commence ici, vous êtes prêts ? :D
## Les qualités intrinsèques de Raku
On ne se refait pas ! Grâce aux qualités de linguiste de son créateur Larry Wall, Raku est très influencé par le langage naturel. Raku est multi‑paradigmes (procédural, fonctionnel, programmation concurrente et orienté objet).
Comme son cousin Perl 5 :
* c’est un langage riche et qui a une notion de « contexte » ;
* ses [[expressions rationnelles]] sont très puissantes et il intègre même une gestion des grammaires directement dans le langage !
* il possède un [CPAN](
https://modules.raku.org/t/CPAN).
Contrairement à lui :
* l’interfaçage avec le code natif est très simple ;
* la programmation orientée objet est native (cadriciel + types objets) ;
* le langage est résistant à la concurrence ;
* Unicode est pris en charge « par défaut ».
Pour des détails techniques supplémentaires, voici le [glossaire de Raku](
https://docs.raku.org/language/glossary) mais également une [comparaison des fonctionnalités entre les compilateurs](
http://web.archive.org/web/20150801100611/http://www.perl6.org/compilers/features) (qui donne un bon aperçu des fonctionnalités du langage). Dans les prochains paragraphes, les qualités/fonctionnalités de Raku seront expliquées plus en détail.
### Le typage
- Typage graduel (typage dynamique et statique) :
```perl
# Dynamique
my Cool $var = 42;
# Statique
my Str $var = "Raku";
```
- Annotation dans les signatures :
```perl
sub ab(Int $a, Int $b) { return $a+$b; };
say ab(1,1);
```
- Inférence de type
- Allomorphs (et évaluation polymorphique) : `IntStr $foo`
- Les jonctions :
```perl
my $jonction = 1|2|3;
$jonction += 4; # jonction maintenant égale à 5|6|7
$jonction += (1&2); # jonction maintenant égale à (6|7|8)&(7|8|9)
```
- [Sous‑ensembles](
https://perl6advent.wordpress.com/2016/12/08/how-to-make-use-and-abuse-perl-6-subsets/) : permet d’étendre les classes isomorphes, servir de contrainte, tout en étant résolu à l’utilisation :
```perl
subset Even where * %% 2;
say 1 ~~ Even; # False
```
- [Coercition](
https://fr.wiktionary.org/wiki/coercition) :
```perl
sub i-cast(Int() $n) { say $n.^name } ;
i-cast "42";
```
- [Coercition dans les signatures (contraintes)](
https://docs.raku.org/type/Signature#Coercion_type)
Contrainte + coercition (« je veux un objet chaîne et je _caste_ en objet entier ») :
```perl
sub f(Int(Str) $want-int, Str() $want-str) { } ;
f '10', 10;
```
Ou contrainte conditionnelle (« mon argument doit être objet entier ou objet chaîne ») :
```perl
sub xyz($n where $_ ~~ Int | Str ) { say +$n }
```
- Types natifs :
```perl
my int8 $verysmall = 42;
say $verysmall;
```
- Auto‑boxing : conversion automatique de type natif vers les types objets
- Auto‑vivification dans les hash/arrays :
```perl
my %a;
%a{'autovivication'}++;
say %a{'autovivication'};
```
- [Twigils](
https://docs.raku.org/language/variables#Twigils) (!) par exemple pour définir la portée des variables
- Toute une [collection de conteneurs objet](
https://docs.raku.org/language/setbagmix). Voir la [liste de type composites](
https://docs.raku.org/type-composite.html) (Keyset, Bag, Map, list, Mix, Pair, Set...)
- _Shaped array/hashes_ (en quelque sorte des matrices ou hash multi dimensions…)
- Compact arrays : `my int @array` est stocké contigu en natif
- [Listes paresseuses](
https://medium.com/@jcoterhals/perl-6-small-stuff-5-gather-around-its-time-to-get-lazy-but-why-da20fdb18a3b) (voir également `Gather`) :
```perl
my @list = (1, 1, * + * ... *).grep({ $_.is-prime });
say @list[4]; # This generates elements 0..4.
# Elements 5..∞ haven't been generated yet
```
### Routines
- Nommées (argument) :
```perl
sub plus2($foo) { return $foo+2; }
```
- Typées :
```perl
sub mul3(Int $foo) { return $foo*3; }
```
- Avec attribut _rw_ ou _copy_ :
```perl
sub make42($foo is rw) { $foo = 42; }
```
- Multi‑dispatch :
```perl
multi sub sayit( Int $n ) { say "Number: $n"; }
multi sub sayit( Str $s ) { say "String: $s"; }
```
Le dispatch se base sur le nombre d’arguments, les types, les contraintes (on peut même en jouer avec les fonctions nextsame, nextwith, callsame, callwith). Voir aussi « _Proper narrowness analysis_ » pour la résolution du meilleur candidat.
- Gobage gourmand des arguments restants et aplatissement des arguments (comme en Perl 5).
### Opérateurs
- Raku possède une grande quantité d’opérateurs, voyez plutôt :
[](
https://i.imgur.com/4RmbUaO.jpg)
- Raku peut être facilement étendu (voir [doc opérateurs](
https://docs.raku.org/language/operators)) ;
- opérateurs natifs (inline optimisations ou explicite) ;
- les opérateurs peuvent être en UTF‑8 ;
- [opérateurs natifs](
https://6guts.wordpress.com/2011/10/15/an-optimizer-lands-bringing-native-operators/).
### Async, parallélisme et concurrence
Une boîte à outils plus que complète de fonctionnalités pour gérer l’[asynchrone, le parallélisme et la concurrence](
http://doc.perl6.org/language/concurrency) :
- [promises (ou future)](
https://docs.raku.org/language/concurrency#Promises) utilisable avec [Proc::Async](
https://docs.raku.org/language/concurrency#Proc::Async) pour des appels externes ;
- gestion des streams avec [Channel](
https://docs.raku.org/language/concurrency#Channels) et [Supplies](
https://docs.raku.org/language/concurrency#Supplies) pour implémenter de l’_event driven_ comme des _patterns publish/suscribe_ ;
- un accès à des primitives plus bas niveau comme les _[threads, scheduler, locks](
https://docs.raku.org/language/concurrency#Low-level_APIs)_.
### Programmation Orientée Objet et Programmation Meta Objet
Possibilité de définir ses propres opérateurs (vu plus haut) et fonctionnalités. La prise en charge du _meta object programming_ est gérée en partie dans la machine virtuelle :
- héritage simple ou multiple ;
- introspection ;
- [« éditer » une classe après instanciation]([exemple](
https://gist.github.com/draegtun/276591)) une classe après déclaration/instanciation ;
- [composer/encapsuler](
https://perl6advent.wordpress.com/2011/12/14/meta-programming-what-why-and-how/) des méthodes ;
- [Trust relationship](
https://docs.raku.org/type/Metamodel::Trusting) qui permet d’accéder à des méthodes privées d’une autre classe (parente) sans les faire rentrer dans l’héritage ;
- [délégations](
https://laurent-rosenfeld.developpez.com/tutoriels/perl/perl6/objets/#L2-6) `has $.base is rw handles <meth1 meth2>` ;
- type _whatever_ « * » (qui a d’ailleurs donné son nom a la distribution « Rakudo star »).
### Grammaires
Une gestion des [grammaires](
https://docs.raku.org/language/grammars) (`grammar`, `token`, `rule`, `regex`) dans le langage !
```perl
grammar Calculator {
token TOP { <calc-op> }
proto rule calc-op {*}
rule calc-op:sym<add> { <num> '+' <num> }
rule calc-op:sym<sub> { <num> '-' <num> }
token num { \d+ }
}
class Calculations {
method TOP ($/) { make $<calc-op>.made; }
method calc-op:sym<add> ($/) { make [+] $<num>; }
method calc-op:sym<sub> ($/) { make [-] $<num>; }
}
say Calculator.parse('2 + 3', actions => Calculations).made;
```
### Interfaçage
La prise en charge du langage natif est vraiment très facile !
- Interfaçage facile avec les langages natifs (_Native Call_) :
```perl
use NativeCall; sub fork() returns int32 is native {};
```
- Interfaçage avec Perl 5 avec [Inline::Perl5](
https://github.com/niner/Inline-Perl5) :
```perl
use Inline::Perl5;
my $p5 = Inline::Perl5.new;
$p5.call('print', 'Hello World');
$p5.use('Test::More');
$p5.call('Test::More::plan', tests => 1);
```
### Unicode traité au niveau graphème
Très haut niveau de gestion d’Unicode, notamment grâce à des primitives dans la machine virtuelle MoarVM.
Les opérateurs du langage eux‑mêmes peuvent être en UTF‑8 (comme ceux que l’on crée).
### Autres fonctionnalités en vrac
- _[Pointy arrow block](
https://andrewshitov.com/2018/10/31/anonymous-code-blocks-in-perl-6/)_ (closure anonyme) :
```perl
my $cube = -> $x {$x ** 3};
say $cube(3); # 27
```
- [Placeholders](
https://andrewshitov.com/2018/10/31/placeholders-in-perl-6/)
Par ordre alphabétique :
```perl
my $pow = {$^x ** $^y};
say $pow(3, 4); # 81
```
Ou alors :
```perl
for 0..9 {
say "$^n2, $^n1";
}
```
Ou avec nommage :
```perl
my $pow = {$:base ** $:exp};
say $pow(:base(25), :exp(2)); # 625
```
# Compilateurs, cadriciels et machines virtuelles
Dans cette seconde partie, nous allons détailler les mises en œuvre du langage Raku. Préparez‑vous, les acronymes arrivent !
 _Licence Creative Commons CC0 1.0_
## Quelle implémentation « officielle » ?
Réponse courte : **Rakudo et MoarVM**.
Au départ il fut décidé qu’aucune implémentation ne serait définie comme « officielle » pour Raku mais plutôt que « Raku est quelque chose qui réussit la [suite de tests officiels](
https://github.com/Raku/roast) ». En réalité, depuis 2012, il existe une implémentation officielle _de facto_ qui est **Rakudo + MoarVM**.
Avant ça, il y eut le cadriciel Parrot (2002 - 2012) ainsi que Pugs (2005 - 2007) ou encore divers autres compilateurs et environnements d’exécution (Mildew, Niecza, Yapsi…). Cette partie technique et historique sera abordée en fin de dépêche. Mais revenons en arrière pour parler des débuts.
La toute première annonce de la création de Raku date du 19 juillet 2000. L’idée de Larry Wall était d’en faire un projet ultra communautaire jusque dans la conception du langage, et il commencera donc par demander de contribuer aux spécifications. Il en découlera en tout 361 [RFC](
https://raku.org/archive/rfc/), dont Larry wall produira des [apocalypses](
https://raku.org/archive/doc/apocalypse.html) qui seront expliquées ensuite par Damian Conway dans les [exégèses](
https://raku.org/archive/doc/exegesis.html) puis encore détaillées dans les [synopses](
https://design.raku.org/).

Des liens pour les historiens ou les curieux :
- 2000 - 1018 : le dépôt [Raku museum](
https://github.com/Raku/museum-items) sauvegarde partiellement les « événements » qui font partie de l’histoire de Raku ;
- 2000 : [Vieil article de blog critiquant le processus de RFC (au début)](
https://www.perl.com/pub/2000/11/perl6rfc.html/) ;
- 2005 : [Get involved in Pugs](
https://www.perlmonks.org/?node_id=455979) ;
- 2006 : [Get involved in Perl 6](
https://www.perlmonks.org/?node_id=628746) ;
- 2008 : [Get involved in Perl 6](
https://www.perlmonks.org/?node_id=690945) ;
- 2009 : [Get involved in Perl 6](
https://www.perlmonks.org/?node_id=771635) ;
- 2015 : [Entretien Flavio Glock](
https://andrewshitov.com/2015/05/15/interview-with-flavio-glock/).
# Parrot
Créés en [2002](
https://github.com/parrot/parrot/blob/master/docs/parrothist.pod), le cadriciel et la [machine virtuelle Parrot](
http://docs.parrot.org/parrot/latest/html) ont longtemps été au centre de l’implémentation de Raku (ce n’est plus le cas aujourd’hui). Parrot est né d’un poisson d’avril annonçant l’unification de Perl et Python et même la sortie prochaine d’un livre sur le sujet :

Pourquoi construire une *nouvelle* VM ?
La JVM fut étudiée en 2001, mais jugée peu adaptée aux langages dynamiques (elle ne l’était d’ailleurs toujours pas en 2010, _quid_ de 2020 ?).
## Compilation
Parrot offre bien plus d’une machine virtuelle, Parrot est un cadriciel de création, compilation et exécution de langage. Ce cadriciel permet de construire facilement et rapidement des langages de haut niveau (HLL). Il a été mis en pratique par Rakudo pendant longtemps.
### PCT
PCT signifie _Parrot Compiler Tools_. Son but est de permettre la création de compilateur et d’environnement d’exécution de langages de haut niveau (HLL).

PCT est écrit en PIR (voir plus loin section assemblage).
### PAST
PAST signifie _Parrot Abstract Syntax Tree_ : représentation interne d’un arbre syntaxique.
### HLL
HLL signifie _High Level Language_.
### PGE
Au départ appelé P6GE, **PGE** signifie _Perl Grammar Engine_. Se base sur **HLLCompiler**. Une règle PGE ressemble à ça :
```perl
rule term { <number> | \( <expr> \) }
rule number { \d+ }
rule expr { <term> ( '+' <term> )* }
```
PGE était utilisé par Pugs, un autre compilateur Raku (voir plus loin).
### TGE
TGE signifie _Tree Grammar Engine_.
### PACT
[PACT](
https://github.com/parrot/PACT) signifie _Parrot Alternate Compiler Toolkit_. Une alternative à PCT qui était considéré comme trop limité.
## Assemblage
### PASM
PASM signifie _Parrot assembly language_ (PASM). Le code bas niveau prêt à être converti et exécuté par Parrot VM. Du code PASM ressemble à ça :
```asm
set I1, 1
REDO:
gt I1, 10, END
print I1
print " "
inc I1
branch REDO
END:
print "\n"
end
```
Références :
- [exemples de code PASM](
http://www.parrot.org/dev/examples/pasm) ;
- articles LinuxMag des mongueurs FR sur l’écriture d’assembleur Parrot : [1](
http://articles.mongueurs.net/magazines/linuxmag97.html), [2](
http://articles.mongueurs.net/magazines/linuxmag98.html) et [3](
http://articles.mongueurs.net/magazines/linuxmag99.html).
### IMCC
IMCC signifie _Intermediate Code Compiler_. C’est un outil alternatif pour créer et exécuter du _bytecode_ Parrot.
IMCC apporte son propre langage, communément appelé _Parrot Intermediate Language_ (PIR). IMCC embarque le l’environnement d’exécution Parrot, donc IMCC peut compiler du PIR vers PASM, puis du PASM vers PBC, puis exécuter ce _bytecode_. IMCC peut également faire des optimisations, même s’il ne le fait pas par défaut.
### PIR
D’abord appelé IMC, [PIR](
http://docs.parrot.org/parrot/latest/html/docs/user/pir/intro.pod.html) est une surcouche de PASM sans être pour autant un langage de haut niveau. Les fichiers contenant du code PIR portent le suffixe « .imc »
Voici à quoi ressemble PIR :
```asm
sub loopy
.local int counter
counter = 0
LOOP: if counter > 10 goto DONE
print counter
print " "
inc counter
goto LOOP
DONE:
print "\n"
end
end
```
Vous pouvez en apprendre plus grâce à cette [intro IMCC](
https://www.oreilly.com/library/view/perl-6-essentials/0596004990/ch07.html) ou cet article sur comment [écrire du PIR](
http://docs.parrot.org/parrot/latest/html/docs/user/pir/intro.pod.html). Voir ici des [exemples PIR](
http://www.parrot.org/dev/examples/pir) ou encore la [documentation détaillée des mongueurs FR sur PIR](
http://articles.mongueurs.net/magazines/linuxmag122.html).
## Exécution
### NCI
NCI signifie _Native Call Interface_.
### PMC
PMC signifie _PolyMorphic Container_ ou _Parrot Magic Cookies_ (la façon de représenter les données dans la machine virtuelle).
### PBC
BC signife Parrot Byte Code
## La VM Parrot
La VM Parrot est une machine virtuelle à base de registre, ce qui n’est pas la « norme » (par exemple JVM).
Voici quelques fonctionnalités de la VM Parrot :
- capable de gérer les langages statiques et dynamiques ;
- _Copy On Write_ ;
- gère les continuations et closures ;
- peut être embarqué dans du code C ;
- _PolyMorphic Container_ (souplesse du stockage des types).
Il est facile d’inclure Parrot dans du code C ou d’appeler du C dans Parrot (_[Native Call Interface](
http://docs.parrot.org/parrot/latest/html/docs/pdds/draft/pdd16_native_call.pod.html)_).
## Implémentation Raku basée sur Parrot (2002 - 2012)

Ou avec une étape IMCC et Parrot fusionnée (plus tard car IMCC contient Parrot) :

Ci‑dessous un schéma encore plus détaillé/technique (tiré d’une documentation Parrot) :

De nombreux détails sont disponibles dans le _[Parrot Design Document](
http://docs.parrot.org/parrot/latest/html/pdds.html)_.
## Problèmes avec Parrot
Si au départ Parrot était au centre de Raku, cela a changé au cours du temps :
- 2008 : « _While Parrot is the most solid solution to deploy Perl 6 in the long term, on the other hand, the challenges Parrot has accepted had proven to consume more time and resources than previously expected._ » ([_Perl foundation news_](
https://news.perlfoundation.org/post/2008q2_grant_proposal_smop_sim)) ;
- 2013 : « _The latest news is that Parrot Virtual Machine is no longer the only one enjoying Rakudo’s exclusivity._ » (_[all about Perl 6](
http://www.josetteorama.com/all-about-perl-6-interview-of-jonathan-worthington-part-1-of-3/)_) ;
- des problèmes de communication ;
- Parrot s’est petit à petit éloigné de Perl 6 (en devenant plus généraliste).
Petit à petit, le compilateur Rakudo s’est émancipé de Parrot et cible à présent une nouvelle machine virtuelle.
# Rakudo Star (à partir de 2010)
La première version majeure de Rakudo Star (ou « Rakudo * ») se basait sur Parrot (PCT + ParrotVM), mais nous passerons sous silence cette version pour nous concentrer sur l’implémentation actuelle (Rakudo + MoarVM).
## Compilation (Rakudo)
**Rakudo** est un compilateur pour Raku qui implémente la totalité du langage et peut cibler plusieurs différentes VM (la principale étant MoarVM). La majeure partie de Rakudo est écrite en Raku simplifié (NQP). Rakudo implémente également la précompilation pour optimiser ses performances. En plus de ça, Rakudo améliore l’arbre syntaxique à l’aide de plusieurs méthodes d’optimisations dont voici quelques exemples :
- les itérations _range_ converties sont en boucles natives ;
- dé‑virtualisation de méthodes privées avec résolution à la compilation ;
- suppression de code (statiquement) mort ;
- anonymiser une variable ;
- réduire la portée d’une variable ;
- dépliage des jonctions.
### NQP
[NQP](
https://github.com/Raku/nqp) est un compilateur comme MiniPerl pour Perl 5. C’est un outil de _bootstrapping_ qui aide à compiler les parties en Raku de Rakudo) et compiler les bibliothèques avant d’avoir compilé les bibliothèques. Contrairement à MiniPerl pour Perl 5 (qui est un interpréteur sans toutes les piles : c’est‑à‑dire sans les modules mélangeant code Perl et code natif), NQP ne sait compiler qu’un « Raku simplifié ». NQP designe aussi bien le compilateur que le code source contenu dans des fichiers portant l’extension « .nqp ». Du code NQP ressemble à ça :
```perl
method symtable() {
%!symbol := nqp::hash() if nqp::isnull(%!symbol);
%!symbol
}
method evaluate_unquotes(@unquotes) {
my $result := self.shallow_clone();
my $i := 0;
my $elems := nqp::elems(@(self));
while $i < $elems {
$result[$i] := self[$i].evaluate_unquotes(@unquotes);
$i := $i + 1;
}
$result
}
```
NQP fait partie de Rakudo et semble avoir été inspiré par MiniPerl6/KindaPerl6.
## Exécution (MoarVM)
[MoarVM](
https://github.com/MoarVM/MoarVM) signifie _Metamodel On A Runtime VM_ ([site officiel](
https://www.moarvm.org/index.html)). C’est une machine virtuelle basée sur les registres comme Parrot. [Jonathan Worthington](
https://github.com/jnthn) est le fondateur et architecte de MoarVM.
Voici quelques caractéristiques de MoarVM :
- représentation interne plus proche de Raku (par rapport à Parrot) (« _On the other hand, there are features that are hard to implement efficiently if the VM doesn’t support it._ », d’après une [interview de Flavio Glock](
https://andrewshitov.com/2015/05/15/interview-with-flavio-glock/)) ;
- superbe gestion d’Unicode, avec les chaînes de caractères représentées au niveau graphème ;
- gestion de la programmation asynchrone et concurrente avec des structures de contrôles pour la programmation concurrente, les sockets synchrones, minuteurs, processus, sémaphores, files bloquantes, etc.
- ramasse‑miettes précis, générationnel (jeunes → [_semispace_](
http://www.cs.cornell.edu/courses/cs312/2003fa/lectures/sec24.htm) et vieux → gros _buckets_) et gérant la concurrence ;
- capable de gérer les continuations ;
- _[bounded serialization](
https://6guts.wordpress.com/2012/02/10/bounded-serialization-better-regexes-and-better-errors/)_, sérialiser le code des modules chargés pour plus tard et gagner du temps de démarrage en évitant de reconstruire les représentations intermédiaires de ce code ;
- _runtime loading of code_ ;
- optimisations : _tail call_ éliminations (ne pas empiler dans la pile d’appel si le retour de fonction est dans l’appel), _dispatch_, élimination de code mort, _on stack replacement_ (remplacement sur la pile de routine non optimisée par une routine optimisée), _[escape analysis](
https://en.wikipedia.org/wiki/Escape_analysis)_ (transformer des allocations de tas en allocation sur la pile ou même dans un registre) et _scalar replacement_ (élimine des allocations mémoire) ;
- JIT compilation ;
- profilage de la pile d’appel et des allocations ;
- [heap snapshotting](
https://6guts.wordpress.com/2016/03/21/a-whole-heap-of-work/) V : principalement pour analyses ultérieures (investigation et amélioration du ramasse‑miettes, par exemple).
Je conseille également la lecture de cette [introduction de MoarVM](
http://brrt-to-the-future.blogspot.com/2014/05/moarvm-as-machine.html).
### MAST
MAST signifie _MoarVM AST_ (arbre de syntaxe abstraite).
### MBC
MBC signifie _MoarVM Byte Code_. Voici à quoi ressemble MBC :
```asm
; Grab value out of Scalar
decont r4, r1
; Grab type ; de-Scalar if needed
wval r5, 1, 34
decont r3, r5
; Ensure arg is an Int
istype r6, r4, r3
assertparamcheck r6
```
## Implémentation basée sur Rakudo + MoarVM (depuis 2012)
MoarVM ne possède pas d’assembleur.

Ci‑dessous un autre schéma d’architecture tiré d’une présentation sur les optimisations Rakudo/MoarVM (2014) :

# Pugs (2005 - 2007)
À partir d’ici on commence l’archéologie, la vraie.
Dans sa courte existence, Pugs a exploré de nombreux choix d’architecture. Pugs désigne l’interpréteur, le compilateur, l’environnement d’exécution et la suite de tests. Le compilateur peut compiler en Haskell, JavaScript, Perl 5 ou PIR (pour Parrot, donc, si vous vous souvenez).

Pugs est écrit en Haskell et tombe en sommeil après 2007.
## Compilation
Voici les notions de compilations autour de l’implémentation Pugs.
### PCR
PCR signifie _Pugs Compiler Rules_. C’est une implémentation en Perl 5 du moteur d’expressions rationnelles de Raku. PCR a remplacé PGE dans Pugs.
### LREP
LREP a évolué en _Pugs::Compiler_, puis, plus tard, MiniPerl6.
### Pugs::Compiler
_Pugs::Compiler_ est un ensemble de modules Perl 5 pour compiler Raku.
### MiniPerl6
Faisait partie de Pugs mais dans un répertoire séparé. **MiniPerl6** est devenu **KindaPerl6** puis **Perlito6**.
### KindaPerl6
KindaPerl6 ou KP6 est une implémentation Raku de la grammaire en Raku avec un _bootstrap_ en Perl 5. KindaPerl6 est construit à partir de MiniPerl6.
## Exécution
### PIL
PIL signifie _Pugs Intermediate Langage_. PIL n’est pas un format lisible par les humains mais plutôt un arbre syntaxique abstrait interne à Pugs.
### PIL-Run

PIL-Run a été construit sur un ensemble de modules Perl 5 qui lisent et exécutent PIL. PIL-Run était le _back‑end_ en Perl 5 de Pugs… au début.
## Implémentations basées sur Pugs
### Pugs + back‑ends variés
« Pugs compile et exécute »

« Pugs compile pour Parrot (PIR) »

La compilation vers PIR se fait en deux temps, petit zoom dessus :

« Pugs compile (transpile ?) vers du JavaScript »

« Perl compile (transpile ?) vers du Perl 5 »

### v6
**v6-pugs** puis **v6-alpha** et à présent [v6.pm](
https://metacpan.org/pod/v6) est une réécriture complète de Pugs, utilisant un mélange de Raku (_Pugs::Compiler_ et les modules associés) et Perl 5. Il réutilise du code de l’environnement d’exécution de PIL-Run et « la moitié du CPAN ». À présent v6 est distribué dans Perlito6. v6.pm est le frontal de Perlito et Pugs en Perl 5.
### Perlito
Le projet [Perlito](
https://github.com/fglock/Perlito) est mené par [Flavio S. Glock](
https://github.com/fglock). Le projet Perlito contient en fait plusieurs compilateurs pour plusieurs langages dans plusieurs langages ciblant des _back‑ends_ variés :
- compiler du Perl 5 vers du code source Java ;
- exécuter du Perl 5 directement dans la JVM ;
- compiler du Perl 5 vers du code source JavaScript, exécute Perl 5 directement dans le navigateur ou Node.js ;
- compiler du Raku vers du code source JavaScript, exécute Perl 6 directement dans le navigateur ou Node.js ;
- compiler du Perl 5 vers Perl 5 ;
- compiler du Raku vers Perl 5 ;
- compiler du Raku vers Python 2.6 ;
- compiler du Perl 5 vers Perl 6 (en cours) ;
- compiler du Raku vers Ruby 1.9 (en cours) ;
- compiler du Raku vers Go (en cours) ;
- compiler du Raku vers Common Lisp (SBCL) (en cours).
Une chose qu’il ne sait pas faire, c’est traduire du Perl 5 en Raku.
MiniPerl6 et KindaPerl6 forment Perlito6. Perlito5 est un portage de Perlito6 en Perl 5. C’est « Perl 5 implémenté en Perl 5 ». Perlito5 lui‑même est écrit en Perl. Perlito6, quant à lui, est écrit en Raku.
Perlito implémente seulement un sous‑ensemble de Raku nommé le « sous‑ensemble utile » et qui :
- nʼa pas de contexte de liste ;
- nʼa pas d’héritage ;
- nʼa pas de paresse ;
- a des closures mais pas de coroutines ou de continuations ;
- nʼa pas de multis.
# Autres compilateurs, environnements d’exécution et machines virtuelles
Dans cette partie, nous allons continuer notre tour des initiatives autour des compilateurs, environnements d’exécution et machines virtuelles historiques.
## STD et viv
[STD et viv](
https://raku.org/compilers/std-viv) sont des œuvres de Larry Wall.
On trouve dans [STD](
https://github.com/perl6/std/blob/master/STD.pm6) la grammaire de Raku… écrite en Raku (qui n’avait pas de compilateur à l’époque ! C’est le début des problèmes de _bootstrapping_ :D).
[VIV](
https://github.com/perl6/std/blob/master/viv) ou littéralement en chiffres romains « VI → V » (et donc « 6 vers 5 ») était un module capable de convertir du Perl 6 vers du Perl 5.
## SMOP
D’abord appelé YAP6, **SMOP** signifie _Simple Meta Object Programming_.
SMOP est un compilateur et environnement d’exécution écrit en C pour Raku, mais on dit parfois SMOP pour désigner seulement l’environnement d’exécution (qui peut être ciblé par d’autres compilateurs).

SMOP n’est pas une machine virtuelle mais un environnement d’exécution qui ressemble à celui de Perl 5, tout en possédant des fonctionnalités pour gérer Raku.
## Mildew
Mildew était un compilateur STD vers SMOP

Il utilise directement la grammaire STD.
## Elf
Elf était un compilateur écrit en Raku avec une grammaire en Ruby. Il pouvait émettre du Perl 5 ou du Lisp. Il n’a jamais été complété. Il était prévu qu’Elf puisse cibler SMOP.
## Ponie
[Ponie](
http://www.poniecode.org/) signifie _Perl On a New Internal Engine_. Il s’agissait de faire tourner Perl 5 dans la machine virtuelle Parrot. Arrêté en 2006.

## Punie
[Punie](
https://en.wikipedia.org/wiki/Punie) (référence directe à Ponie) était un compilateur Perl 1 vers Parrot.
## Yapsi
[Yapsi](
https://github.com/masak/yapsi) pour _Yet Another Perl Six Implementation_ est une implémentation du compilateur et de ses environnements d’exécution et machines virtuelles Raku en Raku.

**SIC** signifie _(S??) Instruction Code_, c’est du _byte code_ propre à Yapsi.
## Niecza
[Niecza](
https://github.com/sorear/niecza) est un compilateur Raku écrit en C# qui cible CLR ([Mono](
https://wiki.winehq.org/Mono)).

Ouf ! C’était le dernier, on a fini. :)
# Conclusion
Après une longue période de gestation, le langage Raku est à présent complet et mature et a donc été publié. Raku fait preuve d’une grande expressivité et d’une grande puissance. On trouve de nombreux concepts intéressants dans Raku comme dans son histoire et celle de ses implémentations (même si la plupart font partie d’un monde disparu) qui méritaient qu’on s’y penche un peu.
J’espère que cette dépêche aura su lever le brouillard autour des méandres d’implémentations de Raku et mettre en valeur les concepts du langage.