5 2nov.2026 Beaucoup de Rust par-ci… Un peu de Go par-là… Saupoudrez de LLM selon vos goûts et vous aurez une bonne photographie des sujets qui préoccupent les développeurs sur l'Internet d'aujourd'hui.

Alors, n'est-ce pas le meilleur moment pour se rafraîchir l'esprit avec des langages plus discrets ? Je vous propose ici une présentation accélérée d'Elixir. Sommaire Un langage de programmation fonctionnelle Correspondance de motifs (ou Pattern matching) Module, fonctions et clauses de garde Listes et récursivité L'opérateur pipe L'exercice sympa qui utilise tout ça (ou presque) Et maintenant Un langage de programmation fonctionnelle Ceux qui ont déjà fait de la programmation orientée objet organisent principalement leur code autour d'objets et d'instances.

Cette approche a ses avantages, mais cela nécessite d'encapsuler la donnée et la gestion des changements d'état peut parfois devenir complexe. De son côté, la programmation fonctionnelle privilégie les fonctions qui, au lieu de masquer les données, transforment simplement des entrées en sorties. Elixir s'appuie essentiellement sur ce paradigme.

Correspondance de motifs (ou Pattern matching) En Elixir, le signe égal n'est pas une affectation mais plutôt une assertion. Ainsi, on n'affecte ou ne modifie la valeur que de la variable située à gauche du signe égal. À droite, la variable est remplacée par sa valeur.

Exemple avec iex, la console interactive : iex> a = 2 2 iex> 2 = a 2 iex> 1 = a ** (MatchError) no match of right hand side value: 2 Cette ligne de code échoue car elle équivaut à 1 = 2, ce qui provoque une erreur. À noter que le caractère _ sert à ignorer une valeur, ainsi : iex> [1, _, _] = [1, 2, 3] [1, 2, 3] La correspondance de motifs en Elixir est similaire à celle d'Erlang (ces deux langages utilisent la même VM). Joe Armstrong, le créateur d'Erlang, compare ce signe égal à celui utilisé en algèbre : lorsque vous écrivez l'équation x = a + 1, vous n'attribuez pas la valeur de a + 1 à x.

Cette correspondance sert essentiellement à vérifier la forme d'une valeur, à en extraire des éléments et à traiter différemment les résultats d'une opération selon qu'elle réussit ou échoue. Tout cela est un peu déroutant au début mais très puissant. Module, fonctions et clauses de garde Dès qu'un programme dépasse quelques lignes, il devient nécessaire de le structurer.

En Elixir, les fonctions nommées doivent être écrites à l'intérieur de modules : defmodule BestMovie do def ever(name) do IO.puts "Le meilleur film de tous les temps est `#{name}`." end end BestMovie.ever("La cité de la peur") #=> Le meilleur film de tous les temps est `La cité de la peur`. De son côté, la macro defp définit une fonction privée, c'est-à-dire une fonction qui ne peut être appelée qu'au sein du module qui la déclare : defmodule MonModule do def fonction_publique do fonction_privée() end defp fonction_privée do IO.puts "Je suis appelé depuis une fonction privée" end end MonModule.fonction_privée() #=> ** (UndefinedFunctionError) function MonModule.fonction_privée/0 is undefined or private. MonModule.fonction_publique() #=> Je suis appelé depuis une fonction privée En Elixir, la correspondance de motifs s'applique aux arguments des fonctions : plusieurs peuvent porter le même nom mais le langage choisira la fonction dont les motifs correspondent aux arguments.

Au moyen du mot clé when, les clauses de garde permettent d'étendre cette correspondance de motifs à des vérifications plus complexes comme la distinction des types d'arguments ou un test portant sur leurs valeurs : defmodule GuardClause do def what_is(x) when is_number(x) and x > 0 do IO.puts "#{x} est un nombre positif" end def what_is(x) when is_list(x) do IO.puts "#{inspect(x)} est une liste" end end GuardClause.what_is(99) #=> 99 est un nombre positif GuardClause.what_is([1,2,3]) #=> [1,2,3] est une liste Toutes les expressions ne sont pas autorisées dans les clauses de garde, mais seulement quelques-unes. Il s'agit d'un choix délibéré du langage pour garantir une exécution efficace. Listes et récursivité En Elixir, une liste peut être vide ou se composer d'une tête et d'une queue.

