[EDIT = Pour ceux qui n'ont pas le temps de lire toutes les propositions, je modifie régulièrement le premier post afin qu'il prenne en compte les remarques qui sont faites dans les posts suivants]
1 Structure des données
1.1 Types récursifs
On pourrait aussi définir des types basiques. Puis définir :
- vecteur : une suite de variables du même type (y compris les dimensions)
- liste : une suite de variables de types différents.
Le vecteur et liste peuvent s'appliquer à eux-mêmes (type récursifs).
Une matrice est un vecteur de vecteur ; un data.frame serait un vecteur de liste. Mais on pourrait aussi définir des choses plus complexe comme des vecteurs de data.frame, ou des data.frame qui contiendraient des matrices...
Note importante : Classiquement, M[1,2] désigne la 1° ligne et 2° colonne...
Il faut donc qu'une matrice soit construite comme un vecteur colonne constitué de vecteurs lignes.
1 2 3 4 5 6 7
| V1 = (11,14)
V2 = (12,15)
V3 = (13,16)
(V1) (11,14)
M = (V2) = (12,15)
(V3) (13,16) |
Ainsi M[1,2] signifiera : 1° vecteur ligne V1, puis 2° valeur de V1, soit 14. C'est bien la définition classique.
De même, un dataFrame doit être un vecteur (colonne) de liste (ligne), chaque liste étant un individu. Ainsi, D[1,2] sera le premier individu , 2° valeur. Définir un dataFrame comme une liste (ligne) de vecteur (colonne), alors D[1,2] serait le premier élément de la liste (première colonne) dont ont prendrait le deuxième élément. La notation serait inversé par rapport à R (et au bon sens).
Tout cela, c'est du point de vu de l'utilisateur. Du point de vue du code cible, il sera peut-être préférable de code les dataFrame comme des listes de vecteurs, mais il faudra alors inverser la notation : M[1,2] en R++ devra devenir M[2][1].
Enfin, l'utilisateur n'aura pas a connaitre les subtilités de vecteur colonne de vecteur ligne ou inversement. Pour lui, nous créerons un type matrix qui sera simplement un vecteur colonne de vecteur ligne. Idem pour les dataFrame.
1.2 Gestion automatiques des types
On veut un langage à deux niveaux : simple pour l’utilisateur (le médecin) qui n’y connait rien, plus sophistiqué pour l’expert. En conséquence :
- Pour le non expert : Si l’utilisateur ne précise rien (déclaration simple), alors tous les types integer de R++ sont des long (C ou Java) ; les numeric de R++ sont des doubles (C ou Java).
- Pour l’expert : il a possibilité de forcer le format et de déclarer des integer comme des short, int, ou long, les numeric comme des float ou des doubles.
- Option « optimisation de la mémoire » : Il est également possible de typer dynamiquement lors de l’exécution. Cela sera une option à spécifier dans le programme, option qui sera utilisée lors de la compilation. Initialement, tous les integer R++ sont des short. Si un short dépasse sa capacité, il est dynamiquement transformé en int, puis s’il grandi encore en long. Idem pour les float. Naturellement, on perdra en efficacité. C'est pour cela que ca sera une option de compilation.
1.3 Typé non explicitement.
Du point de vue du néophyte, l'instruction
MaClass a <- new MaClass()
est un peu étrange car on écrit deux fois MaClass. Il faudrait simplifier. De plus, il n’est pas vraiment nécessaire de dire le premier MaClass. Il serait suffisant de dire :
ou encore mieux :
Pour les types de base, comme il n’y a pas ambiguïté possible, on peut même supprimer le type :
Ensuite, le typeur fabrique automatiquement le type de b.
1 2 3 4 5 6
| True : logical
3 : integer
3.0 : numeric
"L2" : character
"L2" in ("L1"<"L2"<"L3") : ordered
"Z" in ("A","E","Z","F") : factor |
Bien sur, on pourra forcer le type :
Si on veut déclarer sans initialiser (l’équivalent de int a
:
1 2
| b <- integer()
a <- maClass() |
1.4 Nombre
Autoriser les héxadécimaux via 0x et les binaire via 0b. Généraliser ? Permettre de travailler en base 3, en base 60 (0-9,A-Z,AA-AX) and so on ?
1.5 Indices de tableau et matrice
Les indices des tableaux (et matrice) doivent commencer a 1, et non à 0
1.6 Déclaration des variables
On peut les déclarer n’ importe où (et pas seulement dans l’entête comme dans certains langages).
1.7 Transtypage
Pas de transformation automatique d’un boolean en integer, surtout pas de transformation automatique d’un char en integer.
Pour les transtypages de nombre, a voir : integer peut-il devenir automatiquement un numeric ? vecteur peut-il devenir une matrice ? R le fait en recyclant les nombres ou les vecteurs trop court. Personnellement, je penche plutôt pour non sauf dans le cas integer <-> numeric.
Dans tous les cas, un transtypage "rétrécissant" (genre numeric vers integer, ou matrice d'une colonne vers vecteur) qui rétrécit effectivement (par exemple 1.5 transformé en entier, ou bien la matrice avait en fait deux colonnes) doit déclencher une erreur.
1.8 Transtypage automatique
Le transtypage entre objet définit par l’utilisateur doit pouvoir exister (être définit par l’utilisateur comme une méthode).
1.9 Gestion des dates
Les dates sont des integer avec un habillage.
1.10 Type (en vert, ce qui a été rendu obsolète par un autre point, ou par une réponse)
A priori, on prend les mêmes types de base que java, puis on définit des surtypes qui reprennent les types de bases et qui ajoute factor, ordered et date (qui sont des integer).
Idéalement, il faudrait « cacher » le vrai type à l’utilisateur. Il manipulerait des integer, le programme choisirait tout seul si c’est des int, des short ou des long. Idem pour les float et double.
1.11 Infini
Pour chaque type numeric, les valeurs +infini et –infini existent. Elles sont le plus grand et le plus petit nombre du type. Du coup, l’algèbre est modifié :
1 2 3 4 5
| > a<-250
> b<-250
> c <- a^b
> print(c)
[1]+inf \\ et non une valeur négative comme en java |
1.12 Initialisation
On propose une initialisation par défaut à NA ? Le problème ne se pose plus car on a supprimé la déclaration explicite : la déclaration se fait en même temps que l’affectation. Eventuellement, la déclaration se fait en utilisant un constructeur vide, ce qui créer un objet vide.
Ou bien ou impose une initialisation systématique de tout ? Oui, mais éventuellement vers l’objet vide.
Pour les tableaux, obliger à initialiser peut poser problème. Effectivement. Mais comme il n’y a plus de déclaration, ca ne pose pas de problème. On a le choix : non initialisation (ou initialisation à vide), initialisation à NA ou initialisation classique
1.13 Les manquantes
Il faut pouvoir définir plusieurs types de manquantes : soit NA, soit NA1, NA2, NA3, NA4, NA5 (pour « non renseigné », « illisible », « aberrantes »…
1.14 Déclaration d’un tableau
integer[,] et non pas integer[][]
1.15 Création de tableaux
On doit pouvoir faire l’un ou l’autre.
1 2 3
|
int[3] toto, tutu // simplification de int toto[3], tutu[3]
int titi[3], tete[5] // vrai syntaxe (elle offre plus de liberté) |
Partager