1 points par GN⁺ 2023-08-09 | 1 commentaires | Partager sur WhatsApp
  • Raku a été envisagé comme candidat au titre de langage-calculatrice pour combler les lacunes de Python, J, Frink et Excel dans les tâches mathématiques, et même après une courte expérimentation, il donne l’impression d’être un langage très puissant mais étrange
  • Son expressivité centrée sur les opérateurs est vaste, avec des symboles Unicode, des opérateurs infix alphanumériques, le produit de listes, le zip, le reduce, l’accumulation, le matcher ~~ et les séquences ...
  • L’utilisateur peut définir non seulement des opérateurs infix, mais aussi des opérateurs circumfix/postcircumfix, et spécifier leur associativité au-delà du simple gauche/droite, jusqu’aux associations en chaîne ou en liste
  • Le multiple dispatch ne se limite pas aux signatures de type : il peut aussi bifurquer selon des prédicats d’exécution where, et les signatures de fonctions comme leurs paramètres sont traités comme des valeurs de premier ordre
  • Cela semble lourd à maintenir dans une grande base de code, mais reste séduisant pour de la programmation à petite échelle comme les scripts jetables, les calculs ou les outils personnels ; la documentation, le REPL Windows, la vitesse de compilation et les erreurs de sigils sont les principaux freins

Pourquoi regarder Raku, et première impression

  • Raku est le langage autrefois connu sous le nom de Perl 6
  • Après avoir écrit sur mes frustrations envers les langages dynamiques, plusieurs personnes m’ont recommandé Raku, et je l’ai examiné pour voir s’il convenait comme langage-calculatrice pour des tâches mathématiques
  • Jusqu’ici, j’utilisais un mélange de Python, J, Frink et Excel, mais chacun avait de gros défauts
  • Après quelques jours d’expérimentation, mon impression se rapprochait de ceci : « un langage conçu par des gremlins vraiment brillants, ayant beaucoup intégré les retours d’autres gremlins »

Un système d’opérateurs inhabituel

  • Raku utilise activement des opérateurs Unicode
    • l’appartenance à un ensemble se vérifie avec
    • il existe aussi , et
  • Il autorise aussi les opérateurs infix alphanumériques
    • l’opérateur de répétition de chaîne est x
    • la composition de fonctions est o
  • Les combinaisons de listes s’expriment également avec une notation courte
    • X produit le produit cartésien de listes
    • Xf applique f à chaque élément du produit cartésien
    • Zf fait la même chose en mode zip
  • Pour un opérateur infix f, [f] réduit une liste et [\\f] produit les résultats cumulés
    • [+] <1 2 3 4 5> vaut 15
    • [\\+] <1 2 3 4 5> vaut (1 3 6 10 15)

Le matcher ~~ et les séquences ...

  • ~~ sert de matcher unifié pour plusieurs types de comparaison
    • "abc" ~~ "abc" vérifie l’égalité de chaînes
    • "abc" ~~ Str vérifie qu’il s’agit du type chaîne
    • "abc" ~~ {.chars == 3} vérifie que la longueur est de 3
    • "abc" ~~ /^b/ vérifie si abc commence par b
  • ... construit des séquences en déduisant un motif à partir des valeurs précédentes
    • 0,1,2...10 augmente de 1 de 0 à 10
    • 0,2,4...10 produit une séquence de nombres pairs
    • 1,2,4...10 suit un motif de croissance comme 1 2 4 8

