L'équipe de Go publie des brouillons du design du langage Go 2
Au menu : la généricité, la gestion des erreurs et la sémantique des valeurs d'erreur

Le , par Coriolan, Chroniqueur Actualités
Go est un langage de programmation compilé et concurrent développé par Google. Les créateurs de Go ont voulu offrir aux développeurs, même ceux qui sont inexpérimentés, un langage facile à comprendre et facile à adopter pour réaliser de bons programmes. Depuis sa sortie en 2009, Go a connu une forte adoption à cause de ses avantages très intéressants, toutefois, des développeurs ont pointé du doigt certains de ses inconvénients.


En avril, le langage Go s’est doté d’un nouveau logo, une première étape dans la refonte de l’image du langage. Désormais, place à la conception de Go 2 annoncé l’année dernière. À l’occasion du sommet de contributeurs de Go qui se tient annuellement, les participants ont eu droit à un avant-goût des ébauches de possibles designs pour les changements à venir dans le langage. Dans le cadre de ce processus de design de Go 2, l’équipe de développement a publié ces brouillons afin de lancer le débat sur trois sujets : la généricité, la gestion des erreurs et la sémantique des valeurs d’erreur.

La gestion d’erreurs

L’effort autour de Go 2 a pour objectif global de se pencher sur les façons les plus significatives qui empêchent Go de garder son évolutivité à de larges bases de code et d’amples efforts de développeurs.

« Une façon qui fait que les programmes Go échouent à garder leur évolutivité réside dans l’écriture du code de vérification et de gestion d’erreurs, » a écrit Russ Cox, développeur de Google. « En général, les programmes de Go ont trop de code de vérification d’erreurs et pas assez pour s’en charger. L’ébauche du design vise à se pencher sur ce problème en introduisant une syntaxe allégée pour le contrôle d’erreur. »

Pour assurer l’évolutivité de larges bases de code, les programmes de Go doivent être légers sans répétition inutile, mais aussi robustes et gérant avec élégance les erreurs lorsqu’ils remontent en surface.

« Dans le design de Go, nous avons fait un choix conscient d’utiliser des résultats et des contrôles d’erreurs explicites. Par opposition, C typiquement utilise le contrôle explicite d’un résultat d’erreur implicite, errno, alors que la gestion d’exception, se trouvant dans beaucoup de langages comme C++, C#, Java et Python, représente un contrôle implicite de résultats implicites, » a écrit Cox.

« Les subtilités du contrôle implicite sont traitées dans « Cleaner, more elegant, and wrong » (2004), et « Cleaner, more elegant, and harder to recognize » (2005). En substance, parce que vous ne pouvez pas voir les contrôles implicites, il est difficile de vérifier par inspection que la gestion d’erreurs se recouvre de l’état du programme au moment où il y a un échec de contrôle. »

Cox a donné un exemple pour illustrer ce problème. On prend en considération ce code écrit en Go avec des exceptions :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
func CopyFile(src, dst string) throws error {
    r := os.Open(src)
    defer r.Close()
 
    w := os.Create(dst)
    io.Copy(w, r)
    w.Close()
}
Ce code est élégant et propre, mais aussi invisiblement erroné : si io.copy ou w.Close échouent, le code ne supprime pas le fichier dst écrit partiellement.

D’autre part, l’équivalent de ce code aujourd’hui est :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 func CopyFile(src, dst string) error {
    r, err := os.Open(src)
    if err != nil {
        return err
    }
    defer r.Close()
 
    w, err := os.Create(dst)
    if err != nil {
        return err
    }
    defer w.Close()
 
    if _, err := io.Copy(w, r); err != nil {
        return err
    }
    if err := w.Close(); err != nil {
        return err
    }
}
Ce code n’est ni élégant ni propre et il est toujours faux comme la version précédente, il ne supprime pas le fichier dst quand io.Copy ou w.Close échouent. Il y a un argument plausible qu’un contrôle visible puisse pousser un lecteur attentif à se demander quelle réponse de contrôle d’erreur est appropriée à ce point du code. En pratique, cependant, les contrôles d’erreur prennent trop d’espace que les lecteurs apprennent rapidement à les ignorer pour voir la structure du code.

