• # odin, le langage

    Posté par  . Évalué à 1.

    une alternative au langage C, et dans une certaine mesure à Golang ?

    `The Odin programming language is fast, concise, readable, pragmatic and open sourced. It is designed with the intent of replacing C with the following goals:

    simplicity
    high performance
    built for modern systems
    joy of programming
    

    `

  • # Pascal

    Posté par  (site Web personnel) . Évalué à 5.

    On a bien vu que c'était au moins largement inspiré de Pascal! Essaie pas de nous embrouiller en faisant croire que c'est pour remplacer C ou Go!

  • # "Billion dollar mistake"

    Posté par  (site Web personnel) . Évalué à 2.

    C'est le premier truc que je regarde: y a-t-il de références nulles ? Malheureusement, c'est le cas dans ce langage. En fait, après avoir jeté un coup d’œil, j'ai du mal à voir ce qu'il propose de neuf. Pas de types algébriques, des références nulles… je ne vois pas où est la "joie de programmer".

    • [^] # Re: "Billion dollar mistake"

      Posté par  (site Web personnel) . Évalué à 3.

      Si c'est comme dans Go (à vérifier), nil est typé et peut être utilisé comme valeur (on peut même lui appliquer des méthodes tant qu'elles n'accèdent pas à la valeur pointée). Le pire qui puisse se passer, c'est un panic si on accède à la valeur pointée : pas de soucis de safety mémoire. Rien qui ne puisse se passer dans un langage dynamique quelconque et équivalent à un .unwrap() de Rust.

      La joie de programmer est dans la productivité sans prises de tête, s'intéressant plus au résultat qu'à la façon d'y arriver, comme avec Python/Perl/Ruby/…. En prime, on a plus de garanties statiques et de meilleures performances. À partir de là, “billion dollar mistake” est à mon avis une hyperbole pour beaucoup de langages.

      • [^] # Re: "Billion dollar mistake"

        Posté par  (site Web personnel) . Évalué à 3.

        nil n'est pas du tout équivalent à unwrap en Rust. Dans un cas, on peut avoir un panic sans le savoir (on croit avoir un objet valide, mais pas de chance, c'est un nil), dans l'autre cas, on a un type Result qu'on peut choisir d'ignorer explicitement (ce qu'on ne fait pas dans un code en production, normalement).

        De plus, ce n'est pas parce qu'on peut passer nil comme paramètre de méthode qu'il est typé. Un nil dans ce genre de langage n'est pas typé, puisque rien de distingue un nil d'un autre, si je puis m'exprimer ainsi. En revance, en Rust, pour garder cet exemple, un None a un type qui est Option<T>, donc un Foo "nul" et un Bar "nul" n'ont pas le même type: Option<Foo>::None vs Option<Bar>::None. Le fait d'avoir des références nulles fait qu'il y a un typage faible localement.

        Pour avoir utilisé les 2 types de gestion d'erreur, je fais tout pour éviter les langages avec référence nulle qui obligent à vérifier tout le temps qu'on a bien un objet valide.

        • [^] # Re: "Billion dollar mistake"

          Posté par  (site Web personnel) . Évalué à 2.

          Sinon tu as l'approche d'Objective C: appeler une méthode d'un objet nil renvoie nil. Pas de plantage, il ne se passe juste rien.

        • [^] # Re: "Billion dollar mistake"

          Posté par  (site Web personnel) . Évalué à 5.

          Pour avoir utilisé les 2 types de gestion d'erreur, je fais tout pour éviter les langages avec référence nulle qui obligent à vérifier tout le temps qu'on a bien un objet valide.

          En tout cas pour une valeur nulle en C, tu ne dois pas gérer cela partout. Sinon c'est lourd et inutile. Il y a quelques principes à respecter pour faire de la gestion d'erreur efficace. En gros en faisant de la programmation par contrat.

          Si la valeur nulle est légitime (paramètre optionnel par exemple, ou que la fonction sait traiter comme un cas particulier), tu n'as pas le choix et tu dois le vérifier. Mais ce n'est pas une erreur en tant que tel mais disons un comportement particulier car le pointeur nul est considéré ici comme une entrée valide par ta fonction.

          Sinon, cela signifie qu'une allocation mémoire a échoué quelque part. Or pour moi si une allocation échoue, c'est celui qui fait l'allocation qui doit vérifier si ça a réussi ou pas avant d'envoyer le pointeur nul à toutes les fonctions qui suivent. Cela permet de ne vérifier la validité d'un pointeur qu'à un seul endroit et d'alléger le code des fonctions qui s'attendent à un pointeur valide en entrée.

          Car de toute façon, un pointeur nul n'est pas la seule valeur d'un pointeur invalide. Par accident, ou volontairement, le développeur peut affecter une adresse bidon comme 0x42424242 ou il a libéré la mémoire via free() mais continue d'utiliser le pointeur comme si de rien n'était… Or tu n'as aucun moyen de détecter ces cas de figures, le pointeur nul est finalement un cas particulier d'un pointeur invalide et pourtant le seul qu'on sait identifier à coup sûr.

          Donc la vérification d'un pointeur valide ne peut se faire normalement que par l'appelant de la fonction, la fonction apellée sauf cas spéciaux ne doit pas se préoccuper de la validité du pointeur, le fait qu'on appelle la fonction sous entend qu'il est valide. Car tu ne peux le garantir toi même.

        • [^] # Re: "Billion dollar mistake"

          Posté par  (site Web personnel) . Évalué à 3. Dernière modification le 03/08/19 à 10:01.

          dans l'autre cas, on a un type Result choisir d'ignorer explicitement

          Le truc, c'est qu'entre choisir d'ignorer explicitement (volontairement ou par erreur d'inattention) et le faire sans faire exprès dans le cas de Go où, comme je précise plus bas, il y a au moins 3 raisons qui font que c'est très peu probable (par rapport à du C, par exemple), c'est en pratique très similaire à mon avis, même si d'un point de vue purement théorie des types c'est différent.

          Un nil dans ce genre de langage n'est pas typé, puisque rien de distingue un nil d'un autre, si je puis m'exprimer ainsi.

          Heu, en C oui, mais en Go nil est bien typé : tu ne peux pas utiliser un nil d'un type de pointeur donné comme un nil d'un autre type de pointeur, tout ça est vérifié à la compilation ; nil est dans les faits comme un type option en Go (c'est nil d'un certain type particulier, bref Option<Type>::None), sauf que les syntaxes d'accès à la valeur font un unwrap (explicite dans la syntaxe), ce qui demande un check préalable != nil quand on veut les utiliser.

          Le fait d'avoir des références nulles fait qu'il y a un typage faible localement.

          Eh bien pas dans le cas de Go, qui est plutôt fortement typé : typage faible c'est lorsque tu as des conversions implicites où des comportements imprévisible, arithmétiques de pointeur, etc. Go n'a rien de tout ça (pas même de conversions implicites entre différents types d'entiers, encore moins entre différents types de nil).

          Pour avoir utilisé les 2 types de gestion d'erreur, je fais tout pour éviter les langages avec référence nulle qui obligent à vérifier tout le temps qu'on a bien un objet valide.

          Eh bien, pour avoir utilisé les deux types de langages aussi (j'ai fait du OCaml, quelques petits projets en Haskell et fait 20KLOC de Coq), je n'ai à aucun moment eu l'impression que, pour la gestion d'erreur, je perdais grand chose en passant à Go. En Go, quand tu écris v, err := … c'est pas évident d'oublier de gérer avec if err != nil {…} après : 1) ça devient un réflexe car convention respectée partout dans le langage, 2) si err n'est pas utilisé le compilateur se plaint, 3) il y a des linteur qui vont te donner des warnings sur des cas un peu plus complexes (tu utiliserais err sans checker s'il est nil, par exemple).

          Je fais de loin beaucoup plus d'erreurs de logique (faisables en OCaml, Rust comme en Go), que d'étourderies en ce genre et, les rares étourderies de ce genre, j'ai toujours pu les corriger en un rien de temps; c'est les erreurs de logique qui me font perdre du temps. En Coq tu peux spécifier les comportements et là ça devient vraiment intéressant (et tout aussi gourmand en temps de développement), mais en OCaml, Rust ou Haskell la plupart des erreurs sont en pratique les mêmes qu'en Go. En C, ce serait une autre histoire, bien sûr.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.