• # Quelques réactions et... implémentation (existante de base !) en Kotlin

    Posté par . En réponse au journal La programmation concurrente en mode Goto. Évalué à 5.

    J'ai lu l'article, un peu méfiant (normal quand on lit quelqu'un qui se compare implicitement à Dijkstra ;)).

    Mes pensées :

    • ok, la programmation concurrente ça a toujours été bordélique, on se dit souvent qu'il y a sûrement quelque chose à améliorer ou un paradigme à inventer... donc pourquoi pas...
    • je n'avais jamais pensé à comparer les instructions "go" à des "goto", c'est une idée intéressante (mais est-elle pertinente ? (*)).
    • outre l'idéologie (la "boîte noire") et la beauté de la chose, on résout un problème clair : c'est que les exceptions remontent à l'"appelant", même celui-ci était dans un autre thread.

    (*) Tout dépend de ce qu'on veut inclure das les "boîtes noires".
    Considérant qu'une instruction "go" a juste 1 point d'entrée et 1 point de sortie dans le thread courant, celle-ci ne casse pas forcément l'abstraction "boîte noire". Tout dépend du fait qu'on considère la création de thread comme simple un effet de bord ou non. Là dessus, on peut aussi se dire qu'une bonne boîte noire ne devrait pas avoir d'effets de bord du tout (FP pure).

    Trêve de réflexions philosophiques, je me suis dit que cette idée devait être triviale à implémenter dans tout langage avec une syntaxe fonctionnelle bien conçue. En particulier, en Kotlin, en surcouche des coroutines. Donc j'ai essayé de le faire... pour me rendre compte assez vite que c'était déjà de base dans le framework... de base ou presque. Exemple :

    fun main(args: Array<String>) {
     runBlocking {
     launch(coroutineContext) {
     while (true) {
     delay(1000)
     println("coucou")
     }
     }
     launch(coroutineContext) {
     delay(3000)
     throw RuntimeException("Stop !")
     }
     }
    }

    (Ce programme quitte sur une exception au bout de 3 secondes. Celle-ci apparaît bien dans le thread main dans le backtrace.)

    Pourquoi presque ? Parce que ce n'est pas par défaut : il faut préciser le contexte coroutineContext pour avoir un comportement de type nursery. Si on ne le fait pas, la coroutine créée n'est pas enfant de la coroutine du scope extérieur, et donc une exception dans celle-là ne serait pas propagée à celle-ci.

    NJS ne prétendait pas forcément inventer une structure de contrôle complètement nouvelle, mais surtout encourager des langages qui n'autoriseraient la concurrence qu'au travers ce genre de structure. Donc ce "prior art" ne remet pas l'article en question.

    La conclusion, c'est qu'en Kotlin, avec une discipline assez légère (se forcer à n'utiliser que le contexte coroutineContext et ne pas utiliser d'autres primitives de concurrence que celles fournies dans les coroutines), on peut programmer dans le style suggéré par NJS (peut-être même pourrait-on ajouter un support dans l'IDE et dans le build system pour refuser tout programme qui ne s'y plie pas).