Atomy : un Lisp Algébrique pour Rubinius

Source - le 26/12/2011 à 23:13:37

Petite
Phrase
Pour éviter que
L'avatar
Ne casse l'alignement du texte
Qui suit.

Atomy is a language designed to grow. It achieves this goal by having a very simple grammar, much like Lisp. Rather than statements, everyting in Atomy is an expression. These expressions are not merely written, they are designed. Readability, concision, and flow are the primary goal, and this goal is most easily achieved by keeping the grammar small, and building everything up from there with macros and metaprogramming.

Atomy's platform of choice is the Rubinius VM. Its syntax already scales upward to encompass every common Ruby construct (with its own flavor), and Ruby libraries can be used transparently, as long as they run on Rubinius.

An integral part of Atomy's core is pattern-matching dispatch. This gives you immense expressive power, with a form of multiple dispatch. Atomy's style favors declaring your data structures first and defining methods in a functional style in terms of all of their "roles" (the receiver and the message's arguments).

Je suis tombé là par hasard. Le type qui fait ça est un rubyste, mais il n'est pas ignare, il a un bon goût pour le Scheme. Intéressant.

12 réponse(s)

thizanne # - le 27/12/2011 à 00:40:44 - Répondre - Source
Avatar

J'ai pas tout regardé, mais ça a l'air effectivement intéressant. J'aime bien cette espèce de mélange entre fonctionnel et orienté-objet (dans le sens de smalltalk plus que de java) - à moins que le peu que j'ai vu me fasse dire une bêtise.

rz0 # - le 27/12/2011 à 13:02:29 - Répondre - Source
Avatar

Donc après avoir copité sur Lisp, now, Ruby devient Lisp, tout entier. Intéressant. :] #troll

grds # - le 27/12/2011 à 13:27:25 - Répondre - Source
Avatar

Atomy se vante d'être algébrique, mais on a du mal à comprendre ce que ça veut dire dans ce contexte quand on lit le chapitre It's algebraic! : cf http://atomy-lang.org/what-and-why.html#section_its-algebraic

An integral part of Atomy's core is pattern-matching dispatch. This gives you immense expressive power, with a form of multiple dispatch. Atomy's style favors declaring your data structures first and defining methods in a functional style in terms of all of their "roles" (the receiver and the message's arguments).

C'est ça qui rend le langage algébrique ?

(en tous cas c'est très joli comme langage je trouve)

gasche # - le 27/12/2011 à 18:42:02 - Répondre - Source
Avatar

"Algébrique" fait ici référence aux types algébriques des langages ML (Hope, OCaml/SML, Miranda, Haskell...).

Il y a une différence importante par rapport à la sémantique du filtrage en ML (mais qui ne se voit pas forcément), la précédence des motifs n'est pas basée sur un ordre haut-bas (le pattern définit en premier, s'il matche, a la précédence sur tous les autres), ici c'est l'ordre "le plus précis gagne". Évidemment le langage de motifs est trop riche pour pouvoir définir ça précisément, mais ça reste un point important pour permettre l'extensibilité après-coup (c'est un principe général des langages à multiple dispatch).

thizanne # - le 27/12/2011 à 20:07:28 - Répondre - Source
Avatar

↑ ce qui explique le cas default en plein milieu des filtrages. Ça semble intéressant à première vue, en pratique je doute que ça ne pose pas de problèmes sur des filtrages un peu complexes (qu'est ce qui est le plus précis entre (_, 1) et (1, _) ?)

gasche # - le 27/12/2011 à 21:04:55 - Répondre - Source
Avatar

La réponse est assez gore: de ce que je comprends du code, il a un opérateur qui renvoie -1, 0 ou 1 selon que les patterns atomiques (variables, wildcard et constantes) sont plus ou moins précises, et pour les patterns composés il fait la somme (sic) des comparaisons des sous-patterns. Donc ici ça donne (_ <=> 1) + (1 <=> _), soit 0, les deux patterns sont considérés comme "aussi précis", c'est la magie. Du coup il s'autorise à choisir l'un ou l'autre, mais je crois qu'il y a un ordre donné (je suppose de haut en bas, j'ai pas vérifié).

thizanne # - le 28/12/2011 à 00:41:10 - Répondre - Source
Avatar

J'ai hésité entre « Hum. » et « :D » comme réponse. Merci de ces explications en tout cas. L'impression que j'en ai, c'est que c'est beaucoup de complications potentielles pour, finalement, une simplification qui n'en est pas vraiment une : « on n'a qu'à écrire les pattern plus précis en haut. »

