-
Notifications
You must be signed in to change notification settings - Fork 2
Discussion sur la syntaxe
Dans cette page, on documente des améliorations possibles de la syntaxe de PML, pour rendre le langage plus montrable à court terme.
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 commef (S[x])
commeS[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é enS[]
, mais c'est un peu lourd. - (-) La séquence
S[{...}]
est un peu lourde.
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 queCons[{hd = x; tl = xs}]
(un caractère de moins). - (-) On a besoin de parenthèses pour
f (#S x)
, au lieu def 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).
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 syntaxiqueA + 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: # ` @
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.
- (+) ç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.
-
fun x y z -> t
oufun x y z { t }
-
if c then a else b
(ou?a if c else b
) ouif 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 valeurb
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 ?
-
A of x | B of y
ou bienA 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
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.