URL: https://linuxfr.org/users/anaseto/journaux/retour-d-experience-avec-le-langage-j Title: Retour d'expérience avec le langage J Authors: anaseto Date: 2013年08月23日T11:36:37+02:00 License: CC By-SA Tags: langage, linus_torvalds et retour_d_expérience Score: 36 Bonjour Nal, je vais te parler d'un langage que je me suis mis à apprendre ce mois d'août. Son nom c'est [J](http://fr.wikipedia.org/wiki/J_(langage)) tout court. Il s'agit d'un langage spécialisé dans la manipulation de tableaux multidimensionnels à l'aide d'une notation très compacte, descendant d'[APL](http://fr.wikipedia.org/wiki/APL_(langage)). Il n'y a qu'une seule implémentation, dont la [version 701](http://www.jsoftware.com/source.htm) a été libérée sous GPLv3 en 2011, mais des licences commerciales sont aussi possibles. Il s'agit d'un langage interprété, pensé pour une utilisation intéractive exploratrice même s'il permet aussi une certaine modularité pour faire des programmes plus gros. Soyons honnêtes, au début on a parfois l'impression qu'il s'agit juste de code offusqué, ou d'un simple jeu. Pour dire, j'ai failli renoncer malgré mon habitude des notations en tant qu'étudiant mathématicien. Cependant, une fois habitué à la philosophie du langage j'ai fini par changer d'avis, d'où ce journal :) # Un petit tour avec J Maintenant je vais essayer de donner un petit avant-goût de cet étrange langage. ## Un peu d'arithmétique C'est parti : 2 + 3 5 2 4 + 1 3 3 7 `+` se généralise donc tout seul aux listes, mais aussi à un tableau de n'importe quelle dimension. Et la plupart des fonctions se généralisent de façon analogue: 2 ^ 0 1 2 3 4 1 4 8 16 Alors bon, c'est bien tout ça, mais d'autres langages comme Scilab ou Octave permettent des choses similaires. Là où J se démarque vraiment c'est dans sa grammaire exotique. Tout d'abord, l'évaluation est extrêmement simple : pas de priorité parmi les opérateurs, `+` et `*` sont logés à la même enseigne : 2 * 2 + 3 10 Il faut donc lire `2 * ( 2 + ( 3 ) )`. On peut bien sûr mettre des parenthèses pour changer le destin : (2 * 2) + 3 7 ## Du vocabulaire Et là c'est la surprise : au lieu de parler de variables ou fonctions, on parle de *noms* et de *verbes*. En fait, on rencontre des *adverbes*, des *conjonctions*, et même des *gérondifs*! Pourquoi ces noms fantaisistes? Parce qu'un programme J est composé de phrases et que ce vocabulaire donne une image assez fidèle de la réalité. ## Adverbes, conjonctions Regardons l'adverbe `/` pour se faire la main: +/ 1 2 3 NB. 1 + 2 + 3 (après NB. c'est un commentaire) 6 On l'appelle « insère », et il s'agit bien de ça, il insère le verbe qui le précède entre les éléments. Ici `1 + 2 + 3`. On peut l'appliquer à n'importe quel verbe. Prenons par exemple `<.` qui renvoie le plus petit parmi deux nombres. 3 <. 2 2 <./ 5 7 3 4 3 En gros, un adverbe est une fonction qui prend un verbe en argument et renvoie un nouveau verbe avec un nouveau comportement. Les conjonctions sont similaires mais prennent deux verbes ou noms en argument. Par exemple `@:` sert à composer deux verbes. Donc avec `>:` verbe qui incrémente de un les éléments d'un tableau, `*/ @:>:` est le verbe qui incrémente tout de un puis fait le produit des éléments. ## Verbe monadique/dyadique Jusqu'à présent, on a rencontré des cas de verbes *dyadiques*, c'est-à-dire qui prennent deux arguments. La plupart des verbes ont aussi un cas *monadique*, pour `<.` par exemple: <. 2.3 NB. partie entière : l'entier inférieur le plus proche 2 ## Comment définir ses propres verbes, noms,... Le symbole `=:` qui permet d'assigner un nom, verbe, adverbe ou conjonction. Par exemple `min =: <./` pour définir le verbe minimum, qu'on utilise simplement `min 5 7 3 4` comme n'importe quel verbe. ## Séquences de verbes (« verb trains » en anglais) En J, une succession de deux ou trois verbes ou plus à la suite a un sens particulier. Un exemple classique avec trois verbes : calcul de la moyenne d'une liste de nombres. Le verbe `#` renvoie la longueur d'un tableau, et `%` est la division (`/` est déjà pris!) : moy =: +/ % # moy 2 9 7 NB. (2 + 9 + 7) % 3 6 Où est la magie? Il s'agit d'une fourchette (*fork*) : si f, g et h sont trois verbes et y un nom, `(f g h) y` signifie `(f y) g (h y)`. Ici on doit donc lire « la somme(f) divisée(g) par la longueur(h) ». Ces séquences permettent un style de programmation dit *tacite*, où on définit des fonctions sans faire référence explicitement aux arguments. ## Le rang Une notion importante : celle du *rang* (ou dimension). Dans les cas les plus simples il s'agit de décider si une somme se fait suivant les lignes ou les colonnes, par exemple: a =: i. 3 3 NB. matrice 3x3 avec les 9 premiers entiers a 0 1 2 3 4 5 6 7 8 NB. + est « inséré » entre les lignes. +/ a 9 12 15 NB. somme suivant chaque ligne (dimension 1) NB. On utilise la conjonction " appelée « rang » +/"1 a 3 12 21 ## Aller plus loin Voilà, il reste une multitude de choses : calculs d'inverses, itérations à l'aide de la conjonction `^:`, structures de contrôles (if-then-else,... et même while !),... mais l'esprit est là, il ne reste plus qu'à se plonger dans un des guides du [wiki](http://www.jsoftware.com/jwiki/Books) :) # Quelques remarques en vrac Tout a l'air assez simple (j'espère), mais il y a un hic quand on apprend J : il y a plus d'une centaine de [primitives](http://www.jsoftware.com/docs/help701/dictionary/vocabul.htm) (verbes, adverbes, conjonctions), qui s'écrivent à l'aide d'une seule lettre ou symbole, suivie parfois d'un ou deux `.` ou `:`, et même si souvent c'est mnémotechnique, pas toujours, et il m'a fallu un paquet d'heures pour les digérer avant de pouvoir comprendre le code des autres. Le pire c'est les fonctions pour intéragir avec le monde extérieur, qui s'obtiennent toutes grâce à la conjonction `!:`, par exemple `1!:1` est un verbe pour lire un fichier, aucun moyen de s'en souvenir, même si heureusement pas mal d'alias plus verbeux sont prédéfinis pour les tâches courantes. Malgré les difficultés, c'est un langage sympathique, et la possibilité d'exprimer des algorithmes assez complexes, demandant dans un langage plus traditionnel plusieurs boucles, en une seule ligne, c'est quand même pratique. Bien sûr, il faut être capable de se relire après, et je n'y croyait qu'à moitié au début, mais c'est tout à fait possible en fait avec de l'entraînement. Un autre avantage est que toutes les opérations sur les tableaux sont très optimisées, donc on se retrouve avec du code très rapide à la fin, du moment qu'on applique les fonctions sur un maximum de données à la fois (pas de problèmes pour effectuer des opérations sur des tableaux avec des millions de valeurs). La documentation du langage est assez particulière, puisqu'il s'agit d'un [«dictionnaire»](http://www.jsoftware.com/docs/help701/dictionary/contents.htm), et le [wiki officiel](http://www.jsoftware.com/jwiki/FrontPage) collectionne assez d'articles intéressants, et guides variés. Une remarque concernant la licence : la version 701 de J est GPLv3, mais les binaires distribués sur le site officiel par contre viennent avec quelques autres trucs non libres (un IDE, des docs et des broutilles), donc il faut compiler soi-même. Sous Gentoo il y a un ebuild, mais j'ai pas l'impression qu'il y ait de package Debian, sans doute parce que le makefile n'est pas terrible, d'ailleurs l'ebuild Gentoo doit placer ça dans /opt/. Il y a aussi un petit problème mineur : le binaire s'appelle par défaut jconsole donc petit conflit de noms avec java. La compilation est assez facile, il y a juste readline qui n'est pas activé par défaut : le plus simple c'est d'utiliser [rlwrap](http://utopia.knoware.nl/~hlub/uck/rlwrap/). Enfin, une petite mise en garde : apprendre J peut avoir des conséquences surprenantes, comme en témoigne ce petit extrait du fichier `vt.c` du code source C de l'interpréteur définissant le cas monadique du verbe `{.` qui renvoie le premier élément d'un tableau : ```C F1(jthead){I wcr,wf,wr; RZ(w); wr=AR(w); wcr=jt->rank?jt->rank[1]:wr; wf=wr-wcr; R !wcr||*(wf+AS(w))? from(num[ 0],w) : SPARSE&AT(w)?irs2(num[0],take(num[ 1],w),0L,0L,wcr,jtfrom):rsh0(w); } ``` C'est du C ça!? De quoi faire frémir Linus Torvalds ;)

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