Skip to content

Discussion sur la syntaxe

Christophe Raffalli edited this page Aug 6, 2022 · 20 revisions

Dans cette page, on documente des améliorations possibles de la syntaxe de PML, pour rendre le langage plus montrable à court terme.

Révision de syntaxe

Application de constructeurs

Le problème de départ (Rodolphe, soulevé par Christophe) : lorsqu'un constructeur à pour argument un record, dans la syntaxe actuelle de PML, on a beaucoup de crochets et de parenthèses. Par exemple dans Cons[{hd = x; tl = xs}], on pourrait vouloir éliminer un des deux niveau de "parenthésage". Il faut quand même souligner les avantages et inconvénients de l'approche actuelle :

  • (+) Pas d'ambiguïté pour le parsing, on sait qu'on a affaire à un constructeur dés qu'on rencontre le [.
  • (+) On a automatiquement f S[x] reconnu comme f (S[x]) comme S[x] est parsé comme un atome.
  • (+) pas besoin de distinction syntactique entre les noms de constructeurs et les variables ou labels.
  • (-) La syntaxe naturelle pour les constructeurs sans arguments est S[{}], abrégé en S[], mais c'est un peu lourd.
  • (-) La séquence S[{...}] est un peu lourde.

Classe syntactique distincte pour les variants (Rodolphe, par mail)

Utiliser une marque préfixe ou suffixe pour les variants, par exemple $S ou #S.

  • (+) Plus besoin des crochets, on peut appliquer un variant avec l'application "normale".
  • (+) On peut faire #cons{hd = x; tl = xs}, qui est moins lourd que Cons[{hd = x; tl = xs}] (un caractère de moins).
  • (-) On a besoin de parenthèses pour f (#S x), au lieu de f S[x] avant (2 caractèrs de plus au total).
  • (-) Confusion possible : appliquer un constructeur ce n'est pas comme appliquer une fonction.

Conclusion (Rodolphe) : ce qu'on a maintenant n'est pas si mal, et est plus concis en général (même si l'apparence est légèrement plus lourde, principalement sur les exemples triviaux).

Classe syntaxique postfix/infix pour les variants:

Z# pour un variant constant S#x pour un variant avec argument.

  • (+) on gagne un caractère sur S#x versus S[x], on perd un caractère sur Z# versus Z
  • (+) on libère complètement le nommage des autres identifiants
  • (+) cette infix associe naturellement à droite: f S#S#S#x S#Z# sans aucune parenthèse! avec une pririorité plus grande que l'application normale
  • (+) autorise 1# 2# et donc un sucre syntaxique A + B pour [1# of A ; 2# of B] analogue au produit
  • (-) inhabituel et pas super beau (car on n'est pas habitué?) le premier example du book devient Monday#, etc ... peut-être qu'un autre caractère (backquote, exclamation mark, arobasse...) serait mieux ?
  • (-) ça fait un infix spécial plus prioritaire que l'application alors que les autres infix sont moins prioritaires.
  • (?) si on fait ça est-ce que l'on interdit les espaces ? Je dirais oui sinon confusion avec l'application. Mais on ne peut plus aller à la ligne

Conclusion Christophe: ça me plaît vraiment bien. Si dessous des exemples pour choisir le caractère:

S$x     Z$      f S$S$S$S$x S$Z$        Cons$(x,y)      Node${l; x; r}
S#x     Z#      f S#S#S#S#x S#Z#        Cons#(x,y)      Node#{l; x; r}
S`x     Z`      f S`S`S`S`x S`Z`        Cons`(x,y)      Node`{l; x; r}
S%x     Z%      f S%S%S%S%x S%Z%        Cons%(x,y)      Node%{l; x; r}
S!x     Z!      f S!S!S!S!x S!Z!        Cons!(x,y)      Node!{l; x; r}
S@x     Z@      f S@S@S@S@x S@Z@        Cons@(x,y)      Node@{l; x; r}
S^x     Z^      f S^S^S^S^x S^Z^        Cons^(x,y)      Node^{l; x; r}
S\x     Z\      f S\S\S\S\x S\Z\        Cons\(x,y)      Node\{l; x; r}
S~x     Z~      f S~S~S~S~x S~Z~        Cons~(x,y)      Node~{l; x; r}
S&x     Z&      f S&S&S&S&x S&Z&        Cons&(x,y)      Node&{l; x; r}

Christophe: mes préférés: # ` @

Variable "unbound" = variant (Christophe)

Problème: on a pour l'instant des variants constant sans crochet, mais pour cela on impose les variants avec majuscule et tous les autres identifiants en minuscule. Ce n'est pas raisonnable sur les exemples avancés. Le point précédent solution aussi ce problème au prix d'un seul caractère.

Pour ça on doit optimiser les messages d'erreur, pour ne pas "confuser" l'utilisateur, mais ça à l'air de pouvoir marcher.

On peut avoir une approche intermédiaire, où on garder les lower_ident imposé pour les valeurs et termes (sorte iota et tau) mais on est libre pour toutes les autres sortes. Il y a moins de risque de confusion, car ce n'est que si l'on passe un variant dans une application d'ordre supérieur que l'on peut se tromper.

, comme séparateur dans les records

  • (+) ça devient le standard
  • (-) il reste un ';' dans les types, mais c'est défendable car les types utilisent déjà des virgules. La solution est de revoir la syntaxe des types (voir plus bas)

Note: déjà fait dans la dernière branche, mais aucun problème pour revenir en arrière.

accolades pour les blocs, toujours optionnelles, donc deux syntaxes dans certains cas:

  • fun x y z -> t ou fun x y z { t }
  • if c then a else b (ou? a if c else b) ou if c { a } else { b } etc ...
  • Il y a une ambiguïté de syntaxe pour if { b } entre le record { b = b } sans accolade autour et la baleur b avec des accolades. Comme la valeur b n'a pas besoin d'accolade, on peut désambiguer en faveur du record ?
  • Il y a une autre ambiguïté avec les records qui ont des ';' comme séparation. Mais, de toutes façons, on devrait plutôt utiliser des virgules comme python, json, ...
  • (+) code plus légé.
  • (+) standard dans pleins de langage comme C
  • (-) deux syntaxes si on veut des accolades toujours optionnelles pour if, fun et save. Accolade toujours obligatoire pour le case.
  • (-) l'ambiguïté si dessus pour les records avec un seul champs. Un peu compensé par le fait que l'on a déjà un problème avec les tuples de taille 1 qui sont inaccessible sans faire { 1 = x }. Donc on sait que les produits unaires ont déjà des problèmes ?

Syntaxe des types plus homogène entre somme et produit:

Somme:

  • A of x | B of y ou bien A of x + B of y
  • x + y = Pi1 of x + Pi2 of y ou si les variants on un caractère spécial, disons $, x + y = $1 of x + $2 of y C'est un argument fort pour le caratère préfixant les variants.
  • le black bold 0 unicode pour la somme vide

Produit:

  • A : x * B : y
  • x * y = 1 : x * 2 : y (* ou le caractère unicode \times)
  • le black bold 1 pour le produit vide
  • (+) léger
  • (+) bonne dualité entre somme et produit
  • (+) très algébrique
  • (-) trop algébrique
  • (-) ça ne ressemble pas à C et aux autres langages communs qui font des records.