Le code a aussi une seconde omission dans son contrôle des erreurs. Les fonctions doivent inclure typiquement des informations pertinentes sur leurs arguments dans leurs erreurs, comme os.Open qui retourne le nom du fichier ouvert. Retourner l’erreur non modifiée produit un échec sans aucune information sur la séquence d’opération qui a conduit à cette erreur.

Pour résumer, ce code inclut beaucoup trop de vérifications d’erreur et pas assez de contrôle. Une version plus robuste avec plus d’erreurs utiles serait :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
func CopyFile(src, dst string) error {
    r, err := os.Open(src)
    if err != nil {
        return fmt.Errorf("copy %s %s: %v", src, dst, err)
    }
    defer r.Close()
 
    w, err := os.Create(dst)
    if err != nil {
        return fmt.Errorf("copy %s %s: %v", src, dst, err)
    }
 
    if _, err := io.Copy(w, r); err != nil {
        w.Close()
        os.Remove(dst)
        return fmt.Errorf("copy %s %s: %v", src, dst, err)
    }
 
    if err := w.Close(); err != nil {
        os.Remove(dst)
        return fmt.Errorf("copy %s %s: %v", src, dst, err)
    }
}
Corriger ces fautes n’a fait que rendre le code plus correct, pas plus propre ou plus élégant.

Valeurs d'erreur et programmation générique

De ce fait, Cox note que Go 2 vise à rendre le contrôle d’erreurs plus léger, en réduisant la quantité du texte dans le programme Go dédié à la vérification d’erreurs. Il y a aussi l’envie de rendre l’écriture de gestion d’erreurs plus pratique, ce qui augmente la chance que les programmeurs vont allouer du temps à le faire. Tout ça sans mentionner le fait que la vérification et le contrôle d’erreurs doit rester explicite, donc explicite dans le texte du programme.

En plus de la gestion d’erreur, l’équipe veut faire en sorte que les programmes larges doivent être en mesure de tester et réagir aux erreurs et aussi les rapporter d’une bonne façon.

« Une façon qui fait que les programmes en Go échouent à bien garder leur évolutivité réside dans la capacité d’erreurs typiques. Une variété de paquets populaires ajoute des fonctionnalités qui vont au-delà de l’interface d’erreur standard, mais dans des façons incompatibles, » a écrit Cox. « Avec Go 2, nous envisageons de standardiser des “interfaces optionnelles” pour des erreurs afin de permettre aux paquets d’interopérer et idéalement en réduire le besoin. »

Pour faire cela, Cox a cité deux objectifs qui correspondent à ces problèmes : d’abord, il y a un besoin de rendre l’inspection par programmes plus facile et moins exposée aux erreurs, le but étant d'améliorer le contrôle d’erreurs et la robustesse des programmes réels. Deuxièmement, l’équipe veut rendre possible l’impression d’erreurs avec des détails additionnels dans une forme standard.

Enfin, l’équipe a parlé de la programmation générique et comment elle compte l’implémenter dans Go. En programmation, la généricité (ou programmation générique), consiste à définir des algorithmes identiques opérant sur des données de types différents. On définit de cette façon des procédures ou des types entiers génériques. On pourrait ainsi programmer une pile, ou une procédure qui prend l'élément supérieur de la pile, indépendamment du type de données contenues.

Cox note que l’équipe est consciente du potentiel de la généricité, pour rendre Go plus flexible et puissant et en même temps loin d’être plus compliqué. En gros, l’équipe veut rendre possible le polymorphisme paramétrique avec des paramètres de type. Mais cette implémentation va se faire à petits pas histoire d’apprendre et éviter les problèmes que la généricité a causés dans C++ et Java.

Pour consulter en détail ces brouillons, veuillez consulter les documents publiés par l’équipe de Go.

Source : googlesource

Et vous ?

