My team's using rust. HALP!
  
My team's using rust. HALP!
Dis, c'est quoi un·e CTO?
Alignement
 Vision globale des projets, m'assurer que les gens bossent dans le même sens même s'ils n'ont pas toutes les infos  
Priorités
 Priorités, pour permettre de l'autonomie choix des technos en plus  
Facilitateur·ice
 Enlever les obstacles pour que les gens avancent sur leurs projets sans avoir à se poser de questions  
Architecte
 toujours en collaboration avec l'équipe  
Historique Clever
 Je suis arrivé en cours de route, pas mal de choix techniques déjà faits.  
Java Java Java
 Cœur en java  
Scala, Scala? Java.
 Premières tentatives d'intégrer du scala, finalement restage sur java et réintégration dans l'API principal  
Ruby
 utilisé comme langage de script sur les VMs. Common practice à l'époque.  
NODE ALL THE THINGS
 Réécriture d'un orchestrateur from scratch. À l'époque pile la plus simple pour de l'évenementiel. Alternative à ruby pour le scripting  
Scala. A lot
 Toutes les nouvelles briques web en scala.  
(plus les à côtés)
 haskell, elixir, a little bit of go.  
 Ça a l'air un peu inefficace ça, non?
 pas tant que ça en fait, c'est des briques indépendantes, et à chaque fois on commence petit. On n'a jamais réécrit une brique pour le plaisir.  
Donc vous arrêtez scala?
 scala a toute sa place comme pile web pas en compétition avec rust sur la partie API web  
Ben pourquoi pas go alors?
 le système de type c'est fait pour aider. Même si rust et go n'ont pas les mêmes buts, rust répond mieux que go sur le marché de go (déso, pas déso).  
Déploiement facile
 Pour nous le déploiement d'une app web c'est vraiment pas un problème en revanche on doit outiller les instances et on a besoin de petits binaires faciles à packager et sans dépendances système  
"system" language
 utile dans le cadre de sozu en particulier: proche du métal. permet de travailler proprement sur la perf  
Rust && Scala, main dans la main
 même approche de la programmation: modélisation propre à l'aide du système de types découpage en fonctions, implem itérative ??? / unimplemented!. Élimination des problèmes de serde à la fin du monde  
TDD, anyone?
 Make invalid states unrepresentable. Dans le cas de rust ça inclut aussi les data races  
case class Peer(
  cidrs: List[String],
  pubkey: String,
  endpoint: String,
  keepalive: Int)
sealed trait WgCommand
case class InitConfig(…)
  extends WgCommand
case class SetPeer(peer: Peer)
  extends WgCommand
case class RemovePeer(pubkey: String)
  extends WgCommand
pub struct Peer {
    pub cidrs: Vec<String>,
    pub pubkey: String,
    pub endpoint: String,
    pub keepalive: u32,
}
struct Rgb (i8, i8, i8)
pub enum WgCommand {
    InitConfig(String, String, String, u32),
    SetPeer(Peer),
    RemovePeer(String)
}
command match {
    case InitConfig(
        ip,
        pub, priv,
        port) => …
    case SetPeer(peer) => …
    case RemovePeer(pub) => …
}
match cmd {
    WgCommand::InitConfig(
        ip, pubkey, privkey,
        port) => …,
    … 
}
trait Bidule {
    def abstractMethod(t: String): String
    def concrete(t: String): String =
      abstractMethod(t)
}
case class Machin(a: Int) extends Bidule
case class Truc(a: Int) {
    def yolo = a + 42
}
pub trait ProxyClient {
    fn front_socket(&self) -> &TcpStream
    …
}
pub struct Truc {
    pub a: u32,
}
impl Truc {
    fn new() -> Truc {
        Truc { a: 0 }
    },
    fn yolo(&self) -> u32 {
        self.a + 42
    }
}
let a = Truc::new();
let b = &a.yolo();
pub trait FromStr {
    type Err;
    fn from_str(s: &str) ->
      Result<Self, Self:Err>
}
impl FromStr for Bool {
    type Err = ParseBoolError;
    fn from_str(s: &str) -> {
        ...
    }
}
#[derive(Debug,PartialEq,Eq)]
pub struct {
    …
}
customDerive all the things
def myShinyMethod(t: String): String =
  ???