Opérateurs définis par l’utilisateur

  • Raku ne se contente pas, comme certains langages, de laisser définir des opérateurs infix : il permet aussi de créer des opérateurs circumfix et postcircumfix
  • Par exemple, sub circumfix:<[∀ zz>($inner){sum($inner)} permet de définir un opérateur englobant qui additionne les valeurs internes
  • Il est également possible de définir un opérateur postcircumfix qui ressemble à un produit scalaire de vecteurs
    • sub postcircumfix:<| ⟩>(@left, @inside){[+] (@left Z* @inside)}
    • <1 2 3>|<4 5 6>⟩ vaut 32
  • L’associativité des opérateurs peut aussi être configurée de nombreuses façons
    • on peut définir des opérateurs infix classiques associatifs à gauche ou à droite
    • on peut spécifier une association en chaînex < y < z est interprété comme x < y && y < z
    • une association en liste est aussi prise en charge, où a op b op c devient op(a, b, c)

Multiple dispatch et branchement sur conditions d’exécution

  • Raku prend en charge le multiple dispatch, qui choisit parmi plusieurs définitions d’une fonction selon leurs signatures de types
  • Dans l’exemple de la fonction f, le comportement change selon la combinaison des arguments
    • avec un scalaire et un tableau, elle ajoute le scalaire à chaque élément du tableau
    • le cas tableau puis scalaire est également pris en charge
    • avec deux tableaux, elle additionne les éléments correspondants avec Z+
  • Plus inhabituel encore, le dispatch peut aussi se faire à partir de prédicats évalués à l’exécution
    • multi my_abs(Int $x where {$x > 0}) {$x}
    • multi my_abs(Int $x) {-$x}
  • Les signatures de fonctions sont des valeurs de premier ordre, et les paramètres qu’elles contiennent le sont aussi

Une large surface créée par une foule de petites fonctionnalités

  • Si l’on définit une fonction MAIN, ses paramètres sont automatiquement transformés en flags CLI
  • Les objets disposent d’un très grand nombre de méthodes fournies d’avance
    • List object fournit des méthodes pour obtenir toutes les permutations, toutes les k-combinaisons et toutes les fenêtres glissantes
  • Les Junctions sont une forme de valeur inhabituelle permettant d’effectuer plusieurs comparaisons à la fois
    • 1|2 s’étend en any(1, 2), ce qui fait que 1 < 1|2 est vrai
    • 1&2 s’étend en all(1, 2), ce qui fait que 1 !< 1&2 est vrai
  • N’importe quel opérateur infix peut être précédé de ! pour devenir un opérateur de négation
  • Raku semble être un langage qui possède à la fois des noms comme $kebab-case et une soustraction infix, vraisemblablement parce que les sigils permettent de distinguer x-y
  • La syntaxe des regex n’est pas rétrocompatible avec Perl 5
    • alors que les langages ont suivi pendant 30 ans le « standard » PCRE, Perl 6 a choisi de l’abandonner

Domaines encore inexplorés et attrait à petite échelle

  • Ce qui a été examiné ici ne représente qu’une partie des fonctionnalités, surtout du point de vue de l’usage calculatrice
  • Le système objet, les packages et les grammaires n’ont pas encore été étudiés
  • Il manque aussi beaucoup d’éléments, comme samewith, qui permet apparemment de réappeler la même fonction avec de nouveaux arguments depuis son corps
  • Si je devais maintenir une base de code legacy en Raku, cela me semblerait très difficile, mais pour la programmation In The Small, le langage paraît puissant
    • scripts jetables
    • calculs
    • outils personnels
    • le type de tâches que je cherchais au départ

Frustrations et attentes

  • La documentation est très insuffisante, et la forte dépendance aux symboles rend la recherche difficile
    • même avec de l’expérience dans l’apprentissage de langages mal documentés, Raku est bien plus vaste et complexe, ce qui peut faire tomber la motivation
  • Sous Windows, saisir de l’Unicode dans le REPL provoque un crash
  • Le compilateur est aussi assez lent : même un petit fichier demande plus de 0,5 seconde, ce qui rend les itérations pénibles
  • Le système de sigils est peu pratique
    • il y a eu un cas où 30 minutes ont été perdues à déboguer un problème causé par l’usage de $x au lieu de @x
  • Globalement, j’aime bien Raku et j’espère qu’il réussira, mais j’espère aussi qu’avec le temps, les temps de compilation et la documentation s’amélioreront

1 commentaires

 
GN⁺ 2023-08-09
Avis sur Hacker News
  • Si l’on plaçait les langages de programmation dans un espace à deux dimensions, les axes pourraient être à quel point ils surprennent et, quand ils surprennent, si c’est agréable ou horrible.
    On s’attend implicitement à ce qu’un langage normal se situe plutôt en bas à gauche, « surprend peu, mais quand il surprend parfois, c’est agréable ». Raku donne l’impression de viser ouvertement le quadrant supérieur gauche, rarement occupé : une attitude du genre « c’est bizarre, non ? Ce n’est pas génial ? »

    • Le problème, c’est que ces axes sont subjectifs. Une chose peut être à la fois agréable et horrible : j’ai déjà écrit du JavaScript du genre document.write = function ..., et c’était agréable parce que ça faisait ce qu’il fallait, mais en même temps assez horrible.
    • Quand j’ai dû écrire un parseur pour un devoir à l’université, j’ai découvert la fonctionnalité grammar de Raku ; elle faisait presque tout à ma place, comme un code de triche, mais c’était quand même amusant.
    • À l’origine, c’était Perl 6, donc il n’est pas surprenant que les développeurs Perl aient voulu un langage qui ne ressemble à aucun autre.
      Perl avait aussi beaucoup de « surprises agréables », et je vois surtout Raku comme une conception visant à éliminer les surprises horribles de Perl.
    • Le passage où l’on vérifie l’appartenance à un ensemble avec me fait comprendre l’idée.
      0,2,4...10 donne (0 2 4 6 8 10), mais quand 1,2,4...10 donne (1 2 4 8), on se demande : « il va chercher le terme suivant dans l’OEIS ? »
    • Plus les paragraphes avançaient, plus Raku semblait se déplacer vers le quadrant supérieur droit, c’est-à-dire la zone surprenante et horrible.
  • Raku est intéressant comme langage, mais certains idiomes ne me rentrent pas bien dans la tête.
    Un peu comme AppleScript, qui essayait de ressembler au langage naturel et finissait par paraître étrange, Raku mélange des éléments à allure de langage naturel comme my, say, sub, gather, des symboles comme @, des déclarations de modules, et d’autres choix syntaxiques qui paraissent byzantins à un regard extérieur. Même l’exemple 99 bottles se suit logiquement, mais il est difficile à découvrir intuitivement. Il y a beaucoup de symboles, surchargés selon le contexte, au point que même pour des tâches où Raku pourrait être optimal, comme un parseur de langage naturel, je n’aurais pas envie de l’utiliser directement.
    https://examples.raku.org/categories/module-management/Fletc...

    • On dirait que tu n’as pas fait de Perl. Avec un bagage Perl, une bonne partie de cette syntaxe, surtout le sigil @ pour les tableaux, paraît assez familière.
    • Je ressens exactement la même chose en regardant Bash.
  • Ma fonctionnalité préférée dans Raku, c’est que la division entière comme les littéraux décimaux renvoient tous deux Rat, un type rationnel.
    Tout le monde sait que les nombres à virgule flottante ne sont pas terribles, mais peu de langages essaient vraiment de s’en éloigner ; avec Raku, il faut utiliser la notation scientifique pour obtenir un littéral flottant.

    • Des langages plus anciens comme Common Lisp et Scheme attendent eux aussi que les gens qui n’aiment pas les flottants IEEE 754 les remarquent.
      Ils disposent d’une hiérarchie numérique qui inclut les rationnels et même les rationnels complexes, et prennent évidemment en charge les nombres à précision arbitraire. La composabilité est excellente.
    • En réalité, c’est plutôt une mauvaise fonctionnalité. Si la représentation Rat devient trop grande, elle est automatiquement convertie en virgule flottante.
      1/10 est un Rat, mais 1/100000000000000000000 devient un Num. Il existe aussi FatRat, qui n’est pas promu, mais ce n’est pas le comportement par défaut.
    • La hiérarchie numérique de Scheme gère correctement les représentations exactes depuis des décennies.
      Il vaut donc mieux dire qu’elle n’a jamais été dans une situation où elle « s’est éloignée d’une façon d’utiliser des flottants inexacts sans qu’on les ait explicitement demandés ».
    • Racket dirait aussi les choses autrement. Ça fonctionne correctement.
      (/ 1.0 3.0) donne 0.3333333333333333, (/ 1 3) donne 1/3, et (- (+ 0.1 0.2) 0.3) donne 5.551115123125783e-17.
    • Je ne suis pas certain que ce soit une bonne chose. Je sais quand il faut utiliser des types décimaux/rationnels ou des flottants, mais dans mon code Python personnel, j’appelle bien plus souvent float() que Decimal().
      Sauf quand on manipule directement de l’argent, les flottants sont presque toujours le choix souhaité.
  • Je n’ai pas trouvé la documentation de Raku « vraiment épouvantable » ; au contraire, le site officiel m’a impressionné comme ressource tout-en-un regroupant à la fois la documentation conceptuelle et la documentation d’API.
    https://docs.raku.org/
    Comme point de départ pour la documentation conceptuelle, cette page est excellente : https://docs.raku.org/language

    • J’utilise Raku depuis quelques années, et la documentation est à la fois excellente et insuffisante.
      La plupart de ce qui existe est bien écrit et contient des exemples de code utiles, mais il m’arrive de tomber sur des parties pas du tout documentées ou ne couvrant que des cas simples. Le système de modules a été le plus problématique : la distinction modules/packages est difficile à comprendre en lisant seulement la page Modules. Les espaces de noms importés et les espaces de noms déclarés peuvent être différents, mais pour que le compilateur les trouve, la structure de répertoires doit correspondre à l’espace de noms ; c’est utile et étrangement logique, mais j’ai dû l’apprendre en expérimentant.
    • C’est à cause de la culture Perl. La FAQ et les pages de manuel de Perl étaient de tout premier ordre grâce à la personnalité des programmeurs qui utilisaient Perl : spirituelles, concises et bizarres.
    • Les pages de manuel de Perl ont toujours été excellentes.
  • Les superbes opérateurs Unicode de Raku ont tous une notation de substitution ASCII.
    Par exemple, les substituts de , , , sont (elem), !(elem), (cont), !(cont).
    https://docs.raku.org/language/unicode_ascii#Other_acceptabl...

    • Moi, j’utiliserais clairement la version ASCII.
  • On dirait que les critiques typiques formulées avant même de bien connaître le langage se répètent encore. Avant, c’était le « bruit de ligne » de Perl ; maintenant, c’est que Raku utilise sans complexe des opérateurs Unicode
    Mais c’est optionnel, et j’ai essayé de les utiliser directement pour rendre le code plus compact et expressif à l’écran. Ça se prête bien à une utilisation réfléchie et créative d’Unicode. La réaction de rejet envers les sigils est aussi courante, mais j’aimais l’expressivité de Perl, ce côté couteau suisse à moteur, et c’est pour ça que j’ai utilisé Raku/Perl 6 ; Raku donne l’impression d’être Perl élevé au carré, dans ce qui fait Perl. C’est mieux structuré, très expressif, et un énorme tas de fonctionnalités a été empilé sur le bon vieux Perl. La documentation est bonne aussi, même si elle doit continuer à être entretenue, et la comparaison avec la doc de Perl place la barre très haut

    • Je me demande comment on saisit les opérateurs non ASCII. Je ne sais pas si c’est une disposition de clavier spéciale, si l’éditeur convertit automatiquement certaines séquences, ou si l’on utilise des échappements Unicode bruts
      Faire ça pour économiser quelques caractères me paraît compliqué et pas très utile
  • Je me suis parfois demandé à quoi ressemblerait un langage de programmation rempli de sucre syntaxique, maintenant je le sais
    C’est du genre « c’est horrible, mais étrangement attirant, impossible de détourner le regard, montrez-m’en encore »

    • Tu pourrais aimer noulith, un langage hobby créé par quelqu’un qui a remporté plusieurs éditions récentes de Advent of Code
      La présentation GitHub dit : « slaps roof of [programming language]* this bad boy can fit so much [syntax sugar] into it. » Il a aussi gagné le plus récent Advent of Code en utilisant ce langage : https://github.com/betaveros/noulith
    • Attends de découvrir les Grammars de Raku
    • J’ai la même réaction chaque fois que je regarde du C++ moderne
  • Il vaut la peine de rappeler que Raku a commencé comme Perl 6, et qu’une grande partie de sa philosophie de conception vient de la façon de penser de Perl
    À voir la réaction immédiate de l’auteur à l’opérateur x pour répéter des chaînes, on dirait qu’il ne connaît pas bien l’histoire de Perl et de Raku, alors que Perl fait ça depuis des décennies

    • Dans l’article, il y a une phrase disant que « la syntaxe des expressions régulières n’est pas rétrocompatible avec Perl 5. Pendant 30 ans, les langages ont suivi le “standard” PCRE, et Perl 6 a simplement tout jeté », donc il semble au moins en savoir quelque chose
    • La première note indique que Raku était autrefois connu sous le nom de Perl 6
    • L’idée que « Perl6/Raku est totalement différent de Perl 5 » est une exagération beaucoup trop amplifiée
      Ce n’est pas pour rien qu’il s’appelait Perl 6, et il a été développé par à peu près la même équipe Perl. Pour quelqu’un qui a pas mal utilisé Perl 5, l’héritage de Perl6/Raku est évident. Même tout le modèle objet de Raku ressemble beaucoup à une version un peu plus puissante de Moose.pm, un module Perl 5 de CPAN
  • Franchement, la syntaxe des regex Perl 5/PCRE est horrible
    La seule raison pour laquelle elle existe, c’est que (? était une erreur de syntaxe dans l’ancienne syntaxe des regex, donc on pouvait le redéfinir pour n’importe quoi. Raku est une tentative de concevoir dès le départ un langage de regex sensé, maintenant qu’on sait ce que les expressions régulières doivent exprimer. L’alternative, c’est de rester coincé pendant 30 ans de plus avec des choses comme (?:this|(?>or that))

    • Plutôt qu’horrible, c’est de la magie noire indéchiffrable, et une fois qu’on la comprend, c’est génial
      Ça fait longtemps que je n’ai pas touché à Perl, mais j’utilise encore souvent les regex
    • D’accord, mais c’est vraiment utile
  • Dans un certain sens, c’est clairement un gremlin. J’aime les outils bizarres et complexes qui augmentent la productivité
    En revanche, je ne suis pas d’accord avec la comparaison « grands programmes vs petits programmes ». Quelqu’un de moins avisé pourrait comprendre que c’est un mauvais langage pour les gros travaux, alors qu’en réalité il peut être aussi bon, voire meilleur, que d’autres langages. Le problème, comme avec les autres langages gremlins, c’est qu’il faut de la sagesse pour bien s’en servir. Par exemple, les gens qui confondent $x et @x sont rares parmi ceux qui ont suffisamment utilisé des langages similaires. Les sigils rendent même la lecture du code plus facile, parce qu’ils indiquent immédiatement le type simple d’une variable, ou dans Raku son interface, et permettent d’utiliser utilement le même espace de noms de variables avec différents sigils. Ça paraît étrange, ça ressemble à des caractères inutiles, et il faut en connaître le sens, mais cela peut simplifier la vie : https://www.perl.com/article/on-sigils/
    Les problèmes apparaissent avec les gens qui ne savent pas vraiment ce qu’ils font. Pour eux, ce langage gremlin peut être un cauchemar éveillé, et ils ont besoin de beaucoup de protections : pare-chocs de bowling, bouées, gants en Kevlar, casque, GPS. Cela ne veut pas dire qu’on ne peut pas construire un gratte-ciel avec un langage gremlin ; seulement qu’un non-gremlin prompt aux accidents ne le peut pas, alors qu’un gremlin avisé, lui, le peut

    • La mentalité selon laquelle « seuls les gens assez bons peuvent utiliser cet outil » me semble être un énorme code smell de conception
      Les outils existent pour aider une équipe à mieux ou plus vite accomplir ce dont elle a besoin. Si l’on utilise un outil inutilement complexe pour filtrer les juniors ou flatter son ego, cet outil tient plus de l’arme que de l’aide pour le reste de l’organisation