- Piet est un langage de programmation ésotérique conçu pour que le code ressemble à de l’art abstrait ; il doit son nom à Piet Mondrian, pionnier de l’abstraction géométrique
- Un programme est une image composée de 20 couleurs reconnues, et l’exécuteur se déplace entre des blocs de couleur en interprétant les variations de couleur comme des commandes
- Toutes les données n’existent que sous forme d’entiers et sont stockées sur une pile ; la taille d’un bloc de couleur représente une valeur, mais celle-ci n’est pas automatiquement placée sur la pile sans commande
push - Le contrôle de flux est déterminé par le Direction Pointer, le Codel Chooser, ainsi que par les règles des blocs noirs, des bords et des blocs blancs ; certains comportements peuvent varier selon les implémentations
- Il existe des exemples et un écosystème d’outils externes, mais pas d’interpréteur officiel faisant autorité ; la gestion des erreurs et l’interprétation des couleurs non standard restent dépendantes de l’implémentation
L’idée de base de Piet
- Piet est un langage de programmation dont le code ressemble à de l’art abstrait
- Son nom vient de Piet Mondrian, pionnier de l’abstraction géométrique
- Le nom
Mondrianaurait été souhaité, mais comme un langage de script portait déjà ce nom, le nom Piet a été utilisé - Depuis la rédaction de la spécification, une petite communauté s’est formée et a créé des programmes, des interpréteurs, des IDE et des compilateurs
- Il n’existe pas d’interpréteur officiel faisant autorité, et les implémentations disponibles peuvent interpréter la spécification de façon légèrement différente
- Certaines explications de la spécification ont été ajoutées, mais il est possible que certaines implémentations existantes ne les suivent pas
Couleurs et unités de code
- Piet utilise au total 20 couleurs
- 18 couleurs font partie du cycle des teintes et du cycle de luminosité
- Le blanc et le noir ne font partie d’aucun de ces deux cycles
- Le cycle des teintes suit l’ordre
red -> yellow -> green -> cyan -> blue -> magenta -> red - Le cycle de luminosité suit l’ordre
light -> normal -> dark -> lightlightest aussi considéré comme un cran plus sombre quedark, et l’inverse est également vrai
- Des couleurs non standard, comme l’orange ou le marron, peuvent être utilisées, mais leur effet dépend de l’implémentation
- Dans le cas le plus simple, les couleurs non standard sont traitées comme du blanc
- Une autre possibilité est qu’elles soient traitées comme du noir
Codels et blocs de couleur
- Le code Piet est une image composée de couleurs reconnaissables
- Comme chaque pixel de code a une signification au niveau du langage, dans les programmes agrandis pour être plus lisibles, un pixel unique du code est appelé codel
- L’unité d’exécution de base est le bloc de couleur
- Un bloc de couleur est une zone de codels de même couleur reliés horizontalement ou verticalement
- Des blocs qui ne se touchent qu’en diagonale ne sont pas considérés comme reliés
- Un bloc de couleur peut avoir n’importe quelle forme et contenir des trous d’une autre couleur
- Les trous internes ne font pas partie de ce bloc
Pile et représentation des valeurs
- Piet stocke toutes les valeurs de données sur une pile
- Les valeurs de données sont uniquement des entiers
- Selon les commandes, elles peuvent être saisies ou affichées comme valeurs de caractères Unicode
- Conceptuellement, la pile a une profondeur infinie, mais une implémentation peut définir une taille maximale finie
- Sur une pile finie, un dépassement de capacité est une erreur d’exécution, dont le traitement dépend de l’implémentation
- Un bloc de couleur qui n’est ni noir ni blanc représente une valeur entière égale au nombre de codels qu’il contient
- Les entiers non positifs ne peuvent pas être représentés directement
- Ils peuvent toutefois être créés au moyen d’opérateurs
- La valeur d’un bloc de couleur n’est pas automatiquement poussée sur la pile ; une commande explicite
pushest nécessaire
- La taille des entiers est également conceptuellement infinie, mais une implémentation peut définir une taille maximale finie
- Un dépassement d’entier est une erreur d’exécution, dont le traitement dépend de l’implémentation
Flux d’exécution
- L’interpréteur commence l’exécution dans le bloc de couleur contenant le codel situé en haut à gauche du programme
- Pendant l’exécution, deux états sont maintenus
- Direction Pointer (DP) : il pointe initialement vers la droite et peut pointer vers la droite, la gauche, le bas ou le haut
- Codel Chooser (CC) : il pointe initialement vers la gauche et peut pointer vers la gauche ou la droite
- La prochaine destination est déterminée par la bordure du bloc de couleur courant et par la combinaison DP/CC
- On cherche le bord du bloc de couleur courant le plus éloigné dans la direction du DP
- Sur ce bord, on choisit le codel le plus éloigné dans la direction du CC, relativement à la direction de progression du DP
- Depuis ce codel, on se déplace vers le bloc de couleur auquel appartient le codel immédiatement suivant dans la direction du DP
- Ce processus se répète jusqu’à ce qu’une condition de terminaison soit atteinte, auquel cas le programme se termine
Blocs noirs, bords et blocs blancs
- Les blocs de couleur noirs et les bords du programme agissent comme des barrières qui bloquent le flux d’exécution
- Si l’interpréteur tente de se déplacer vers un bloc noir ou hors des bords, il s’arrête et inverse le CC
- Si la deuxième tentative échoue également, il fait tourner le DP d’un cran dans le sens horaire
- Après avoir alterné changements de CC et de DP pour un total de 8 tentatives, si le bloc de couleur courant ne peut toujours pas être quitté, le programme se termine
-
Déplacement dans les blocs blancs
- Les blocs de couleur blancs sont des zones libres que l’interpréteur traverse sans obstruction
- Lorsqu’il passe d’un bloc de couleur à une zone blanche, l’interpréteur se déplace en ligne droite dans la direction du DP jusqu’à atteindre un bloc de couleur non blanc
- Aucune commande n’est exécutée lors du passage à une nouvelle couleur à travers un bloc blanc
- Grâce à cette propriété, les blocs blancs permettent de changer la couleur courante sans exécuter de commande, ce qui est utile pour écrire des boucles
- Le déplacement dans un bloc blanc n’utilise pas la procédure de choix de sortie d’un bloc de couleur non blanc et n’effectue qu’un déplacement en ligne droite
-
Lorsqu’on est bloqué dans un bloc blanc
- Si, en traversant un bloc blanc en ligne droite, l’interpréteur rencontre un bloc noir ou un bord, cela est traité comme une contrainte
- Dans ce cas, le CC est inversé, mais comme la position visée ne change pas, le DP est immédiatement tourné d’un cran dans le sens horaire
- Ensuite, depuis le codel blanc courant, le déplacement en ligne droite reprend dans la nouvelle direction du DP
- Chaque fois qu’une contrainte est rencontrée dans un bloc blanc, l’inversion du CC et la rotation du DP se répètent
- Si un bloc de couleur est atteint, l’exécution continue ; si le chemin commence à se rebrousser à l’intérieur du bloc blanc, il n’existe aucune sortie et l’exécution se termine
Système de commandes
- Les commandes de Piet sont déterminées par la variation de couleur lors du passage d’un bloc de couleur au suivant
- La commande est définie par le nombre d’étapes parcourues dans le cycle des teintes et dans le cycle de luminosité
- Aucune commande n’est exécutée lors d’une transition de couleur effectuée via un bloc blanc
-
Commandes de pile et arithmétiques
push: place sur la pile la valeur du bloc de couleur qui vient d’être quittépop: retire et jette la valeur au sommet de la pileadd: additionne les deux valeurs du sommet et replace le résultat sur la pilesubtract: soustrait la valeur du sommet de la deuxième valeur et place le résultat sur la pilemultiply: multiplie les deux valeurs du sommetdivide: effectue une division entière de la deuxième valeur par la valeur du sommet- La division par zéro est une erreur dépendante de l’implémentation ; il est recommandé d’ignorer la commande
mod: place sur la pile le reste de la division de la deuxième valeur par la valeur du sommet- Le résultat a le même signe que le diviseur, c’est-à-dire la valeur au sommet de la pile
- Si la valeur au sommet est 0, il s’agit d’une erreur de division par zéro ; il est recommandé d’ignorer la commande
- Pour un dividende négatif,
modest identique à la division euclidienne arrondie vers le bas décrite dans l’article Wikipedia sur l’opération modulo
-
Commandes de comparaison, de pointeurs et d’entrée/sortie
not: remplace la valeur au sommet de la pile par 0 si elle n’est pas 0, ou par 1 si elle vaut 0greater: place 1 sur la pile si la deuxième valeur est supérieure à la valeur du sommet, sinon 0pointer: retire la valeur au sommet de la pile et fait tourner le DP dans le sens horaire autant de fois- Si elle est négative, la rotation se fait dans le sens antihoraire
switch: retire la valeur au sommet de la pile et inverse le CC autant de fois- Si elle est négative, il est inversé autant de fois que sa valeur absolue
duplicate: place une copie de la valeur au sommet de la pile sur la pileroll: retire les deux valeurs du sommet et fait tourner une partie restante de la pile selon une profondeur et un nombre de rotations donnés- Si la profondeur est négative, il s’agit d’une erreur et la commande est ignorée
- Un
rollqui dépasse la profondeur maximale de pile dépendante de l’implémentation est une erreur dépendante de l’implémentation ; il est recommandé d’ignorer la commande in: lit un nombre ou un caractère depuis STDIN et le place sur la pile- S’il n’y a pas d’entrée, ou si une entrée entière ne fournit pas d’entier, il s’agit d’une erreur et la commande est ignorée
out: affiche sur STDOUT la valeur au sommet de la pile sous forme de nombre ou de caractère- Les opérations qui ne peuvent pas être exécutées faute de valeurs suffisantes sur la pile sont ignorées, puis l’exécution passe à la commande suivante
Exemples et outils
- Des exemples Piet sont disponibles dans Sample programs
- Des interpréteurs et outils de développement externes sont recensés dans Third-party Piet interpreters and development tools
1 commentaires
Avis sur Hacker News
Le dernier programme de la page d’exemples est vraiment étonnant : une personne nommée Piet aurait vu une œuvre d’art qui lui faisait penser au langage Piet et l’aurait exécutée.
Elle s’est exécutée, et il s’agit peut-être du premier cas de l’histoire où un artiste graphique a peint par hasard un programme informatique fonctionnel.
https://www.dangermouse.net/esoteric/piet/samples.html
https://gitlab.fabcity.hamburg/hofalab/piet-get-together
https://www.mcmillen.dev/sigbovik/
Piet a pris l’œuvre en photo, l’a convertie en un fichier image réorganisé avec des couleurs proches de la palette Piet, puis l’a exécutée : elle s’est effectivement lancée, et le code était une boucle infinie qui lisait des caractères ASCII et affichait leur valeur numérique ASCII.
C’est vraiment difficile à croire.
L’explication selon laquelle « bien sûr, avec un programme plus grand, on peut obtenir une valeur plus précise » m’a paru être un type de blague que je n’avais encore jamais vu.
Selon la spécification, l’interpréteur doit commencer à glisser depuis le codel blanc courant dans la nouvelle direction du DP, et continuer jusqu’à entrer dans un bloc de couleur ou rencontrer une autre limite.
Mais l’interpréteur npiet regarde dans l’espace blanc, puis revient à la position du dernier codel coloré. J’aimerais un jour ajouter ce comportement en option au lexer de mon compilateur Piet, mais je ne m’y suis pas encore attaqué.
En suivant la spécification, ce programme devient une simple boucle non terminante, car les coins extrêmes de presque tous les blocs sont adjacents au blanc. Écrire des programmes Piet complexes ciblant plusieurs interpréteurs et compilateurs est assez difficile, chacun ayant de subtiles différences d’interprétation non documentées.
Je pense que la sortie de mon backend Piet dépend généralement moins de l’interpréteur, mais je n’ai examiné en détail que trois ou quatre autres interpréteurs.
https://github.com/boothby/repiet/
En parcourant la documentation, à cause de la règle selon laquelle « les opérations impossibles à effectuer, comme une opération de dépilement quand la pile ne contient pas assez de valeurs, sont simplement ignorées et l’exécution continue avec l’instruction suivante », il me semble possible que toutes ces images s’exécutent sans erreur.
Reste à savoir combien de ces images aléatoires font réellement quelque chose de « significatif ».
Piet est une expérience marquante parmi les langages de programmation ésotériques, mais à mon avis il n’atteint pas vraiment son objectif de faire ressembler les programmes à des tableaux de Mondrian, sauf si le développeur le cherche vraiment.
J’aurais aimé que la structure même du langage soit conçue de sorte que, quoi que l’on « écrive », cela ressemble à un tableau de Mondrian.
Ce genre de question me revient sans cesse : à quoi ressemble un algorithme ?
Peut-on créer dans le monde réel quelque chose qui ressemble à ce qu’on trouve dans le roman de Herman Hesse The Glass Bead Game ? Le titre original est Magister Ludi
En tant que personne très visuelle, j’ai envie de croire que c’est possible, et j’ai même déjà utilisé de tels outils
https://community.carbide3d.com/uploads/default/original/3X/5/b/5b0872a5666fec9b7bb6fd623c431de03263372d.jpeg
Mais sans réponse claire à la question précédente, ces outils risquent toujours de finir comme ceci
https://blueprintsfromhell.tumblr.com/
https://scriptsofanotherdimension.tumblr.com/
Il est aussi difficile de trouver l’équilibre entre expressivité visuelle et modularité ; et si l’on pousse trop la modularité, on retombe trop facilement sur la barrière du texte que l’on voulait éviter
Sergei Lewis et moi avons chacun créé des outils qui génèrent du code Piet. L’assembleur de Sergei produit un code bien plus agréable à regarder que mon backend Piet
Ce qu’on voit vraiment dans la sortie de mon compilateur, c’est surtout que j’ai utilisé un trampoline de manière très paresseuse
http://www.toothycat.net/wiki/wiki.pl?MoonShadow/Piet
https://github.com/boothby/repiet/
https://en.wikipedia.org/wiki/Trampoline_(computing)
C’est une idée qui m’est venue en lisant un livre de Steven Pinker : les mots abstraits peuvent être décomposés en termes plus simples et finissent par décrire une relation spatiale. Par exemple, « rekindle » peut être vu comme « ramener deux choses ensemble »
De même, une boucle for est le concept mental d’« une chose qui passe au-dessus de plusieurs autres », ce qui a une représentation visuelle comme « 100 » -> « 010 » -> « 001 »
Je me demande donc s’il serait possible de créer un langage qui définisse ces briques comme de pures transformations visuelles
Ce genre de chose aurait sa place dans un thriller criminel, où cela bloquerait le protagoniste ou les enquêteurs jusqu’à ce que quelqu’un réalise que c’est du code
Moi qui pensais que seuls les QR codes étaient utiles
Quelqu’un a créé un quine en Piet : http://mamememo.blogspot.com/2009/10/piet-quine.html?m=1
L’image de l’article est cassée, mais une copie se trouve ici : https://codegolf.stackexchange.com/a/23255/103045
Découvrir Piet est un moment particulier, mêlé d’émerveillement, de confusion et de surprise
Dans mon cas, c’est capturé dans cette conversation de « The CS Primer Show », un podcast d’informatique avec mon ami Oz : https://show.csprimer.com/episodes/e2-dont-let-a-gpt-have-all-the-fun
À l’université, il y avait un petit cours sur les langages de programmation ésotériques
Chacun devait choisir un langage comme Brainfuck ou Piet et jouer avec ; j’ai choisi Piet et je me suis bien amusé
Honnêtement, la petite appli d’exemple que j’ai faite n’était pas très réussie esthétiquement, et j’ai l’impression qu’il faut devenir expert de Piet pour faire de l’art avec
La page d’exemples est excellente
On peut voir le canevas évoluer progressivement vers quelque chose de plus sophistiqué et plus agréable à regarder
https://www.dangermouse.net/esoteric/piet/samples.html
« light est considéré comme un cran plus sombre que dark », c’est assez profond
Ce serait chouette de pouvoir créer un autoencodeur qui apprend à prendre du code Python, ou d’un autre langage moins ésotérique, et à produire du Piet
On pourrait alors peut-être générer des algorithmes aléatoires, un peu comme avec Stable Diffusion