\include{parameters}
\usetheme{Madrid}
\usepackage[french]{babel}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{bortzmeyer-utils}
\usepackage{xspace}

\title{Le langage de programmation Go}
\author{Stéphane Bortzmeyer\\~\texttt{<stephane+enac@bortzmeyer.org>}}
\date{19 avril 2011}

%\setlength{\parskip}{1ex plus 0.5ex minus 0.2ex} 
% \setlength{\parskip}{15pt} 
\setlength{\parskip}{15pt plus 10pt minus 10pt} 

\begin{document}

\maketitle

\begin{frame}
  \titlepage
\end{frame}

\begin{frame}[fragile]
\frametitle{Exposé libre}
 Ce document est distribué sous les termes de la GNU Free
      Documentation License \url{http://www.gnu.org/licenses/licenses.html#FDL}.
 Permission is granted to copy, distribute and/or modify this document
      under the terms of the GNU Free Documentation License, Version 1.2
      or any later version published by the Free Software Foundation;
      with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.  
\end{frame}

\begin{frame}
\frametitle{Pourquoi parler de Go~?}

\begin{enumerate}
\item Situé sur un créneau où il y a peu de langages concurrents,
\item Robert Griesemer, Rob Pike, Ken Thompson, Ian Taylor, Google\ldots
\end{enumerate}

\end{frame}

\begin{frame}
\frametitle{Positionnement de Go}

\only<1-2>{Il existe des zillions de langages de programmation\ldots
}

\only<2-3>{Certaines familles sont très encombrées (langages
      fonctionnels: Haskell, Erlang, famille ML\ldots)
}

\only<3-4>{Go est sur le créneau des langages « systèmes et réseaux »,
où il n'y a guère que C et C++ (et Erlang ?). La précédente tentative sérieuse de
détrôner C était D (peu de succès).
}

\only<4-5>{Go est donc positionné comme langage de relativement bas
niveau. Ce n'est pas Python. Ce n'est pas Haskell.
}
\end{frame}

\begin{frame}[fragile]
\frametitle{Au commencement, était Hello, World}
\begin{info}
package main

import ("flag"; "fmt"; "os";)

func main() { 
   if flag.NArg() != 1 {
      fmt.Printf("Usage: program name\n");
      os.Exit(1);
   }  
   fmt.Printf("Hello, %s\n", flag.Arg(0)); 
} 
\end{info}
\end{frame}

\begin{frame}
\frametitle{Points importants du langage}
\begin{enumerate}
\item<2-> Parallélisme (les \foreign{goroutines}),
\item<3-> Inférence de types,
\item<4-> Pas orienté objet (mais une fonction peut être attachée à un type),
\item<5-> Pas d'exceptions (mais les fonctions peuvent renvoyer
   plusieurs valeurs et il existe un mécanisme de \foreign{panic/recover}),
\item<6-> Vues (\foreign{slices}) sur les tableaux,
\item<7-> Et bien d'autres choses\ldots
\end{enumerate}
\end{frame}

\begin{frame}[fragile]
\frametitle{Parallélisme}
Une des principales raisons de la conception de Go, selon les auteurs.

