Gleam est un changement

Posted on Oct 4, 2024

J’en parle partout, j’aime de plus en plus programmer en Gleam.run.

C’est un relativement nouveau langage. La version 1 est sortie en mars 2023, mais c’est un peu moins de 10 ans de developpement au total.

Qu’est-ce que Gleam ⭐?

Gleam is a friendly language for building type-safe systems that scale! (source: gleam.run)

Ou suivant les mots de lpil, son créateur:

Gleam is Go ideas but from the perspective of a FP nerd instead of a C nerd (source: Discord Gleam)

Un langage relativement simple, fonctionnel, type-safe et donc statiquement typé et qui fonctionne sur la machine virtuelle d’Erlang mais peut aussi se convertir en Javascript.

Par simple j’entends un nombre restreint d’instructions possibles, comme on pourrait avoir avec Go, mais avec des inspirations bien plus larges. En quelques minutes on peut sans trop se tromper, énumérer tous les mots clefs du langage et de ses datastructures.

Est-ce que c’est bien ? Pour moi oui, parce que j’aime la simplicité.

A quoi ça ressemble ? Ca:

import gleam/io
import gleam/option

pub fn main() {
  let name = "Cédric"
  io.println("Hello, " <> name <> "!")

  let reward = case name |> get_reward {
    Some(val) -> val
    // Pas de chance, 0 si rien
    None -> 0
  }

  io.println("Tu as gagné " <> int.to_string(reward))
}

// Il n'y a pas de keyword `return`, la dernière ligne est un return automatique
fn get_reward(name: String) -> Option(Int) {
  case name {
    "Cédric" -> Some(10)
    _ -> None
  }
}

En prime, le compilateur sert aussi de LSP et de linter. On peut penser au code sereinement, et coder sans tooling supplémentaire.

La première fois que j’ai vu ce langage, j’ai tout de suite accroché. Je me suis dit, comme beaucoup: “Mais c’est quoi ce truc ? Mais il est parfait dans la syntaxe !”. L’expressivité frappe au premier coup d’oeil.

Et puis après j’ai moins aimé quand il fallut se passer des if/else et des boucles 😆. Je commence à m’en sortir.

Une découverte de la programmation fonctionnelle

Gleam est le premier langage fonctionnel que j’ai vraiment pratiqué et ce n’était pas sans difficulté. J’en ai encore. Penser fonctionnel c’est abandonner ce que j’ai toujours appris : la POO et donc la programmation avec des side-effects (ou du moins le plus possible).

Aucun objet, seulement des types très expressifs et des fonctions qui acceptent des arguments. C’est aussi abandonner les données mutables pour de l’immutabilité. Aucune variable ne peut être reassigné après assignation. Juste ça, c’est un gros changement de paradigme. Ce n’est évidemment possible que pour des langages qui font de la tail-optimization. Gleam en est un.

Je découvre donc ce monde à part, sans boucle mais avec de la recursion, sans condition mais avec du pattern matching, etc. C’est plutôt déroutant et amusant. Je remets tout en question. Je découvre des patterns super intéressants.

Mais c’est surtout une introduction douce à la programmation fonctionnelle. Depuis j’explore un peu Ocaml, Roc, Elm, etc. C’est, je trouve, dans ma code au quotidien.

Une découverte de BEAM

Au début je n’étais pas très intéressé par BEAM, la VM qui fait tourner Erlang. Tout ce que j’en savais pouvais se réduire à :

  • Actor Model
  • Concurrence
  • Années 80

Peu de chose, beaucoup de vérités incomplètes. Je ne m’étais jamais vraiment interessé à BEAM, parce qu’il faut se le dire, c’est cantoné à Erlang et plus récemment Elixir. Deux technos dont je suis resté hermétique pour le moment.

Il faut voir BEAM comme une VM qui gère la concurrence nativement avec un système de messages passés à des fonctions (actors), qui exécutent le code de manière asynchrone, et sans faire paniquer tout le programme en cas d’échec. Cette isolation rend les programmes résilients.

Mais la vraie distinction de ce modèle de concurrence, c’est l’objectif. Là où Go par exemple maximise le débit de tâches, avec une nombre de requêtes par seconde élevé pour du web, BEAM fait moins bien mais avec une latence par tâche plus stable. L’écart-type du temps de la latence est réduit, très stable même sous une forte charge.

Ma découverte de BEAM reste limité pour l’instant. Je ne peux en dire bien plus.

Un langage pour du backend et du front-end.

Oui, Gleam compile vers JavaScript donc il peut faire du front-end…et du backend soit en JS soit en Erlang.

On peut soit faire du JavaScript natif classique avec des bindings disponibles, soit faire ses bindings directement depuis d’autres librairies JS, soir utiliser l’excellent Lustre, framework front-end inspiré par Elm mais plus sympathique.

On retrouve la recette qui a fait que JavaScript est ce qu’il est aujourd’hui, mais avec la force de Gleam : être un langage fiable.

Par fiable j’entends statiquement typé, même si c’est est fait par inférence. C’est la direction qu’a pris l’écostystème JS avec TypeScript de Microsoft, mais aussi les projets comme ReasonMl, ReScript, PureScript, js_of_ocaml, etc…

Le gros avantage de Gleam sur les options cités, c’est que je le préfère. Je n’aime pas TypeScript, et son typage n’est vraiment pas fiable. Cela reste une surcouche à Js sans grand changement de design.

ReasonMl est mort, ReScript est mort, PureScript trop Haskell pour moi. J’ai besoin d’un langage avec des parenthèses. Et puis surtout, j’ai assez confiance qu’on peut très rapidement comprendre mon code en Gleam grâce à la simplicité du langage.

Un langage riche

Du fait que l’on peut assez facilement faire des bindings depuis Js ou Erlang, Gleam n’est pas du tout isolé comme le serait un autre nouveau langage partant de zéro. Beaucoup de libraries sont déjà sur ce principe, un portage d’Erlang ou de Js.

Riche ne veut pas pour autant dire farfelu. Il existe un package particulier pour les serveurs HTTP (Wisp) base sur un package TCP (mist), un principal framework frontend (Lustre), une bonne std lib, etc… Vous préférez utiliser un runtime Js pour votre serveur, qu’Erlang ? Glen s’en charge avec une API proche de Wisp. Les principaux packages sql ont des bindings Erlang et Js. On n’est pas dans le cas de NPM avec des packages pour tout et rien à la fois, dupliqués à l’infini.

En fait, pour mon usage - du web - je n’ai pas trouvé de package qui me manquait vraiment. Evidemment, il n’y aura pas de librairie pour une base de donnée un peu spécifique, mais pour du SQL classique, il y a ce qu’il faut. Il y a même des bindings pour deno serve, React, etc… Et il est assez facile de porter soi-même des librairies tierces JS sur Gleam, du moment qu’on garde la target sur javascript.

Un retour en arrière difficile

Le plus compliqué avec Gleam, c’est de faire autre chose que du Gleam. Diffile de revenir vers un langage avec un système de type moins bien pensé, et même avec un écosystème général moins bon.

Je ne parle pas de Go, qui est juste “ok”, je pointe directement PHP, langage que j’affection tant mais aux décisions parfois si…criticables.