Qu’en pensez-vous ?
Utilisez-vous le langage Go ? Quels sont les avantages que vous lui trouvez ?
Et quels sont ses inconvénients ?

Voir aussi

Le langage Go se dote d'un nouveau logo, une première étape dans la refonte de l'image du langage, la mise à jour du site sera la prochaine étape
Quels avantages ou inconvénients trouvez-vous au langage Go ? Schörghuber raconte son aventure avec Go et finit par le rejeter pour diverses raisons
Le langage Go se mesure à C++, Java et Scala une nouvelle étude comparative des performances, menée par un ingénieur de Google


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :


 Poster une réponse Signaler un problème

Avatar de codec_abc codec_abc - Membre averti https://www.developpez.com
le 30/08/2018 à 1:48
C'est fantastique! Bientôt Go ressemblera à un langage de moitié du 20ieme siècle.

J'ai franchement du mal à voir ce qui peut rendre attrayant Go. Ces créateurs ont clairement ignoré les décennies de recherches que des chercheurs ont fait sur les langages et implémentation et on se retrouve avec un langage primitif et hyper verbeux. A ma connaissance seul le tooling est plutôt bien foutu (encore que j'ai entendu que la gestion de dépendances est un peu laxiste). Bon en même temps, c'était annoncé dès le début par Rob Pike:

The key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt.
Du coup, je me demande si les gens qui apprécient Go:

1- Sont d'accord avec la phrase ci-dessus ?
2- Se considère eux-mêmes comme étant incapable de comprendre un langage brillant ?

Si un gopher qui passe par là veut bien répondre à ces questions je le remercie par avance.
Avatar de Mingolito Mingolito - Membre extrêmement actif https://www.developpez.com
le 30/08/2018 à 1:56
En fait Go c'est quoi ? C'est un reboot marketing par Google du Pascal Objet mais en moins bien ?
Avatar de pboulanger pboulanger - Membre actif https://www.developpez.com
le 30/08/2018 à 9:23
Vive le C ou le C++... "Go' too null...
Avatar de strato35 strato35 - Membre régulier https://www.developpez.com
le 30/08/2018 à 13:32
Sur le papier c'est bien joli le Go.. mais bon la structure du code est quand même moche... Quand on viens d'autres langages "courant" comme le C# ou le Java, ça donne juste la gerbe de voir ce genre de code...
Après je suis pas contre la volonté de faire un langage accessible, mais ça veux dire que quelqu'un débutant par du Go aura beaucoup de mal à passer vers un langage historique le jour où il en aura besoin, et un habitué des autres va râler comme un Javaiste qui se met au php... (Je n'ai rien contre java ou php, je pratique les 2, et je râle sur les 2...)

Vive le C ou le C++... "Go' too null...
Ce n'est pas dans la même cours.. tu admettra tout de même qu'il est plus facile de faire du python pour "monsieur tout le monde" que de faire du C++ ... (même si on est d'accord, C++ ça déchire quand on sais l'utiliser )

Si un gopher qui passe par là veut bien répondre à ces questions je le remercie par avance
+1
Avatar de Dymmm Dymmm - Nouveau membre du Club https://www.developpez.com
le 30/08/2018 à 14:03
Citation Envoyé par codec_abc Voir le message
Si un gopher qui passe par là veut bien répondre à ces questions je le remercie par avance.
Bon, je suis sur pas un gopher pur et dur, mais j'ai néanmoins sélectionné ce langage pour mon prochain projet back-end de mon département. Je travail dans une mini équipe de deux personnes et nous sommes en charge de la création, évolution et de la maintenance d'un backend mode SOA. Habituellement mon département travail en C et cela depuis 1985. J'ajouterai même que, à mon grand regret et malgré mes efforts, notre processus de développement est issu de cette année également.

Par rapport au C, utiliser le Go permet, jusqu’à présent, de régler pas mal de souci :
  • source bien plus facile a lire que le C
  • Dispose d’une bibliothèque standard importante
  • la gestion des erreurs et bien plus naturelle : si ca retourne un 'error' alors il faut le gérer
  • conversion implicite causant des effets de bord pénible a localiser
  • plus de dead lock
  • fuite de mémoire courante lors des premières releases en prod
  • liaison statique des bibliothèque, donc plus de version de bibliothèque a installer en prod


