The Go Programming Language

Posté par  . Édité par ZeroHeure et palm123. Modéré par Ontologia. Licence CC By‑SA.
56
6
déc.
2015
Golang

Ce titre me rappelle quelque chose, les noms des auteurs me rappellent quelque chose aussi. Un certain Kernighan…
Il me faut remonter assez loin dans ma mémoire, à une époque où la lecture d'un seul livre permettait de s'occuper un sacré bout de temps.

couverture

Nous avons bien là l'auteur du mythique « The C Programming Language » qui reprend la plume pour un nouveau langage. Cela attise ma curiosité, je contacte l'éditeur qui me propose un spécimen en échange de mon avis impartial. Impartialité toute relative vu les souvenirs et le respect qu'imposent les auteurs du livre et du langage !

Sommaire

The Go Programming Language

par Alan A. A. Donovan et Brian W. Kernighan

Lecture

Le livre entre rapidement dans le vif du sujet après une brève introduction où on apprend que les auteurs sont également des personnes bien connues comme Rob Pike (utf8), Ken Thomson (unix) et Robert Griesemer (V8). Nulle perte de temps à essayer de vendre le langage, si on est là c'est qu'on veut juger sur pièce. Cela tombe bien, la particularité de ce langage est justement d'être simple pour pouvoir être pris en main rapidement. Mais simple ne veut pas dire facile. Le livre s'adresse à des personnes connaissant déjà la programmation, pas nécessairement Go mais il est à mon avis préférable de suivre le tutorial du site de référence avant. Le livre aborde dès le départ des exemples beaucoup plus ardus que ceux des tutos.

Une fois les premiers exemples parcourus, on rentre dès le deuxième chapitre dans la structure du langage, les variables, les fonctions etc d'une manière qui semble assez exhaustive. On s'y retrouve quand même assez facilement, les principes et la syntaxe de base étant très classiques. La première et principale partie du livre décortique le langage, on a le sentiment d'avoir fait le tour et de pouvoir fermer le livre et commencer à mettre tout ça en pratique, ce qui était normal à la naissance du C et qui est de plus en plus rare aujourd'hui. Le langage Go fait le pari que la simplicité reste préférable à l'accumulation de fonctionnalités. Si on aime on est comblé.
Comme dans le livre sur le C, les exemples donnés montrent tout de suite que la simplicité du langage n'empêche pas la complexité de ce que l'on doit faire avec sur des cas réels. Les exercices demandés sont encore pires car ils n'ont parfois pas tellement de rapport avec le chapitre en question et demandent des compétences qui seront acquises dans les chapitres suivants. Par exemple un exercice de bench dans le chapitre sur l'organisation des packages. Mais comme on a de toutes façon prévu de lire et relire le livre plusieurs fois on s'en accomode !

Certains chapitres vont encore plus loin dans l'exhaustivité, par exemple celui sur l'UTF-8 permet de comprendre non seulement comment Go nous aide à résoudre le problème mais également en quoi consiste ce problème en général, avec schémas bien utiles à l'appui.
De même le chapitre sur les tableaux permet de bien comprendre les problématiques d'un tableau de longueur variable et comment cela est géré en Go. Les performances d'un programme résultent souvent de la bonne compréhension de ces mécanismes. En particulier lorsqu'on aborde un nouveau langage, il devient réellement efficace lorsqu'on l'utilise comme il est prévu et non comme on en a l'habitude avec un autre langage.

Le duck typing et les compositions grâce aux interfaces est quand même sympa mais rien de très original jusque là.

