Journal The Go Programming Language

Posté par  . Licence CC By‑SA.
39
6
déc.
2015
Ce journal a été promu en dépêche : The Go Programming Language.

Sommaire

The Go Programming Language

Alan A. A. Donovan et Brian W. Kernighan

Titre de l'image

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.

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 !

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. Ca 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 2 è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'ordres générales 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.

Liens

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 impressionnante 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.

  • # GO GO GO GO

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

    Merci pour ce journal,

    j'ai testé le GO juste pour voir, grâce a ce Hors Série

    Mais je n'ai pas réussi a être convaincu, mais c'est un peu comme vi (entre autres) … si tu remontes pas en selle tout de suite … tu restes par terre et regardes galoper les autres.

    Cela n'a pas été comme python … la lumière venant d'en haut, les oiseaux , les anges, la musique … la rencontre d'un autre type (non pas Integer)

    Aussi, peuple moulesque, si vous avez découvert le langage GO et que vous vous sentez l'âme d'un évangéliste, s'il vous plaît, prenez le temps de décrire ce qu'il vous a plut dans ce nouveau langage.

    Dommage que ce bouquin soit cher, mais bon c'est comme tout les livres intéressants en informatique.

    • [^] # Re: GO GO GO GO

      Posté par  . Évalué à 10. Dernière modification le 06 décembre 2015 à 17:25.

      Je pratique ce langage depuis plus de 2 ans avec un background Java [Spring/Spring Boot] principalement.
      J’apprécie dans ce langage :
      - Sa simplicité, tout est dans le code, pas besoin d'aller voir un fichier xml pour comprendre le comportement d'un bout de code ou une injection de dépendance (un pique contre Spring)
      - Sa compilation pas de choses mystérieuses/magiques au runtime (un autre pique contre Spring)
      - Sa communauté très réactive/sympathique/compétente
      - Son outillage très complet (profiling cpu/mémoire, formatage de code, fuzzing)
      - Sa concurrence simplissime et performante (c'est un langage monte très bien en charge) grâce aux goroutines
      - Un écosystème complet avec une multitude de librairies disponibles
      - Un sobriété sur l'usage de la mémoire largement supérieur à Java (pour diverses raisons)
      - La possibilité d'écrire du code (sync.Pool) qui limite l'allocation dynamique de la mémoire, et de le tester via du microbenchmark. Ce permet de limiter l'usage du garbage collector pour avoir des applications vraiment performantes (comme l'indique Brad Fitzpatrick un des gurus de Go dans cette vidéo ou ici)

      Il y a aussi des manques dans ce langage :
      - D'un débogueur fiable et multi-plateforme (même si cela change avec Delve)
      - Les generics afin d’éviter les insertions de type qui peuvent générer des erreurs au runtime

      Bref, je pourrais en parler des heures mais le temps me manque :)

      • [^] # Re: GO GO GO GO

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

        Merci pour cette réponse claire et documentée, qui donne envie de creuser un peu plus le sujet.

        j'aime bien la partie :

        • Un sobriété sur l'usage de la mémoire largement supérieur à Java

        mouaaahahahah … trop facile

        désolé pas pu m'en empêcher, je sais pourtant que dredi c'est passé mais c'est plus fort que moi …

      • [^] # Re: GO GO GO GO

        Posté par  . Évalué à 9.

        <troll>

        Je pratique ce langage depuis plus de 2 ans avec un background Java [Spring/Spring Boot] principalement.
        J’apprécie dans ce langage

        Evidement avec ce background tu peux meme apprecier du perl
        ->[]
        </troll>

      • [^] # Re: GO GO GO GO

        Posté par  . Évalué à 3.

        • Les generics afin d’éviter les insertions de type qui peuvent générer des erreurs au runtime

        Merci pour ton analyse je la partage sauf pour les génériques où j'avoue je n'ai pas très bien compris ton point. Le problème le plus souvent adressé par les génériques en java en tout cas, c'est la réutilisation aisée de bout de code générique quelque soit le type. Or Go réponds très bien à cette problématique via « go generate » ces 2 articles en parle ici

        De plus en java le type générique est completement effacé au runtime rendant l'argument d'utilisation des génériques pour les types complexes completement caduques.

        • Sa simplicité, tout est dans le code, pas besoin d'aller voir un fichier xml pour comprendre le comportement d'un bout de code ou une injection de dépendance (un pique contre Spring)
        • Sa compilation pas de choses mystérieuses/magiques au runtime (un autre pique contre Spring)

        [hs]

        Suite à tes remarques complètement pertinentes sur spring et son sur-framework spring-boot, je voulais porter à ta connaissance le projet nuun (https://github.com/nuun-io/kernel), un projet java sur lequel je travaille depuis maintenant 2012 et qui est utilisé en production sur à peu près 50 projets.

        C'est un microkernel java léger qui vise à réinventer/alléger l'injection de dépendance dans le monde java et approfondir l'I.O.C. (comprendre aller plus loin que @MyBlackMagicAnnotation) en proposant une API full java #NOXML pour répondre aux besoins de stacks logicielles un peu ambitieuse et aux applications vraiment grosses.

        Nuun est le kernel de SeedStack ( http://seedstack.org/ ) qui a été présenté au Paris OpenSource summit. SeedStack est la stack logicielle de PSA utilisée en interne et donc opensourcée cette année.

        See https://linuxfr.org/news/le-paris-open-source-summit-arrive-et-linuxfr-org-sera-la-ossparis15#comment-1630876

        Si jamais cela te titillait de savoir comment/pourquoi ? tu peux nous rejoindre sur #nuun sur freenode.

        PS : je vais essayer de faire une dépêche pour présénter ces 2 jeunes projets nuun et seedstack.
        [/hs]

        • [^] # Re: GO GO GO GO

          Posté par  . Évalué à 2.

          Merci pour ton analyse je la partage sauf pour les génériques où j'avoue je n'ai pas très bien compris ton point.

          Effectivement, je n'ai pas été assez clair. Je vais donner un exemple très concret avec atomic.Value qui permet de partager une valeur sans aucun lock entre plusieurs goroutine et de façon performante.

          A cause d'un manque de générique, nous sommes obligés de passer interface{} (qui est le java.lang.Object de go) pour enregistrer/récupérer une valeur.
          sync.Value.Store est obligé de vérifier si le type est identique à celui enregistrer la première fois et te lancera un panic (au runtime) si ce n'est pas le même type (voir cet exemple)

          J'aurai préféré avoir une truc comme ci-dessous (et d'autant plus si cela ne reste pas au runtime comme Java) :

          var value sync.Value<[]byte>

          Pour go generate, cela reste pour ma part (c'est mon avis et c'est normal qu'il ne soit pas partagé :) ) une bidouille si tu l'utilises pour combler le manque de generics du langage.

          • [^] # Re: GO GO GO GO

            Posté par  . Évalué à 1.

            Merci je comprends mieux maintenant le besoin. En as tu parlé sur l'une des nombreuses listes de diffusion go-nuts : irc ou mailing list.
            À froid comme ça, je dirais c'est pas bien de mixer un même atomic.Value pour des type differents mais ça résoudra pas ton besoin :)

            Et si je ne me trompe pas ce n'est pas un probleme de générique puisque je ne vois pas comment ça aurait résolu ton problème ici. si jamais tu avais « var value sync.Value<[]byte> » tu ne pourrais toujours pas changer de type (i.e. passer de []byte à autre chose).
            Et dans les 2 cas tu utiliseras 2 variables. Par contre, je suis d'accord avec toi le comportement de atomic.Value est étrange.

            En ce qui concerne le « go generate », je l'utilise et je trouve la solution très pragmatique :)
            Je ne pense pas que cela soit de la bidouille d'une part parce que « go generate » fait partie intégrante de la toolbox et d'autre part les templates à installer sont de simple package go à "go getter" comme les autres (incluable donc dans git). On est en terrain maitrisé.
            Et pour terminer l'esprit de go c'est vraiment ça; ne pas compliquer le langage en utilisant un ecosystème périphérique performant :)

            • [^] # Re: GO GO GO GO

              Posté par  . Évalué à 2.

              À froid comme ça, je dirais c'est pas bien de mixer un même atomic.Value pour des type differents mais ça résoudra pas ton besoin :)
              Et si je ne me trompe pas ce n'est pas un probleme de générique puisque je ne vois pas comment ça aurait résolu ton problème ici. si jamais tu avais « var value sync.Value<[]byte> » tu ne pourrais toujours pas changer de type (i.e. passer de []byte à autre chose).
              Et dans les 2 cas tu utiliseras 2 variables. Par contre, je suis d'accord avec toi le comportement de atomic.Value est étrange.

              Je ne veux pas mixer un même atomic.Value avec des types différents mais montrer que c'est possible de le faire par inadvertance (erreur) et que la compilation ne te remontre pas cette erreur qui te pétera à la figure au runtime…

        • [^] # Re: GO GO GO GO

          Posté par  . Évalué à 4.

          C'est un microkernel java léger qui vise à réinventer/alléger l'injection de dépendance dans le monde java et approfondir l'I.O.C. (comprendre aller plus loin que @MyBlackMagicAnnotation) en proposant une API full java #NOXML pour répondre aux besoins de stacks logicielles un peu ambitieuse et aux applications vraiment grosses.

          Ça apporte quoi par rapport à HK2, Dagger ou guice ?

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

          • [^] # Re: GO GO GO GO

            Posté par  . Évalué à 1.

            Nuun est backé par guice, un composant d'injection très flexible avec d'excellentes API et SPI.

            Nuun est un peu plus qu'un moteur d'injection. Son objectif est d'être un coeur logiciel incluant l'injection de dépendance via la JSR 330, la gestion du cycle de vie d'une application et surtout permettre une extensibilité sans friction.

            HK2, Guice, Dagger sont des moteur d'injections et la configuration des injections sont à définir par le développeur à chaque fois.
            Nuun va apporter une API et des nouveaux concepts qui permettent de définir des définitions d'injection dynamiques. Je m'explique :

            Tu peux définir toutes les conventions que tu veux en les décrivant des classes java appelés des plugins. Ces plugins dialoguent avec le kernel et construisent dynamiquement la configuration des injections suivants tes propres regles.
            Par exemple, tu peux décider que toutes les classes implémentant une interface suffixées par *BusinessRule sont injectés dans cette interface.

                public interface ShippingBusinessRule {
                   // methodes
                }         
                public class ColissimoShipping implements ShippingBusinessRule {
                  // implementation des methodes
                }
            

            à n'importe quelle endroit de ton application tu pourras te servir

                @Path("/checkout")
                public class CheckoutResource {
            
                  @Inject
                  ShippingBusinessRule businessRule;
            
                  public void processCommand () {
                      businessRule.process(command)
            
                  }
            

            Nuun te permet de te créer ta boite à outils avec tes propres opinions et sans dépendre d'autres librairies. Les conventions ne sont pas forcément basé sur des annotations comme c est le cas dans cet exemple très simple. Des choses plus élaborés sont possibles, par exemple dans seedstack (qui utilise nuun comme coeur) nous avons implémentés un plugin de moteur complet de transactions, un framework pour faire du DDD, un moteur de validation et pleins d'autres choses, et tout ça sans xml et sans annotationporn voir ici http://www.seedstack.org.

            • [^] # Re: GO GO GO GO

              Posté par  . Évalué à 3.

              J'aime bien utiliser simplement des moteurs d'injections parce que je les comprends, ils ne sont pas trop difficile à implémenter (après le faire de manière performante et avec quelques tricks pour le développeur c'est différent).

              J'aime bien ne pas avoir d'annotation dans mes beans, mais pour cela j'utilise simplement les solutions d'injection « par méthode » des injecteurs (comme ce que fais beaucoup dagger). C'est très simple à comprendre et ça permet de tout gérer par injection y compris du code qui ne t'appartient pas.

              Ça marche avec n'importe quel injecteur (même spring) et tu as toute la souplesse que tu veux.

              Je n'ai jamais travaillé avec des systèmes qui soient tellement gros avec tellement de choses à injecté que ça me pose problème.

              Par contre j'ai une question du coup. Comment fais-tu pour reconfigurer ton injection ? Il est important pour moi de pouvoir :

              • configurer l'injection à partir de la configuration de mon application
              • configurer l'injection pour injecter des mocks lors de mes tests

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

              • [^] # Re: GO GO GO GO

                Posté par  . Évalué à 0.

                Je suis comme toi j'aime bien utiliser des choses que je comprends :) L'intérêt des moteurs d'injection comme guice, hk2 , jodd, et SilkDi (le petit nouveau) c est justement d'être simple et compréhensible lorsque tu codes une application. tu sais ce que tu fais ça compile, c'est la classe.

                Comme toi je n'aime pas l'annotationporn mais si j'utilise des annotations il faut que ce soit les miennes avec des comportements que j'ai décidé.

                Je te rejoins tout à fait dans ton raisonnement, le problème que je cherchais à résoudre est celui-ci :

                1) Un développeur qui créé souvent des applications avec souvent les mêmes composants à injecter va vouloir les réutiliser simplement sans copier/coller la configuration à chaque fois. Le coté déclaratif plutot qu'impératif fait que tu ne te préoccupes plus de la configuration. Les conventions que tu as décidé (exemple plus haut) seront valable sur tous tes projets, tu commences à coder sans penser à la configuration du moteur d'injection.

                2) Dans le cadre d'une entreprise (plutot une corporation) avec > 1000 développeurs avec toutes les problématiques qui vont avec (niveaux des developpeurs hétérogènes, développeurs interne vs externe, SSII aux forfaits, offshore, plusieurs langues etc ) → Il faut prévoir des buildings blocs suffisament autonomes pour que les développeurs se concentrent sur le code métier et non le « code technique » . Avoir un socle technique permet de standardiser sans alourdir et d'avoir moins d'erreur

                C'est dans cet esprit que respectivement nuun et seedstack ont été créé. Pour une application classique, nuun est aussi utilisable tu codes juste ton module Guice tu lui colle un @Install dessus et ça roule. Une dernière chose, nuun est compatible guice, spring, hk2, jodd etc etc car il wrap le moteur d'injection. Cela veut dire que tu peux utiliser au sein d'une même appli de la conf spring, guice, hk2 et Jodd (ce sont des exemples que je prépare pour la documentation)

                Par contre j'ai une question du coup. Comment fais-tu pour reconfigurer ton injection ? Il est important pour moi de pouvoir :

                configurer l'injection à partir de la configuration de mon application
                configurer l'injection pour injecter des mocks lors de mes tests

                Pour reconfigurer l'application est ce que tu peux me donner un exemple précis ? Mais comme ton plugin est du code java tu peux rajouter les regles de reconfiguration que tu veux ou alors utiliser un autre plugin ton application fonctionnera juste différement. Autre chose, Nuun supporte les qualifiers de la JSR330 ce qui veut dire que pour tu peux qualifier ton injection dans notre exemple plus haut.

                   @Inject @Name("colissimo") //@Colissimo est aussi possible
                   ShippingBusinessRule colissimoShipping; //  ColissimoShipping sera injecté 
                

                Pour les mocks, c est simple tu peux déclarer des bindings d'override (au cas par cas) qui vont faire qu'en cas de test tu utiliseras ton Mock à la place de la vraie implémentation, c est un cas que j'ai pris en compte dès le départ étant moi même friand de Mock.

    • [^] # Re: GO GO GO GO

      Posté par  . Évalué à 7.

      Je ne sais pas s'il faut évangéliser ce langage. Le livre est justement très clair là dessus (contrairement à des tutos ou blogs), on bénéficie d'un langage simple et particulièrement facile à prendre en main mais il faut aimer et arriver à en tirer partie. Il n'y a pas de miracle c'est du brut, un string reste une suite de bytes len("mémé") == 6 sauf si on lui demande explicitement de le traiter en []rune, les goroutines engendrent facilement des "data race" etc… On est vite refroidi !
      Je comprend que tu ne retrouve pas le côté magique de python où on peut coder en recopiant ce que qu'on a écrit sur la feuille de brouillon. Personnellement je suis content de retrouver le plaisir du C avec un peu de sucre pythonique plutôt que l'inverse.
      Pour ceux qui se posent la question, le gros avantage c'est qu'il est vraiment facile d'essayer. Au pire on ne perdra pas beaucoup de temps.
      Le piège c'est qu'on a tout de suite envie d'essayer sur des programmes ardus, genre besoin de performance ou de multitache, alors que quand on découvre python on a plutôt tendance à l'essayer avec des scripts. Mais on s'en sort, la communauté Go aime bien les problèmes tordus et ne culpabilise pas de s'amuser à chercher la performance dès le départ :-)

      • [^] # Re: GO GO GO GO

        Posté par  . Évalué à 4.

        les goroutines engendrent facilement des "data race" etc… On est vite refroidi !

        Ah oui, j'oubliai le détecteur de race condition. Pour en avoir détecter plusieurs, c'est vraiment un outil qui est très utile.
        Pour l'activer, il suffit de compiler le binaire avec l'option -race.
        Le détecteur de race condition remonte uniquement des vrais positifs (il peut donc en laisser passer), donc ils faut toujours prendre au sérieux les alertes remontées (elles sont remontées dans la STDERR via une stack trace des deux goroutine impliquées et qd elles ont été créées).

        Autre point, le fait de l'activer, cela va consommer en terme de mémoire et d'usage CPU. Donc, on :
        - doit passer tous ses tests unitaire/microbenching avec le détecteur activé et cela dès le début du projet.
        - peut imaginer l'activer sur une partie de votre cluster.

  • # Pas de magie noire

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

    Ah la vache, il y aurait un coté Perl dans Python ;-)

  • # Outils

    Posté par  . Évalué à 6.

    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.

    Bonjour,
    Si je comprends bien : vous êtes passé de Go à Python à cause des outils de formatage et vérification de code, et de refactoring.
    Vous connaissez bien Python donc j'ai du mal à croire que nous ne connaissiez pas un outil comme PyCharm sinon testez-le ;)

    • [^] # Re: Outils

      Posté par  . Évalué à 2.

      PyCharm est un IDE. Hors l'auteur a l'air d'apprécier les outils "à la unix", ce que j'interprète comme des outils simples en ligne de commande ne faisant qu'une chose.

      • [^] # Hors ≠ Or

        Posté par  . Évalué à 10.

        Hors --> Or

        Je me permet de signaler cette faute car je la lis de plus en plus souvent. Le projet Voltaire propose la règle suivante :

        Vous pouvez remplacer le mot par « et » ? Il s’agit alors de la conjonction de coordination « or ».
        Dans le cas contraire, il convient d’écrire « hors », lequel signifie « en dehors de ».

        Il avait rendez-vous ce matin, or il ne s’est pas présenté. = Il avait rendez-vous ce matin, et il ne s’est pas présenté.

        mais

        Ce matériel est hors d’usage. ≠ Ce matériel est et d’usage.

      • [^] # Re: Outils

        Posté par  . Évalué à 3.

        Je ne passe pas au Go pour les outils mais pour des besoins particuliers. Les outils sont un avantage qui pourrait prendre de plus en plus d'importance mais je ne changerai pas d'IDE pour ça justement.
        Et pour répondre en même temps au côté black magic, j'ai remarqué que plus on connaît un langage (comme python), plus on le pousse dans ses retranchements pour s'apercevoir enfin que l'on a perdu en simplicité. Les IDE comme pycharm se retrouvent vite dépassés si on abuse du côté dynamique du langage. La rigidité de Go n'a pas été décidée au hasard, c'est justement pour que n'importe quel développeur (soit-même en particulier !) qui passe par là s'y retrouve, quelque soit ses outils.

        Au niveau du formatage, c'est bluffant, on aime déjà le côté propre de Python qui impose l'indentation, mais à la main (l'IDE ne peut pas deviner si j'ai terminé mon bloc par erreur ou pas). La on tape un peu n'importe comment et hop un coup de gofmt à l'enregistrement et on a un code propre comme pas deux.

        Je pense que ceux qui aiment PyCharm apprécieront d'autant plus ces possibilités. Le langage a été conçu pour ça.

        • [^] # Re: Outils

          Posté par  . Évalué à 3.

          La on tape un peu n'importe comment et hop un coup de gofmt à l'enregistrement et on a un code propre comme pas deux.

          J'aime bien le formatage gofmt, mais j’apprécie beaucoup plus celui de goimports qui va :
          - faire le formatage de "base" de gofmt
          - enlever les imports inutilisés (sinon erreur de compilation)
          - classer par ordre alphanumérique et grouper les dépendances externes

          • [^] # Re: Outils

            Posté par  . Évalué à 2.

            Et voilà, à force d'utiliser un IDE Vim, j'avais oublié que c'est goimports que j'utilise aussi :-)
            Apparemment c'est incroyable le gain qui a été gagné en vitesse de compilation du fait d'interdire les imports inutiles.

            • [^] # Re: Outils

              Posté par  . Évalué à 1.

              Je n'ai jamais vérifié comment fonctionne exactement go get mais je pense que d'enlever les imports non utilisés doit aussi faciliter la tâche de l'analyseur pour descendre les sources et ses dépendances.

  • # Juste de la sorcellerie

    Posté par  . Évalué à 1.

    J'ai un peu de mal à comprendre les gens qui s'excitent en parlant de Go. Particulièrement le duck typing me semble extrêmement dangereux. On perd énormément niveau sécurité du typage.
    Après, on gagne comparé à python que du code exécutable est déjà fonctionnel de A à Z …

    • [^] # Re: Juste de la sorcellerie

      Posté par  . Évalué à 2.

      On perd énormément niveau sécurité du typage.

      Ce qu'il faut savoir ce que Go n'est pas vraiment du duck typing car la validation est faite à la compilation et non runtime.
      Donc l'erreur sera détectée à la compilation avec une erreur détaillée.

      • [^] # Re: Juste de la sorcellerie

        Posté par  . Évalué à 2.

        On va dire que c'est du duck typing statique.
        Une fonction attend comme paramètre un animal qui sait faire coin-coin et non un animal qui soit un canard. Donc tout animal qui sait faire coin-coin peut passer. Ce qui rend le code léger en Go c'est que l'animal qui fait coin-coin n'a pas besoin de spécifier qu'il ressemble à un canard, il implémente juste la fonction coin-coin.
        La vérification est faite à la compilation donc la sécurité du typage est conservée et on bénéficie des outils associés.
        Je ne sais pas pourquoi le duck-typing devrait être considéré comme dynamique. Je pense que c'est parce que le terme est venu de python.

        • [^] # Re: Juste de la sorcellerie

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

          Pour le statique on appelle ça le typage structurel.

        • [^] # Re: Juste de la sorcellerie

          Posté par  . Évalué à 2.

          Néanmoins, que se passe-t-il si deux interfaces demande l'implémentation d'une fonction avec le même nom ?

          • [^] # Re: Juste de la sorcellerie

            Posté par  . Évalué à 1.

            Jamais testé.
            Mais je pense que les structures implémentant la fonction des deux interfaces peuvent être vue comme l'une ou l'autre interface.

            • [^] # Re: Juste de la sorcellerie

              Posté par  . Évalué à 2.

              Du coup, quelle est la solution conseillée, si l'on veut implémenter InterfaceA et InterfaceB qui partagent une fonction f pour un type T, mais que les deux implémentations devraient être différentes ?

              • [^] # Re: Juste de la sorcellerie

                Posté par  . Évalué à 1.

                Tu peux donner un exemple, je suis pas sûr de comprendre ce que tu veux dire…

              • [^] # Re: Juste de la sorcellerie

                Posté par  . Évalué à 6.

                Je répond avec de la magie noire et puis je sors … (vous avez le droit de "moinsser").

                En perl6:

                role go-game {
                  multi method move (@truc){
                    say "move";
                  }
                }
                
                role chess-game {
                  multi method move ($pouet){
                    say "pouet";
                  }  
                }
                
                class plateau does go-game does chess-game {
                  has $.xrows;
                  has $.ycols;
                }
                my $toto = plateau.new;
                $toto.move(<1 2 3>); # move
                $toto.move(4); # pouet
                

                … Retourne dans sa hutte de sudation manger ses champignons qui font rire …

              • [^] # Re: Juste de la sorcellerie

                Posté par  . Évalué à 1.

                A mon avis, tu l'as dans l'os :) (ou faut que j'y réfléchisse plus mais je suis fainéant ce soir :) )
                Il faut bien comprendre que dans Go, il y a des trucs bien dégoutant mais aussi des trucs super intéressant.
                Il faut faire la balance pour voir si ce langage peut répondre à vos problématique/besoins ou pas.

Suivre le flux des commentaires

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