gasche # - le 28/12/2011 à 01:03:54 - Répondre - Source
Avatar

Comme j'ai essayé de le dire mais quand on ne prend pas vraiment le temps de l'expliquer ce n'est pas clair et on ne peut s'en prendre qu'à soi-même, l'intérêt pour le concepteur du langage, je pense, est l'utilisation pour de l'extension à posteriori de méthodes. Quelque chose comme (c'est pas la syntaxe directe du langage, hein, j'invente):

(n: Integer) show = n Integer.to_string
(s: String) show = s
_ = "<invisible>"

et plus tard, dans un autre module

data(Pouet):
  Foo
  Bar(@baz)

Foo show = "Foo"
Bar show = "Bar(" + @baz show + ")"

C'est une astuce classique dans un contexte de dispatch multiple (les utilisateurs de langages dynamiques disent même que ça résoud l'Expression Problem, alors que les gens des langages statiques disent que ça ne permet pas pour autant de vérifier que les définitions sont sûres); en contrepartie, la question de la définition de "plus fin que" se pose tout de suite aussi.

thizanne # - le 28/12/2011 à 01:49:16 - Répondre - Source
Avatar

Pardon, j'avais effectivement lu ce que tu essayais de dire mais je l'ai oublié en répondant.

Je continue tout de même d'avoir du mal avec cette notion de « plus précis » : pouvoir définir un cas par défaut qui permette un rajout postérieur de cas possibles (comme tu le fais dans ton exemple) c'est très bien, mais encore une fois le problème est qu'on n'a pas seulement « un cas par défaut ». L'exemple que j'avais choisi était simple, mais imaginons par exemple _ :: _ : si je comprends bien, c'est considéré comme « moins défini » que _. Pourtant, il me semble qu'on s'attendrait intuitivement au contraire.

edit : après réflexion, il me semble qu'en fait le cas de _ :: _ vs. _ pose surtout un problème de « sur quoi porte le plus ou moins défini » : dans le premier cas, on a deux wildcards qui peuvent prendre chacune une valeur a priori indéterminée, donc « deux degrés de liberté » pour parler comme un physicien, contre un seul dans le deuxième. D'un autre côté, le premier motif impose celui d'une liste non vide, alors que le deuxième n'impose rien (éventuellement une liste selon le typage du langage) en tant que motif.

En même temps il me semble qu'on peut considérer, si on veut continuer à jouer au physicien, que _ est de toute façon à degré de liberté infini (et dans cet exemple ça marche bien pour dire que _ est plus défini que _ :: _, parce qu'il impose moins de choses sur la structure tout en ayant le même nombre de « valeurs indéterminées »). Mais d'une part ça me semble beaucoup trop louche pour être utile en vrai, et d'autre part j'ai l'impression qu'on pourrait trouver deux motifs où ça ne marcherait pas.

HS : je me suis (presque) toujours dit que ce serait intéressant de voir ce que donnerait un langage où les types marcheraient comme des dimensions physiques (exemple : (*) qui serait de type t -> s -> t.s), et cette idée floue et louche de degrés de liberté me plaît, ne serait-ce que pour jouer avec.

acieroid # - le 28/12/2011 à 09:23:56 - Répondre - Source
Avatar

Citation de Maxibolt

HS : je me suis (presque) toujours dit que ce serait intéressant de voir ce que donnerait un langage où les types marcheraient comme des dimensions physiques (exemple : (*) qui serait de type t -> s -> t.s), et cette idée floue et louche de degrés de liberté me plaît, ne serait-ce que pour jouer avec.

Frink permet de faire ce genre de choses.

gasche # - le 28/12/2011 à 13:06:51 - Répondre - Source
Avatar

L'approche "degré de liberté" n'est pas la bonne façon de penser au problème. Un motif est à la fois un test (j'accepte ou pas) et un enrichissement de l'environnement quand on accepte. Un motif est plus général qu'un autre quand il accepte plus souvent : p1 est plus général que p2 quand pour tout x, test(p1,x) implique test(p2,x). _ est plus général que _ :: _. Le problème c'est que ce n'est pas un ordre total.

Pour des unités de mesures dans un langage typé, cf. le travail de Andrew Kennedy pour F#, et pour l'inférence le rapport de recherche de Adam Gundry.

thizanne # - le 28/12/2011 à 15:02:01 - Répondre - Source
Avatar

J'ai lu (mais pas tout compris, il me manque des notations) le truc d'Andrew Kennedy, c'était intéressant, merci.

Répondre à "Atomy : un Lisp Algébrique pour Rubinius"

Vous devez être connecté pour poster.