• [^] # Re: Critique du langage.

    Posté par . En réponse à la dépêche Le language de programmation ooc sorti en version 0.2. Évalué à 1.

    Bonbonbon, eh bien voila plein de critiques intéressantes. Je vais reprendre point par point:

    > ninja language reference
    ninja est le nom de code de la version 0.2. Je devrais peut-etre mettre entre parenthese le nom complet de la version pour éviter les problèmes de priorité d'opérateurs ;)

    > types primitifs en minuscule/majuscule
    ca dépend de ta définition de "cohérence", en fait. comme dit dans le guide, ooc privilégie la cohérence syntaxique. Cela permet une lecture du code très facile. Tout ce qui a une majuscule en premier = un type. Tout ce qui n'en a pas = une variable ou une fonction
    Pour la "tradition C++", le problème c'est que comme il n'y a aucun standard qui est forcé, tout le monde le fait a sa sauce, et a utiliser c'est un joyeux mélange.
    Quant aux classes Integer/Float en Java, ce sont a mon humble avis des abominations.

    > several variables on the same line
    Je ne vois pas ou est-ce que j'ai dis que "pointeur" etait un type. De plus, sans les pièges du C/C++ concernant justement ce point de grammaire, la déclaration de plusieurs variables lignes n'est *plus* une mauvaise habitude, puisqu'elle est sans danger.

    > correspondance with C and Java types
    Le mot-clé self? Jamais entendu parler en Java. url?
    pour les types numériques, il y en a peut-etre en effet plus que nécessaire.. personellement j'utilise quasiment uniquement des Int et des Float, mais c'était surtout pour ne pas décevoir les programmeurs C qui aiment avoir des types petits pour pouvoir stocker érnomément de nombres en mémoire.

    Pour Octet, et bien précisément non il n'est pas maladroit ;) Le guide ne l'explicite pas assez, mais c'est un typedef vers un uint8_t qui a une taille fixe de.. 8 bits. Si "unsigned char" est aussi dans la colonne "C" a la meme ligne, c'est parce qu'il est généralement utilisé à sa place, par erreur de compréhension (donc que ceux qui utilisent des unsigned char a la place d'uint8_t devraient utiliser des Octet et non des Char en ooc.)
    Les Int en revanche sont des typedefs vers int, donc ils sont également de taille variables. Je vais réfléchir a l'utilisation d'un type numérique de précision arbitraire, mais j'ai l'impression que ce serait très couteux au niveau performance, non?

    > pourquoi pas console.print "A moins que vous n'epousiez la %s?\n".format name ;
    la vraie question est "quand" et non "pourquoi pas" ^^ l'appel de fonctions ayant des arguments sans parentheses est prévu, et la méthode format de String aussi, cependant ça, ça attendra que je trouve une bonne manière d'implémenter/d'écrire (syntaxe) les fonctions variadiques.

    > covers
    ce qui a pu t'échapper, c'est qu'une Cover, c'est d'un type primitif, pas d'une classe. Rajouter des fonctions a un type primitif, et donc pouvoir l'utiliser (syntaxiquement) comme un objet, c'est l'utilité principale des covers.

    > tableaux
    c'est vrai que je n'y ai pas réfléchi beaucoup. Dans l'application qui m'a poussé a développer ooc, j'utilisais des structures plus avancées comme des ArrayList/SparseList, donc des routines de bas niveau encapsulées dans des classes donc avec bound checking et tout le bazar. Je ne vois aucune objection a encapsuler tous les tableaux dans des objets, de plus le cout est rellement minime (1 pointeur vers la structure de meta-classe).

    > mot-clé func
    1) lisibilité, 2) facilité de parsing (moins d'ambiguites dans la grammaire). Et si tu as des doutes sur la nécessité de résoudres des ambiguités qui apparamment n'existent pas, considère que j'ai prévu en ooc la possibilité de faire des fonctions imbriquées (nested functions), et des closures. Le mot-clé func permet donc d'être très lisible et clair dans tous les cas.

    > type de retour après la liste des paramètres
    parce que 1) en C, void ne sert a rien (sinon a faire des pointeurs sur n'importe quoi). C'est un mot parasite qui encombre la syntaxe. Avec une syntaxe comme ooc 0.2, quand tu as une liste de fonction tu vois les choses de gauche a droite dans l'ordre qui t'intéresse le plus (en général) a savoir 1) le nom de la fonction 2) les arguments qu'elle prend et 3) le type de retour s'il y en a un.

    > pourquoi une fonction main?
    heuuuuuuuuuuuuuu eh ben parce qu'on a toujours fait comme ça? ;) non sans rigoler, merci de me rappeler ce que je voulais faire depuis longtemps, en fait. je note.

    > SDL_Quit()
    en effet c'est une incohérence ET une limitation technique temporaire. La note de bas de page explique la difficulté à parser correctement certains headers C. Des améliorations sont à attendre dans les prochaines versions, of course.

    > Instanciation & mot-clé new
    le mot-clé new est principalement une affaire de lisibilité
    Pour l'allocation sur la pile/le tas, eh bien.. pour etre franc, je me suis dit "Java alloue tout sur le tas, et les performaces sont acceptables dans la plupart des cas, donc ça ne devrait pas poser problème."

    Et, après benchmarks, eh ben effectivement:

    newbench_O1 6.522s
    newbench_O1_stack: 1.004s
    newbench_O2: 5.890
    newbench_O2_stack: 0.867s

    Je viens de me dire.. je pourrais faire en sorte, dans le compilateur, que le compilateur détecte ce qui peut etre alloué sur la pile ou le tas, suivant si la variable reste locale ou si son adresse est envoyée ailleurs pour être stockée (ex. appel de fonction avec une assignation de pointeur) ou si elle reste locale, auquel cas elle peut etre allouée sur la pile.

    > functor
    si tu demandes si on peut appeler un objet avec une méthode call a une fonction qui s'attend a un pointeur sur une fonction en espérant très fort que ca appelle "call" tout seul, eh bien non. Pour l'instant, ooc gère les pointeurs sur les fonctions de la même manière que le C pur, mais cela pourrait bien changer (pour permettre le passage de fonctions membres en tant que callback.) J'ai déjà testé une solution basée sur GNU lightning, qui assemble en temps réel une fonction qui appelle la fonction member sur le bon objet. Je n'ai pas fait de benchmarks de performance, par contre.

    > les objets sont-ils polymorphiques ?
    bien sur =) ooc n'aurait que peu d'intérêt s'ils ne l'étaient pas.

    > portée par défaut et encapsulation
    absolument, ooc ne gère actuellement pas les différentes portées, et c'est très très vilain de ma part (je devrais être puni). Mais de nouveau, c'est par manque de temps pour l'instant: implémenter correctement les règles d'encapsulation n'est pas du tout simple, vous pouvez trouver facilement des exemples contre-intuitifs en Java par exemple.

    > for in ranges
    le type range, c'est prévu ^^ de nouveau, manque de temps jusqu'ici.

    > virer switch
    tiens donc? pourquoi cela? je pensais juste inverser le comportement par défaut du C/C++/Java, plus précisément introduire un mot-clé fallthrough et gicler le mot-clé break pour les switch.

    > do while
    Tiens donc, petit oubli de ma part. Bien que je ne l'aies pas du tout prévu dans le compilateur ooc, ca compile quand meme (je viens de tester) car cela ne provoque pas d'erreur de syntaxe.

    > relative to the sourcepath
    eh bien c'est un point controversé en effet, je n'ai pas fini d'y réfléchir, mais j'attends encore qu'on me donne une très bonne raison pour devoir rajouter des lignes "package blah.truc.machin;" a toutes mes classes, autre que "ouais mais si c'est pas le bon sourcepath, ca va tout foirer". C'est pas des manchots, les programmeurs quand meme, ils savent encore quel sourcepath ils mettent, non?

    en tout cas merci pour toutes les remarques, c'est assez curieux: pour la moitié j'ai l'impression que tu voudrais transformer ooc en python, et l'autre moitié que tu voudrais le transformer en C++! on va tenter de trouver un juste milieu =)