fn myShinyFunction(t: &str) -> String {
    unimplemented!()
}
def doThing(p: Param):
  Either[Error, Value] = …
fn do_thing(p: &Param) ->
  Result<Value, Error> {
    …
}
?
for {
    res1 <- op1() // yay scala 2.12,
                  // thanks Simon!
    res2 <- op2(res1)
} yield res2
fn do_things() -> Result<Value, Error> {
    let res1 = op1()?;
    let res2 = op2(res1)?;
    Ok(res2)
}
Not monadic, only for errors
Et le fonctionnel dans tout ça?
 Le modèle mémoire de rust est super top, mais assez limitant quand on a l'habitude de scala  
Persistent data structures :/
 difficile sans GC. Pas si utile que ça finalement grâce au borrow checker  
L'impératif, ça passe en fait
 avec le borrow checker ça permet d'isoler la mutabilité, et ça passe à peu près en fait. d'ailleurs en scala c'est toléré tant que ça s'échappe pas. Mais en scala c'est dur à prouver (cf la mutabilité de List)  
Closures :/
 Pour des pures lambdas c'est pas gênant, mais dès qu'on close over un bout de contexte, le borrow checker s'excite  
Async :/
 Futures. Code encore piégeux, event loop à gérer explicitement. Design pas encore bien fixé, modifications à attendre. Le multithread est jouable dans certains cas, encore une fois grâce au borrow checker  
Unboxing & spécialisation
 Pas mal de restrictions sur les génériques à cause de l'unboxing, boulot sur la spécialisation. Grosses questions sur l'inférence de type de retour  
ipml trait to the rescue
 impl trait => abstract boxed / unboxed types not ready yet  
No HKTs yet
 en cours de discussion https://github.com/rust-lang/rfcs/pull/1598 premier pas  
def mapTwice[A, F[_]: Functor](
    v: F[A],
    f: A => A
): F[A] = {
    …
}
Strings. Encore pire qu'en haskell
static str
&str
String
[u8]
[u8,4]
Vec<u8>
C'est normal
 On rajoute plus d'invariants, donc le compilo va vérifier plus de choses, mais la contrepartie c'est que plus de programmes légaux vont être refusés. On a donc un tradeoff entre plus de sécurité (moins de corner cases à gérer) et une diminution dans ce qu'on peut faire sans être emmerdé. Bénéfice relatif, tout dépend du projet, de l'équipe, …  
Ça vaut le coup de me mettre à rust?
Pour apprendre
 C'est toujours bien d'apprendre un nouveau langage basé sur des concepts nouveaux.  
Un autre regard sur des concepts du fonctionnel
 Il y a pas mal de features des langages fonctionnels qui ne sont pas fondamentalement fonctionnelles et qui ont du sens dans un contexte impératif.  
Faire du système / bas niveau en douceur
 C'est jouable et moins dangereux qu'en C, du coup ça permet de déstresser  
Pour du web?
 Pour remplacer des déploiements scala, bof sauf si contraintes particulières. Rien de bien folichon en templating, piles web pas encore bien stables. Je garde mon play, même avec de la DI :-)  
Contraintes de déploiement fortes
 RAM dépendances, système de déploiement  
Exposer simplement une lib C
 La FFI en rust c'est quand même plus simple que JNI Routage propre, typage des requêtes, interface sympa. C'est toujours mieux qu'un shell out dégueu  
Lib bas niveau / haute perf
 Plutôt pertinent pour les langages interprétés qui ont tendance à tomber en C pour avoir des perfs (node, python, ruby). Sur la JVM c'est plutôt rare #JNI  
 Pour du tooling à déployer sur des machines en support d'une appli principale. Fat binary, small footprint  
Rust is a better go than go
 Rust répond mieux que go aux use cases principaux de go. Pas vraiment grâce à sa gestion de la mémoire, juste parceque le tooling est mieux et que le langage est plus expressif.  
Code métier à déployer dans le browser
 Très bon fit avec webasm, vu qu'il n'y a pas de runtime. Gros focus de la communauté rust en ce moment  
Recap
 Langage très intéressant Tradeoffs plus violents que d'habitude Frustrant quand on est habitué à tout boxer et qu'on a un GC