On aborde ensuite quelques innovations plus originales, le defer pour lancer un code en sortie de fonction (en entrée aussi d'une certaine manière) et bien sûr les goroutines (threads légers) et channels (canaux de communication entre les goroutines).

Ces dernières possibilités sont illustrées de cas concrets en allant là encore assez loin dans les explications d'ordre général au niveau de la programmation concurrente en général.

Une autre particularité du Go, décrite dans le livre, vient du fait qu'il est accompagné d'un ensemble d'outils d'aide au développement, ce qui n'est pas étonnant car il a en partie été conçu pour permettre de réaliser facilement ces outils. Comme le langage, ces outils (formatage, compilation, tests, coverage, bench, debug, doc, refactoring…) sont les plus simples possibles (à la Unix) tout en couvrant la grande majorité des besoins quotidiens du développeur. Ils ont le même avantage d'être pris en main très rapidement et de ne pas céder à la profusion de fonctionnalités qui finalement perdent le développeur et divise les équipes.

Les deux derniers chapitres concernent les fonctions bas niveau et de reflection (en anglais). Le lecteur est prévenu que ces chapitres sont à réserver aux cas très particuliers, ils sont à éviter dans un premier temps.

En conclusion, c'est grâce à la simplicité du langage qu'un livre comme celui-ci peut couvrir une palette aussi complète de ses possibilités.

Mise en pratique

Ensuite j'ai mis en pratique mes nouvelles compétences dans deux projets nécessitants soit des performances soit du multitache (websocket). Le résultat a été à la hauteur de mes attentes, passée la première étape de prendre l'habitude de la syntaxe des types on est productif très rapidement. Les performances sont d'autant plus impressionnantes que l'on n'hésite pas à utiliser le multiproc.
Au début je ne pensais pas l'utiliser pour autre chose que des cas particuliers, tellement comblé que je suis avec Python/C depuis des années, mais plus je l'utilise plus j'ai du mal a me passer des outils mis à disposition qui rattrapent. En particulier pour le formatage automatique du code, la vérification du code avant exécution et l'aide au refactoring.
Ce que l'on perd du côté dynamique de Python on le gagne en simplicité, pas de magie noire. On aime ou on n'aime pas, le tuto permet de se faire une idée très rapidement.

Références

  • Éditeur Addison-Wesley
  • version papier publiée le 26 octobre 2015
    • 380 pages
    • ISBN: 978-0134190440
  • version ebook publiée le 20 novembre 2015
    • 400 pages
    • ISBN-13: 978-0-13-419058-7
    • ISBN-10: 0-13-419058-0

Aller plus loin

  • # map/fold/filter

    Posté par  (site web personnel) . Évalué à 10.

    Dommage qu'on ne puisse pas utiliser les primitives map/fold/filter, et qu'on doive donc écrire…

    Des boucles :-(

    « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

    • [^] # Re: map/fold/filter

      Posté par  (site web personnel) . Évalué à 1.

      Outch en effet!

      Il y a une raison "officielle" a ce manque? Une justification technique?

      • [^] # Re: map/fold/filter

        Posté par  . Évalué à 3.

        L'absence de generics. D'après ce que j'ai compris c'est qu'il n'y a pas plus simple et efficace que de faire chacun sa bonne boucle des familles plutôt que de torturer le langage pour quelque chose qui sera toujours moins performant.
        La réponse de Rob Pike en code (à ne pas utiliser précise t-il !) : https://github.com/robpike/filter

        On retrouve cette recherche de simplicité à peu près de partout, ça donne une certaine cohérence.
        En pratique j'ai eu besoin d'un set, j'ai commencé par chercher de partout, perdu du temps à essayer des implémentations déjà faites, pour finir par utiliser le map de base et quelques routines maison finalement mieux adaptées à mon problème.

        A voir à l'usage si c'est réellement pénalisant…

        • [^] # Re: map/fold/filter

          Posté par  (site web personnel) . Évalué à 1.

          En effet, quand on cherche les performances, avoir recours aux "syntaxic sugar" (en français c'est comment?) n'est peut être pas toujours pertinent.

          • [^] # Re: map/fold/filter

            Posté par  . Évalué à 2.

            "syntaxic sugar" ("syntactic", non ? à moins que les deux ne soient valables en anglais) -> "sucre syntaxique"

          • [^] # Re: map/fold/filter

            Posté par  . Évalué à 6.

            La question est de savoir si on gagne en performance sur le programme mais aussi sur le programmeur…
            Un essai sur la question par un évangéliste complètement fondu de Go mais qui je pense résume bien ce que l'on adore ou déteste de ce langage :
            http://dave.cheney.net/2015/03/08/simplicity-and-collaboration

        • [^] # Commentaire supprimé

          Posté par  . Évalué à -8. Dernière modification le 09 décembre 2015 à 00:24.

          Ce commentaire a été supprimé par l’équipe de modération.

          • [^] # Re: map/fold/filter

            Posté par  . Évalué à 1.

            Il y a des possibilités de "reflection", avec un module dédié. Le code de Rob Pike que j'ai cité au dessus en est un exemple. Et on trouve dans les librairies tout ce qu'on veut pour faire ça, mais ça ne fait pas partie du langage.

            Comme Dave Cheney l'explique, on ne peut pas ajouter de la simplicité après coup, lorsqu'ils ont mis au point le langage les 3 auteurs se sont dit, si une chose n'est pas considérée essentielle par eux 3 ils ne l'ajoutent pas.

            • [^] # Commentaire supprimé

              Posté par  . Évalué à -6. Dernière modification le 09 décembre 2015 à 17:53.

              Ce commentaire a été supprimé par l’équipe de modération.

    • [^] # Re: map/fold/filter

      Posté par  . Évalué à 3.

      Comment, pas de map!? Mais c'est affreux, même PHP le fait!

    • [^] # Re: map/fold/filter

      Posté par  . Évalué à 1.

      Alors map/fold/filter cela n'a rien à voir avec le langage.
      Les streams sont un pattern arrivés avec scheme qui est tout à fait utilisable avec d'autres langages (js, python, php , etc ). Il suffirait qu'une bonne âme la code pour Go cette lib.

      PS : je m'y colle ce soir

      PS 2 :

      http://streamjs.org/
      coffeestream is a CoffeeScript port by Michael Blume
      streamphp is a PHP port by Ryan Gantt
      python-stream is a Python port by Aris Mikropoulos

  • # totalement hs

    Posté par  . Évalué à -1.

    Totalement hors sujet mais autant je peux comprendre que un livre fasse 300 pages mais un ebook de 400 pages, elles sont compté comment. Parce que soit c'est un epub et je ne vois pas comment compter, soit c'est un PDF et je veux bien connaître le pourquoi des 100 pages en plus

    • [^] # Re: totalement hs

      Posté par  . Évalué à 2.

      Sans répondre à la question, c'est pas 100 pages en plus, mais 20.

    • [^] # Re: totalement hs

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

      ça dépend pas de la police utilisée le calcul des pages ?

      • [^] # Re: totalement hs

        Posté par  . Évalué à -1.

        Si tu autorises le débordement du texte de la page non.

      • [^] # Re: totalement hs

        Posté par  (site web personnel) . Évalué à 3. Dernière modification le 07 décembre 2015 à 12:42.

        Et de la taille des pages, et de l'espacement entre les lignes, etc.

        Pas sûr que pour une version électronique on utilise les mêmes réglages que pour une version imprimé papier.

        Un typographe dans la salle ?

        Python 3 - Apprendre à programmer dans l'écosystème Python → https://www.dunod.com/EAN/9782100809141

        • [^] # Re: totalement hs

          Posté par  . Évalué à 6.

          Une éditrice me disait justement que pour avoir un bon ebook il faut pas juste faire un copier/coller de la présentation du livre papier. Tous ceux qui utilisent régulièrement une liseuse confirmeront.

    • [^] # Re: totalement hs

      Posté par  . Évalué à 5.

      Tu n'as pas besoin d'ouverture a droite dans un ebook contrairement a une version papier et cela semblerait bien correspondre a 20 pages supplementaire.

  • # Téléviseurs

    Posté par  . Évalué à 3.

    Non, Ken n'a jamais produit de téléviseurs, il s'agit de Ken Thompson (avec un p) qui a écrit Unix.

  • # got get et version

    Posté par  . Évalué à 4.

    Je présume que les utilisateurs de go font un usage relativement important de go get, j'ai quelques questions là dessus :

    • comment se passe la gestion de version ? De ce que je vois il récupère le trunk/master (donc mise à jour etc)
    • comment je fais si j'écris un logiciel qui dépend d'une version de la bibliothèque X et que je commence à la faire passer à la dernière version de cette même bibliothèque, mais que je veux continuer à sortir des corrections de la version actuelle de mon appli ? J'utilise plusieurs workspaces (pour pouvoir avoir 2 versions de la même bibliothèque installée) ?
    • l'arborescence dans le quel il l'installe dépend du dépôt, comment ça se passe pour un projet qui change de dépôt (qui passe de google code à github par exemple) ?

    Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

    • [^] # Re: got get et version

      Posté par  . Évalué à 2.

      Merci pour cette question.
      Une autre ?

      Sinon… Personnellement mes projets sont trop récents pour avoir à gérer des versions différentes de libs externes. J'ai tendance à procéder comme virtualenv en Python, un GOPATH par projet.
      Il y a une entrée dans la FAQ :
      https://golang.org/doc/faq#get_version
      La première phrase résumant tout : "Go get" does not have any explicit concept of package versions. Versioning is a source of significant complexity, especially in large code bases, and we are unaware of any approach that works well at scale in a large enough variety of situations to be appropriate to force on all Go users"
      En gros comme le reste, on fait au plus simple tant qu'on n'a pas trouvé mieux. Avec un petit plus testé à partir de la v1.5 (current) et par défaut dans la 1.6, le vendoring https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo

      • [^] # Re: got get et version

        Posté par  . Évalué à 3.

        En gros comme le reste, on fait au plus simple tant qu'on n'a pas trouvé mieux.

        À minima rendre au moins à peu près simple le fait de déterminer une différence entre 2 workspaces ça me paraît être un minimum vital. Ça me paraît être un très gros frein à la réutilisation de code alors que go get est là pour ça.

        Je ne sais pas si docker a beaucoup de dépendance externe. Ça pourrait être intéressant d'avoir leur retour sur le langage et son outillage/environnement.

        Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

        • [^] # Re: got get et version

          Posté par  . Évalué à 1.

          Après dans la plupart des langages ça fait très peu de temps qu'on a des solutions et elles sont encore loin d'être parfaites.
          Là il y en a déjà plusieurs, la seule chose c'est qu'il faut que ça se stabilise, c'est en cours. Si quelqu'un pouvait faire un article sur le govendoringexperiment qui sera par défaut sur la 1.6…

          Ce qui reste très intéressant c'est déjà d'avoir résolu le problème du déploiement en créant un binaire statique.

          • [^] # Re: got get et version

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

            avoir résolu le problème du déploiement en créant un binaire statique.

            C'est une solution "facile". Est-ce une bonne solution (mises à jour pour corrections de bugs et de failles de sécurité dans des libs tiers…)?

            Python 3 - Apprendre à programmer dans l'écosystème Python → https://www.dunod.com/EAN/9782100809141

            • [^] # Re: got get et version

              Posté par  . Évalué à 1.

              J'ai un peu exagéré, ça ne résout pas LE problème mais un des problèmes (ce qui est déjà pas mal)…

    • [^] # Re: got get et version

      Posté par  . Évalué à 3.

      Personnellement, j'utilise gb qui fonctionne très bien et surtout ;
      - ne modifie pas les chemins d'import des dépendances
      - rassemblement toutes tes dépendance dans répertoire vendor avec un fichier manifest

      De plus, son approche workspace me convient beaucoup plus que l'approche GOPATH.

Suivre le flux des commentaires

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