La tête (head) contient une valeur et la queue (tail) est elle-même une liste : iex> [ head | tail ] = [ 1, 2, 3 ] [1, 2, 3] iex> head 1 iex> tail [2, 3] Ainsi, une liste à un seul élément (que nous écririons habituellement sous la forme [4]) peut s'écrire comme la valeur 4 jointe à une liste vide, soit [ 4 | [ ] ]. Cette définition permet d'aborder certains problèmes de manière récursifs et donc sans s'appuyer sur une variable de boucle et/ou les traditionnels if et else : defmodule MyList do def flip([]), do: [] def flip([ head | tail ]) do flip(tail) ++ [head] # `++` permet de concaténer des listes end end MyList.flip([1, 2, 3, 4, 5]) #=> [5, 4, 3, 2, 1] # Explication pas à pas : # flip([1, 2, 3, 4, 5]) # ↳ flip([2, 3, 4, 5]) ++ [1] # ↳ flip([3, 4, 5]) ++ [2] ++ [1] # ↳ flip([4, 5]) ++ [3] ++ [2] ++ [1] # ↳ flip([5]) ++ [4] ++ [3] ++ [2] ++ [1] # ↳ flip([]) ++ [5] ++ [4] ++ [3] ++ [2] ++ [1] # ↳ [] ++ [5] ++ [4] ++ [3] ++ [2] ++ [1] # ↳ [5, 4, 3, 2, 1] Note : l'usage de ++ est moins efficace qu'une version utilisant une variable pour accumuler le résultat mais cette approche reste plus didactique pour découvrir la récursion. L'opérateur pipe Nous avons tous déjà croisé du code séquentiel où chaque étape dépend du résultat de la précédente : cart = ShoppingCart.for_user(user_id) items = Inventory.check_availability(cart) total = Pricing.calculate_total(items, tax: 1.2) L'ordre des opérations est clair, mais au final les variables intermédiaires sont là pour éviter des appels imbriqués : Pricing.calculate_total( Inventory.check_availability( ShoppingCart.for_user(user_id) ), tax: 1.2 ) Elixir propose d'écrire ce type de code d'une façon fluide et sans variable intermédiaire : user_id |> ShoppingCart.for_user() |> Inventory.check_availability() |> Pricing.calculate_total(tax: 1.2) L'opérateur |> prend le résultat de l'expression située précédemment et l'insère en tant que premier paramètre de l'appel de la fonction suivante.

L'exercice sympa qui utilise tout ça (ou presque) Maintenant que vous avez les bases, je vous propose un exercice qui m'avait bien plu lorsque j'ai découvert le langage au travers le livre de Dave Thomas : trouver un nombre compris dans un intervalle donné (ex : 1..100 dans une expression ou 1..100//1 pour effectuer une correspondance de motifs, //1 correspondant au pas). Il existe plusieurs façon de résoudre le problème mais voici ma solution : defmodule Devine do def en_tatonnant(cible, min..max//1) when is_integer(cible) and is_integer(min) and is_integer(max) and cible > min and cible < max do estimation = div(min + max, 2) IO.puts "Est-ce #{estimation} ?" guess(cible, min..max, estimation) end def en_tatonnant(cible, min..max//1) when not is_integer(cible) or not is_integer(min) or not is_integer(max) or cible < min or cible > max do IO.puts "Très drôle…" end defp guess(cible, min.._//1, estimation) when estimation > cible do IO.puts "Non, c'est plus petit… Maintenant on va rechercher entre #{min} et #{estimation}" en_tatonnant(cible, min..estimation) end defp guess(cible, _..max//1, estimation) when estimation < cible do IO.puts "Non, c'est plus grand…

Maintenant on va rechercher entre #{estimation} et #{max}" en_tatonnant(cible, estimation..max) end defp guess(cible, _, estimation) when estimation == cible do IO.puts "Mais oui, c'est bien #{estimation} 🤩" end end Devine.en_tatonnant(273, 1..1000) #=> Est-ce 500 ? #=> Non, c'est plus petit… Maintenant on va rechercher entre 1 et 500 #=> Est-ce 250 ? #=> Non, c'est plus grand… Maintenant on va rechercher entre 250 et 500 #=> Est-ce 375 ? #=> Non, c'est plus petit…

Maintenant on va rechercher entre 250 et 375 #=> Est-ce 312 ? #=> Non, c'est plus petit… Maintenant on va rechercher entre 250 et 312 #=> Est-ce 281 ? #=> Non, c'est plus petit… Maintenant on va rechercher entre 250 et 281 #=> Est-ce 265 ? #=> Non, c'est plus grand…

Maintenant on va rechercher entre 265 et 281 #=> Est-ce 273 ? #=> Mais oui, c'est bien 273 🤩 Et maintenant Vous vous doutez bien que je n'ai fait qu'effleurer le sujet mais j'ai trouvé le langage Elixir tellement singulier que je n'ai pas résisté à l'envie de vous le présenter. Je continue ma découverte de ce langage, à mon rythme ; en ce moment, j'aborde la programmation concurrente. À n'en pas douter, j'enchaînerai sur le framework Phoenix !

Aller plus loin Site officiel du langage Elixir (4 clics)