Langage Go de Google, une Ford T avec moteur Ferrari
Google a créé le langage Go pour pour pouvoir fonctionner avec les processeurs multi-coeurs actuels ce qui est difficile avec les langages actuels. Comme toujours, un nouveau langage répond à l'insatisfaction ressentie vis à vis des langages actuels. Dans ce cas, on le destinait à remplacer C++ pour la programmation de bas niveau, ce que ni Java ni C# ne peuvent faire. Mais cela ne signifie pas qu'il est effectivement utilisé pour cela. Il est amusant que les créateurs aient voulu conserver une syntaxe à laquelle les programmeurs soient habitués, celle de C, mais que la majorité utilisent Go pour remplacer Python!
Pour le concevoir, il a fait appel à plusieurs vétérans de la programmation ce qui explique la syntaxe vénérable du langage...
Fonctions modernes et syntaxe vieille de 40 ans!
- Ken Thompson. Co-auteur de Unix, créateur du langage B auquel a succédé C (par Dennis Ritchie).
- Rob Pike, a créé le système Plan 9 pour Bell.
- Robert Griesemer a contribué au compilateur JavaScript V8 de Chrome et à GCC.
Ces développeurs n'ont rien à voir avec C++, qui a été créé par Bjarne Stroutstrup sur la base du C, ce qui explique des choix de conception différents, tels que la composition à la place de l'héritage.
L'objectif de Go est de rester le plus proche possible du langage C tout en améliorant de beaucoup la productivité, et se substituer à lui.
Il s'inspire de C, Java, Pascal, Python et reprend même des caractéristiques de Scriptol!
Google nous dit dans la présentation:
"Nous affirmons que Go est un langage moderne."
Et c'est vrai quand à ses fonctionnalités, non quand à la syntaxe qui date de 1969 exactement et du langage B, et avec des emprunts à Pascal (1970)!
Il est utilisé en production chez Google depuis mai 2010, mais outre le fait qu'il remplace C++ très efficacement, il tend aussi à être utilisé à la place de Python et Ruby car sa vitesse de compilation convient au scripting, tout en produisant des binaires exécutables rapides. Il peut donc remplacer tous les langages pour des programmes en ligne de commande.
Une autre citation, par l'auteur, Rob Pike:
Le point central ici est que nos programmeurs sont des Goggleurs, ce ne sont pas des chercheurs. Typiquement ils sont plutôt jeunes, fraichement sortis de l'école, ont probablement appris Java, peut-être C ou C++, et peut-être Python. Ils ne sont pas capables de comprendre un langage brillant mais nous voulons les amener à réaliser de bons programmes. Ainsi, le langage que nous leur donnons doit être facile à comprendre et facile à adopter.
Pourquoi utiliser Go? L'expérience des utilisateurs...
L'expérience est plutôt négative chez les programmeurs individuels, ayant utilisé d'autres langages modernes. Go est principalement conçu pour une équipe où ajouter/remplacer un programmeur est récurrent. Il permet d'être rapidemment productif même pour des débutants.
Sa syntaxe et la façon dont il traite les objets le destine surtout à la programmation sur les serveurs comme remplacement de Perl, Python ou PHP. Il permet à la fois un développement rapide et des scripts véloces.
Il possède d'emblée les fonctionnalités de concurrence et un garbage collector.
Un garbage collector ne convient généralement pas pour la réalisation d'un OS, de pilotes, mais il a été spécialement optimisé pour parvenir à des pauses de moins de 100 microsecondes!
On peut l'utiliser pour réaliser des logiciels serveurs et par exemple pour construire un CMS et générer des pages HTML, un domaine où il est supérieur à Python et Java.
Il est plus simple que C++, plus adaptable que Java, plus rapide et plus sûr que Python, dispose d'une bibliothèque complète et bien conçue (coté serveur) et fournit les services requis aux applications Web, tel que WebSocket, les closures.
Et les programmes sont compilés instantanément ce qui facilite la mise au point, tout comme la description précise des erreurs éventuelles, contrairement à d'autres langages comme C++.
Une syntaxe venant du langage C
La syntaxe améliore la productivité.
- Point-virgules inutiles sauf pour séparer des instructions.
- map est une table de hâchage et fait partie du langage.
- Multiples threads qui communiquent entre eux.
- Les variables sont déclarées comme en Pascal sous la forme:
var nom type.
Ex: var x int; - break et continue peuvent spécifier un libellé.
- Le structure switch case peut comporter des tests différents comme c'est le cas en Scriptol.
- Un case peut comporter plusieurs alternatives:
case 0, 1, 2: - Une slice est une structure qui reprend une partie d'une liste et pointe sur celle-ci.
- La commande go appelle une fonction en démarrant un thread différent.
- chan (channel) est un canal pour communiquer entre goroutines (qui sont les fonctions de processus concurrents).
- Format de chaînes UTF-8.
- Les primitives sont: bool, string, int, int8 à 64 de même pour uint, byte, float32 et 64, complex64 et 128.
La technologie CSP, (Communicating Sequential Processes) gère la communication entre programmes et aide à la gestion des processeurs multi-coeurs.
Go vs. Java
Java a été conçu comme un langage pour le Web et est devenu populaire grâce à cela. Il peut fonctionner sur le serveur ou sur le poste client grâce à des applets (celles-ci sont devenues obsolètes).
Son principal intérêt est sa bibliothèque d'interface graphique très étendue.
Go comme Java permet de tester immédiatement un programme ou un script en développement, mais il produit du code binaire, donc plus rapide et compact.
Go vs C++
Même s'il reprend la même syntaxe des années 70, Go simplifie la programmation par rapport à C++.
Quelques causes d'erreurs fréquentes provenant de la syntaxe sont supprimées.
Le fonctionnement multi-thread devient simple, avec une seule commande.
Le garbage collector facilite la gestion de la mémoire.
- Il n'y a pas de classe et d'héritage. On remplace les classes par des structs et des interfaces qui sont proches des objets de JavaScript. Les objets sont étendus par composition et non pas par héritage.
- La mémoire est gérée automatiquement par un garbage-collector. En octobre 2016, il est annoncé que le nouveau GC marquait des pauses de moins de 100 micro-secondes, donc invisibles à l'utilisateur.
- Les pointeurs ont un type fixé.
- Les tableaux sont passés par valeurs et non comme des pointeurs.
- Des imports de packages comme en Java plutôt que des fichiers d'en-têtes comme en C.
- Pas de conversion de types sans passer par une fonction.
- nil remplace null.
- Le symbole de pointeur -> est remplacé par le point.
- Les incréments -- et ++ ne peuvent pas s'utiliser dans des expressions.
- Les constantes peuvent être déclarées sans type.
- new est une fonction et non pas un opérateur.
- Go ne supporte pas la généricité, a cause de tous ses inconvénients, selon les auteurs. (Ref: Esmeralda imagination).
Comparaison des syntaxes...
Go
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
C++
#include <stdio.h>
void main() {
puts("Hello, World!");
}
Go: deux déclarations équivalentes.
var i : int = 10
var i = 10
C++
int i = 10;
Go
var str = "Hello in Go"
fmt.Println(str)
C++
string str = "Hello in C++";
puts(str);
Go
const a = 1
C++
const int a = 1;
Go
var b int = 2
var x, y, z int
var i, j, k int = 5, 10 , 20
b += x
C++
int b = 2;
int x, y, z;
int i = 5, j = 10, k = 20
b += x;
Go
x := 2
C++
int x = 2;
Go
if x < 1 {
fmt.Println("ok")
}
if x = mult(y, 100); x < 1000 {
fmt.Prinfln("ok")
}
C++
if(x < 10) {
puts("ok");
}
x = mult(y, 100);
if(x < 1000) {
puts("ok");
}
Go
switch x {
case "a":
fmt.Println("a")
case "b":
fallthrough
case "c":
fmt.Println("b ou c")
default:
fmt.Println("x")
}
C++ 11
switch(x) {
case "a":
puts("a");
break;
case "b":
case "c":
puts("b ou c");
break;
default:
puts("x");
}
Go
for i:= 0; i < 10; i++ {
fmt.Println(i)
}
C
int i;
for(i = 0; i <= 10; i++)
puts(i);
Go
var i = 0
for i < 10 {
fmt.Println(i)
i += 1
}
C
int i = 0;
while(i < 10) {
puts(i);
i += 1;
}
Go
for {
if condition {
break
}
}
C++
while(true) {
if(condition)
break;
}
Go
var arr = []int { 10,20,30 }
for i, v := range arr {
fmt.Println(v)
...
}
C++ version 11
int arr[] = { 10,20,30 };
for(x : arr) {
puts(x);
...
}
La syntaxe de Go pour déclarer une fonction reste simple, celle de Rust étant inutilement compliquée et abscon.
Si plusieurs arguments sont de même type, on déclare le type une seule fois. Mais cela reste des types statiques dans les deux langages et n'offre pas le multiple dispatch de Julia.
Go
func mult(x int, y int) int {
return x * y
}
C++
int mult(int x, int y) {
return (x * y);
}
Go
func ftuple(x int, y int) (int, int) {
return x * 2, y * 2
}
x, y = ftuple(10, 15)
C++
int[] ftuple(int x, int y) {
return { x * 2, y * 2 };
}
int z[] = ftuple(10, 15);
x = z[0]; y = z[0];
Go
type Point struct {
x int
y int
}
C++
struct Point {
int x;
int y;
}
Go
package main
import ("os";"flag";)
func main() {
var s = "Démonstration"
for i := 0; i < s; i++ {
fmt.Println(s[i])
}
}
C++
#include <stdio>
#include <string>
void main() {
string s = "Démonstration";
for(i : s) {
puts(i);
}
}
Sur le plan des bibliothèques, Go va directement à l'encontre de C++, non seulement il n'y a pas de fichiers d'en-têtes, mais on peut même inclure des modules externes directement depuis un site distant, car toute l'information pour l'intégration est stockée dans les modules.
En général cela facilite la distribution des programmes, mais cela à des inconvénients. Les modules importés directement cessent d'être compatibles et obligent à réécrire les logiciels...
Polémique au sujet du nom
Lors du lancement public du langage, un ticket a été créé sur le forum du langage avec pour code d'identification issue 9.
L'auteur d'un langage totalement inconnu clame que le nom Go est déjà celui de son propre langage.
Le fait est qu'un livre a été écrit sur celui-ci, sous le titre Let's Go!
Mais ce langage s'appelle Go! et non pas go, et le mot Go appartient au domaine public: il s'agit d'un jeu de tableau chinois qui existe depuis plusieurs milliers d'années! (Et aussi le verbe "aller" en anglais).
Sites et outils pour Go