❌

Vue lecture

Découverte du langage Elixir

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

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 !

Commentaires : voir le flux Atom ouvrir dans le navigateur

  •  

Journées Open Food Facts 2026 - 13/14 novembre - Paris

Open Food Facts, la base de données ouverte des produits alimentaires, tiendra le vendredi 13 et samedi 14 novembre 2026 ses journées de communauté.

Vous êtes cordialement invité·e à venir découvrir le projet et sa communauté. Ça se passe à l’académie du Climat, à Paris. (si possible inscrivez-vous, c’est gratuit !)

Événement

Cette année un accent particulier est mis sur le monde de la recherche. Le vendredi en particulier, des chercheurs viendront à la rencontre de la communauté pour présenter ce qu’ils font et voir comment nous pouvons interagir avec eux au service du bien commun.

Logo

NdM : pour plus de détails sur Open Food Facts, les épisodes du podcast Projets Libres n°19 et n°22 ou celui du podcast Libre à vous n°44, la dépêche récit d’un contributeur ou le journal d'appel à dons en décembre 2025.

Pendant ces journées, vous pourrez :

  • voir des courtes présentations de différents aspects du projet ;
  • participer à des ateliers pour découvrir ou améliorer le projet sur différents aspects ;
  • échanger avec plein de gens sympathiques lors de moments conviviaux.

Open Food Facts est un projet citoyen de collecte des données alimentaires qui vise la transparence afin d’améliorer l’impact de l’alimentation sur la santé, l’environnement et la société dans son ensemble.

Les données sont sous licence ODbL et cc-by-sa pour les images. Les logiciels et modèles, que nous développons avec un large communauté, sont tous libres.

PS : Il y aura des moments du programme en anglais, mais nous ferons notre possible pour assurer des traductions en français.

Commentaires : voir le flux Atom ouvrir dans le navigateur

  •  

Tempo, saison 2026‑2027 : couleurs et prévisions en accès libre, sans jeton

(NdM : Tempo est une offre commerciale d'EDF, cette dépêche traite des API et flux de données ouverts permettant de connaître et prédire les coûts du kWh.)

En avril 2025, une dépêche faisait le point sur les sources accessibles sans jeton pour connaître la couleur Tempo du jour, après la fermeture des anciennes URL d'EDF. La saison des jours rouges reprend le 1er novembre : voici une mise à jour, avec une nouveauté, des prévisions au delà de demain en JSON et en données ouvertes. Transparence d'abord : je fais partie de l'équipe de Calendrier Tempo EDF, l'une des sources présentées plus bas.

    Rappel du contexte

    L'option Tempo d'EDF compte 300 jours bleus, 43 blancs et 22 rouges par saison. Les jours rouges tombent entre le 1er novembre et le 31 mars, jamais un samedi ni un dimanche, et le kWh y coûte nettement plus cher. La couleur du lendemain est fixée par RTE et annoncée la veille. Pour piloter un chauffage ou une machine à laver depuis une box domotique, il faut donc une source lisible par une machine.

    La couleur officielle (aujourd'hui et demain)

    • RTE : la source officielle. Son API passe par un compte et un jeton sur le portail data de RTE. Les couleurs passées sont aussi publiées en données ouvertes : Tempo Like Supply Contract sur data.gouv.fr.
    • api-couleur-tempo.fr : déjà citée en 2025, toujours là. JSON simple, sans clé, très utilisé dans les forums domotiques.
    • Calendrier Tempo EDF : relaie la couleur officielle (via api-couleur-tempo.fr) sur /api/today et /api/tomorrow, qui renvoie "status": "unavailable" tant que la couleur de demain n'est pas publiée. Si vous lisez déjà RTE directement, gardez cette source : c'est l'originale.

    Exemple :

    curl https://www.calendrier-tempo.fr/api/today
    {"status": "ok", "date": "2026-10-09", "couleur": "BLEU", "code": 1}
    

    Les prévisions (après demain)

    C'est ce qui a changé depuis 2025 : on trouve maintenant des prévisions en JSON, sans compte.

    • Open DPE publie un fichier de prévisions jour par jour, avec une probabilité : https://open-dpe.fr/assets/tempo_days_lite.json
    • Calendrier Tempo EDF publie /api/predictions : une prévision par jour jusqu'à J+15, avec la probabilité de chaque couleur et la température moyenne prévue, recalculée chaque soir à partir des prévisions de consommation de RTE, de la météo (Open‑Meteo) et des règles officielles de Tempo. /api/remaining donne les jours restants par couleur dans la saison.

    Une prévision reste une prévision, et seule la couleur publiée fait foi. Plus l'échéance est lointaine, plus c'est une tendance qu'une certitude.

    Vérifier avant de faire confiance

    Plusieurs fils de forums domotiques l'ont montré l'hiver dernier : des prévisions affichées sans historique, on ne sait jamais ce qu'elles valent. Chez Calendrier Tempo EDF, chaque prévision est figée au moment où elle est émise, de J‑15 à la veille, puis comparée à la couleur réelle. L'historique complet, erreurs comprises, est consultable en ligne et téléchargeable en CSV sous licence CC BY 4.0 :

    De quoi mesurer soi‑même la fiabilité par échéance, et comparer les sources cet hiver.

    Côté domotique

    L'API ne demande ni compte ni clé, et les réponses sont en cache deux minutes : une requête toutes les trente minutes suffit largement. Des configurations prêtes à copier pour Home Assistant (intégration installable via HACS, sous licence MIT), Jeedom et Domoticz sont réunies sur une page : intégrations domotique. Documentation de l'API : https://www.calendrier-tempo.fr/api-tempo

    Pour finir

    Comme en 2025 : si vous connaissez d'autres sources sans jeton, ou si vous suivez la fiabilité des prévisions de votre côté, les commentaires sont là pour ça.

    Commentaires : voir le flux Atom ouvrir dans le navigateur

    •  
    ❌