Toute fonction peut être exécutée en parallèle avec le
mot-clé \computer{go}~:
\begin{info}
go coffee_machine(chan_machine);
\end{info}
Très pratique pour les serveurs réseaux. Ici, un serveur echo~:
\begin{info}
        for {   // ever...
                conn, error := listener.AcceptTCP();
                if error != nil {
                     ...
                     go handle(conn);
                }
                // Prêt pour le client suivant
\end{info}
\end{frame}

\begin{frame}[fragile]
\frametitle{Canaux de communication}
Les goroutines communiquent par des canaux \emph{typés}.

\begin{info}
func coffee_machine(c chan bool) { 
   // Do something
   c <- true;
} 
// Dans une autre goroutine:
result <- chan_machine;
\end{info}
\end{frame}

\begin{frame}
\frametitle{Autre possibilités sur les canaux}
\begin{itemize}
\item Les canaux sont synchrones par défaut mais on peut les rendre
   asynchrones en indiquant la taille du tampon,
\item On peut, avec \computer{select}, écouter sur plusieurs canaux en
même temps.
\end{itemize}
\end{frame}

\begin{frame}[fragile]
\frametitle{Inférence de types}
Go est typé mais il n'est pas indispensable de déclarer les variables.
\begin{info}
conn, error := net.Dial("tcp", "", "whois.nic.fr:43");
\end{info}
Et \computer{conn} sera de type \computer{net.Conn}, sans avoir eu
besoin de le déclarer, car c'est ce que
renvoie \computer{net.Dial}. Ce type sera vérifié~:
\begin{info}
whois.go:30: invalid operation: conn + 4 (type net.Conn + int)
\end{info}
\end{frame}

\begin{frame}[fragile]
\frametitle{Pas orienté-objet}
Ce n'est plus à la mode.

Mais on peut attacher une fonction à un type.
\begin{info}
// Définition
func (t *Twitter) FriendsTimeline() (string, os.Error) {
...
// Utilisation
tw := twitter.NewTwitter(*username, *password);
timeline, error := tw.FriendsTimeline();
os.Stdout.WriteString(timeline);
\end{info}
\end{frame}

\begin{frame}[fragile]
\frametitle{Pas d'exceptions}
Les auteurs les voient comme une structure de contrôle dangereuse.

Mais :
\begin{itemize}
\item Fonctions multi-valuées :
\begin{info}
file, status := os.Open(filename, os.O_RDONLY, 0)
if status != nil {
      fmt.Printf("Cannot open \"%s\": %s\n", filename, status.String())
}
\end{info}
\item Mécanisme \foreign{panic/recover}, moins général :
\begin{info}
func clean() {
      status := recover()
      /* Do something */
...
defer clean()
...
panic("Something is horribly wrong")
\end{info}
\end{itemize}
\end{frame}

\begin{frame}[fragile]
\frametitle{Une vue sur le tableau}
Les tableaux sont assez rigides et fixes.

Mais il y a les vues (\foreign{slices}) !

En Go, on utilise presque toujours une vue et pas le tableau
sous-jacent.

\begin{info}
binary.BigEndian.PutUint16(result[4:6], packet.Qdcount)
// result est le tableau, result[4:6] une vue (pas une copie)
\end{info}

\end{frame}

\begin{frame}[fragile]
\frametitle{Interfaces}
Go, comme Java, a des interfaces : un ensemble de fonctions que doit
mettre en \oe{}uvre un type, pour pouvoir être utilisé.

Très utilisé dans les bibliothèques. Exemple
dans \computer{io} :
\begin{info}
/* Un type qui a une fonction d'écriture. Cela peut être un fichier,
une prise réseau, une chaîne de caractères, etc */
type Writer interface {
    Write(p []byte) (n int, err os.Error)
}
/* Et ensuite : */
func NewBufferedWriter(wr io.Writer) *BufferedWriter
/* Permet de ``bufferiser'' tout io.Writer */
\end{info}
\end{frame}

\begin{frame}
\frametitle{La bibliothèque standard}
Elle est très riche :
\begin{itemize}
\item Crypto
\item Expressions rationnelles
\item Réseau (et protocoles comme HTTP)
\item XML
\item Grands entiers
\item mais pas encore de moyens standards de parler à un SGBD
\item et pas grand'chose encore question interface utilisateur\ldots
\end{itemize}
\end{frame}

\begin{frame}[fragile]
\frametitle{Exemple bibliothèque : XML}
Accès aux données du VéloStar de Rennes, KR (Keolis-Rennes). Le
paquetage XML utilisé la \emph{réflexion} de Go :
\begin{info}
type Station struct {
	Id             int
        ...
	Bikesavailable int
...
type ApiKR struct {
	Request string
	Answer  Answer
}
...
result := ApiKR{}
error := xml.Unmarshal(buffer, &result)
fmt.Printf("Bikes available: %d\n",
          result.Answer.Data.Station.Bikesavailable)
\end{info}
\end{frame}

\begin{frame}
\frametitle{Autres bibliothèques}
\url{http://godashboard.appspot.com/package}

Qualité variable...

Déjà un programme standard d'installation, goinstall
\end{frame}

\begin{frame}
\frametitle{Mises en \oe{}uvre}
\begin{itemize}
\item gc, le compilateur natif original. Pour Linux, FreeBSD et MacOS X. Génère
du code pour amd64, i386 et ARM. Les goroutines sont mises sur des fils du
système sous-jacent, selon la demande (il n'y a pas de correspondance univoque).
\item gccgo, désormais inclus dans gcc (depuis la 4.6).
\item erGo, écrit en Go, non libre, sur Windows.
\end{itemize}
\end{frame}

\begin{frame}
\frametitle{Problèmes et limites}
\begin{itemize}
\item Nom incherchable dans Google,
\item Langage (et environnement) pas encore stabilisé, tout change
tout le temps (il y a même un programme spécial pour mettre à jour les
sources, gofix),
\item Manque encore de bibliothèques \emph{stables} pour des choses comme
l'accès aux SGBD,
\item Langage de bas niveau (et c'est fait exprès), donc on n'essaie
pas de masquer la machine,
\item Les chaînes de caractères sont en fait des chaînes d'octets
(pénible pour Unicode, où on doit travailler avec des tableaux d'entiers). 
\end{itemize}
\end{frame}

\begin{frame}[fragile]
\frametitle{Idiosyncrasies}
\begin{itemize}
\item Variable non utilisée ? C'est interdit...
\begin{info}
hello.go:10: name declared and not used
\end{info}
\item Allocation mémoire avec \computer{make} :
\begin{info}
value := make([]byte, 1024)
\end{info}
\end{itemize}
\end{frame}


\begin{frame}
\frametitle{Un serveur de noms en Go}
Grong \url{http://github.com/bortzmeyer/grong} est un serveur de noms
faisant autorité. 

Il est séparé en deux parties, un \emph{frontal} qui analyse les
requêtes entrantes et génère des requêtes sortantes correctes. Et
un \emph{dorsal} qui produit la réponse à partir de la
requête. Plusieurs dorsaux différents sont possibles comme un serveur
AS112 ou bien un serveur qui renvoie au client l'adresse IP du
résolveur.

\end{frame}

\begin{frame}
\frametitle{Implémentation de Grong}
Une fonction d'écoute pour TCP et une pour UDP, toutes les deux
lancées en goroutines.

Chacune lance ensuite une goroutine par requête (UDP) ou par connexion
(TCP).

Avec les goroutines, écrire un serveur réseau est un plaisir.
\end{frame}

\begin{frame}
\frametitle{Autres exemples de DNS en Go}
[Développés à SIDN]

\begin{enumerate}
\item GoDNS, une bibliothèque \url{https://github.com/miekg/godns}
\item Funkensturm, un relais DNS (capable par exemple de signer à la
volée) \url{http://www.miek.nl/blog/archives/2011/01/23/funkensturm_a_versatile_dns_proxy/index.html}
\end{enumerate}
\end{frame}

\end{document}