Alors comme ça, on peut dire que le C l'offre aussi... mais, cela dépend avec qui on travail. Le Go sera moins permissif que le C et permettra d'obtenir cela plus naturellement. Les mentalités de certaines personnes sont dures à changer et dans ce cas, j'ai grand espoir que le Go améliorera grandement la qualité logicielle.
Avatar de SofEvans SofEvans - Membre expérimenté https://www.developpez.com
le 30/08/2018 à 14:21
Citation Envoyé par Dymmm Voir le message
Par rapport au C, utiliser le Go permet, jusqu’à présent, de régler pas mal de souci :
  • source bien plus facile a lire que le C
  • Dispose d’une bibliothèque standard importante
  • la gestion des erreurs et bien plus naturelle : si ca retourne un 'error' alors il faut le gérer
  • conversion implicite causant des effets de bord pénible a localiser
  • plus de dead lock
  • fuite de mémoire courante lors des premières releases en prod
  • liaison statique des bibliothèque, donc plus de version de bibliothèque a installer en prod
Je suis dans le même cas que toi : Je fais du C et on est en cours de migration Go.

Autant sur certains point je suis d'accord, sur d'autre je sais pas, et sur le reste, je ne suis pas d'accord.

Dire que lier statiquement les bibliothèques en Go c'est mieux que le C, c'est juste passer à côté des points suivant :
* le C te permets de lier une bibliothèque en statique ou dynamique
* Si on fait des bibliothèques dynamique et statique, c'est bien que chacune possède des avantages et des inconvénient.
En l'occurence, si tu ne fais que du statique, le jour où tu découvre un bug dans une bibliothèque, t'es bon pour recompiler tout tes projets et tous les redéployer (avec tout le bazar que ça engendre).
* Go l'a très bien compris, et propose maintenant de faire des bibliothèque dynamique (même utilisable en C ! On va utiliser cet aspect pour faire une migration "en douceur").

Pour les fuite de mémoire en C, il faut rajouter une étape "valgrind/Dr Memory" à votre chaîne de test (même si je suis d'accord qu'avec certaines bibliothèque on obtient des faux positif : merci libssl).

Pour la gestion de l'erreur, je suis surpris. Je ne savais qu'il fallait absolument gérer les erreurs en Go. Y'a pas moyen de les ignorer ?
Avatar de Pyramidev Pyramidev - Membre expert https://www.developpez.com
le 30/08/2018 à 14:27
Dymmm et SofEvans, pourquoi avoir choisi Go au lieu de Rust ? Est-ce à cause des bibliothèques ou bien d'autre chose ?
Avatar de SofEvans SofEvans - Membre expérimenté https://www.developpez.com
le 30/08/2018 à 14:56
Décision hiérarchique, et je n'ai pas les connaissances nécessaires en Go ou Rust pour y dire quoi que ce soit.
Avatar de Dymmm Dymmm - Nouveau membre du Club https://www.developpez.com
le 30/08/2018 à 15:03
Citation Envoyé par Pyramidev Voir le message
Dymmm et SofEvans, pourquoi avoir choisi Go au lieu de Rust ? Est-ce à cause des bibliothèques ou bien d'autre chose ?
Dans mon cas, mon choix a été orienté par des considérations psychologiques. je dois m'assurer que le langage choisi soit accepté par mes collègues. J'ai choisi le Go car il est simple et relativement proche du Pascal, langage regretté par certaines des personnes avec qui je travail. Le Rust me plait bien, mais il offre bien trop de choses effrayantes, POO et autre. J'ai vu passer des choses effarantes écrites en C... je n'ose pas imaginer ce qui pourrait être produit en Rust

Citation Envoyé par SofEvans
Je suis dans le même cas que toi : Je fais du C et on est en cours de migration Go.

