• [^] # Re: Notation do

    Posté par . En réponse au journal Compilateur et Monad Reader. Évalué à 5.

    Mmh, oui. C'est une question pertinente, sauf que si la syntaxe existe, c'est parce qu'elle permet de simplifier de manière élégante les multiples binds imbriqués.

    faire_un_calcul_complexe x = do 
     a <- premiere_etape 
     deuxieme_etape
     c <- troisieme_etape a
     return (a,c)

    Qui est quand même bien plus simple que la même chose avec des binds (lisibilité, et le code facilement modifiable) :

    faire_un_calcul_complexe x = 
     premiere_etape >>= (\a -> 
     deuxieme_etape >> 
     troisieme_etape a >>= (\ b -> 
     return (a,c)))

    La solution, c'est de faire des fonctions très simples, pour que ce soit toujours raisonnable, sauf que dans le cadre d'un compilateur, quand tu veux traduire une opération, la manière naturelle de décrire un while va être triviale avec la notation do (alors que sans, on va utiliser pleins de >> qui ne feront que « décorer » le code de manière inutile) :

    compile (While e c) = do
     cond <- makeLabel "COND"
     body <- makeLabel "BODY"
     jump cond
     printLabel body
     compile c
     printLabel cond
     compileExpr e
     jumpIfNonZero body

    Qui se comprend en regardant la « traduction assembleur »

    [While e do c]
     jmp .COND
    .BODY
     [c]
    .COND
     [e]
     popq %rax
     cmpq 0,ドル %rax
     jne .BODY
    

    La notation do permet de conserver la même « forme » de traduction, ce qui est pratique à la fois pour la lecture (compréhension) et la modification (on peut facilement permuter deux lignes si on a loupé un truc).