Autant sur certains point je suis d'accord, sur d'autre je sais pas, et sur le reste, je ne suis pas d'accord.

Dire que lier statiquement les bibliothèques en Go c'est mieux que le C, c'est juste passer à côté des points suivant :
* le C te permets de lier une bibliothèque en statique ou dynamique
* Si on fait des bibliothèques dynamique et statique, c'est bien que chacune possède des avantages et des inconvénient.
En l'occurence, si tu ne fais que du statique, le jour où tu découvre un bug dans une bibliothèque, t'es bon pour recompiler tout tes projets et tous les redéployer (avec tout le bazar que ça engendre).
* Go l'a très bien compris, et propose maintenant de faire des bibliothèque dynamique (même utilisable en C ! On va utiliser cet aspect pour faire une migration "en douceur").

Pour les fuite de mémoire en C, il faut rajouter une étape "valgrind/Dr Memory" à votre chaîne de test (même si je suis d'accord qu'avec certaines bibliothèque on obtient des faux positif : merci libssl).

Pour la gestion de l'erreur, je suis surpris. Je ne savais qu'il fallait absolument gérer les erreurs en Go. Y'a pas moyen de les ignorer ?
Bon, c'est vrai que tu n'avais pas toutes les info en mains. Actuellement, nous travaillons sur des AIX avec "vi" et "xlc" en SSH. J'ai essayer durant un temps de travailler en parallele sur Linux pour assurer un minimum de test avec Valgind mais cela c'est avéré trop chronophage et je n'arrivais pas a justifier les modifications pour compatibilité big - little endian.
En ce qui concerne les liaisons dynamiques, lorsque les serveurs de dev, certification et prod n'ont jamais les mêmes versions des lib les catastrophes arrivent.
Avatar de codec_abc codec_abc - Membre averti https://www.developpez.com
le 30/08/2018 à 15:40
Citation Envoyé par Dymmm Voir le message
Bon, je suis sur pas un gopher pur et dur, mais j'ai néanmoins sélectionné ce langage pour mon prochain projet back-end de mon département. Je travail dans une mini équipe de deux personnes et nous sommes en charge de la création, évolution et de la maintenance d'un backend mode SOA. Habituellement mon département travail en C et cela depuis 1985. J'ajouterai même que, à mon grand regret et malgré mes efforts, notre processus de développement est issu de cette année également.

Par rapport au C, utiliser le Go permet, jusqu’à présent, de régler pas mal de souci :
  • source bien plus facile a lire que le C
  • Dispose d’une bibliothèque standard importante
  • la gestion des erreurs et bien plus naturelle : si ca retourne un 'error' alors il faut le gérer
  • conversion implicite causant des effets de bord pénible a localiser
  • plus de dead lock
  • fuite de mémoire courante lors des premières releases en prod
  • liaison statique des bibliothèque, donc plus de version de bibliothèque a installer en prod


Alors comme ça, on peut dire que le C l'offre aussi... mais, cela dépend avec qui on travail. Le Go sera moins permissif que le C et permettra d'obtenir cela plus naturellement. Les mentalités de certaines personnes sont dures à changer et dans ce cas, j'ai grand espoir que le Go améliorera grandement la qualité logicielle.
Déjà il y a quelques erreurs dans ta liste de features:



Ensuite il y a débat sur la gestion d'erreurs, bien qu'elle soit "complète" (chose que j'apprécie de manière générale), elle est hyper verbeuse et des langages comme Rust pourtant plus bas niveau font beaucoup mieux. Et je ne parle de ce passage sur la FAQ qui est juste pitoyable.

Et après, pour la très grande majorité des points que tu cites, des langages "battle tested" tel que Java ou C# les fournissent avec un écosystème (et un pool de développeur) bien plus grand que celui de Go. Du coup, je suis toujours pas convaincu par ce que Go apporte. Ça me donne l'impression que Go c'est pour les dinosaures qui ne veulent pas apprendre un langage plus récent dans les domaines ou le C ne se justifie plus aujourd'hui.
Contacter le responsable de la rubrique Accueil