Lecture de code : un superpouvoir pour la chasse aux bogues

2025-09-08

Cet article décrit un changement de carrière significatif : du codage itératif à la détection proactive des bogues. Au lieu de se fier uniquement à l’itération pilotée par les tests, l’auteur préconise une lecture attentive du code pour identifier les problèmes de manière préventive. La clé, selon l’auteur, est de lire attentivement le code, de construire un modèle mental complet du programme, puis d’identifier les différences entre ce modèle et le code réel dans Git. L’article suggère de se concentrer sur le flux de contrôle et les structures de données, et d’identifier les schémas potentiellement sujets aux erreurs dans le code. Cette approche réduit considérablement les bogues et améliore la qualité du code.

Lire plus
Développement lecture de code

Boucles de réessai élégantes : éviter la redondance et les attentes inattendues

2025-08-27

L'auteur explore comment écrire une boucle de réessai élégante qui limite clairement le nombre de tentatives, évite les attentes inutiles après la dernière tentative, signale l'erreur originale si la tentative échoue et évite la duplication de code. Plusieurs approches sont comparées, et finalement un boucle `try while` avec une limite supérieure est choisie pour garantir la terminaison, résolvant ainsi les problèmes de limites et les boucles infinies potentielles des solutions précédentes. Bien que la solution finale ne soit pas parfaite, elle représente une amélioration significative en termes de concision et de robustesse par rapport aux tentatives précédentes.

Lire plus
Développement

Une astuce élégante en Zig : correspondance partielle des énumérations

2025-08-09

Zig offre une solution élégante pour gérer la correspondance partielle dans les énumérations, évitant ainsi le code redondant et les plantages en temps d'exécution. L'article détaille une technique astucieuse utilisant `inline` et `comptime unreachable` pour permettre au compilateur de vérifier les branches `else` inutiles au moment de la compilation, améliorant ainsi la robustesse et la lisibilité du code. Ceci est particulièrement utile lorsqu'on traite de nombreuses variantes d'énumération, simplifiant ainsi considérablement la logique du code.

Lire plus

L'utilité mal comprise de `font-size-adjust`

2025-07-26

Cet article remet en question l'idée fausse répandue concernant la propriété CSS `font-size-adjust`. L'auteur soutient que `font-size` spécifie la taille de la boîte autour d'un glyphe, et non le glyphe lui-même, ce qui conduit à des incohérences entre les différentes polices. Au lieu de se concentrer uniquement sur la substitution de polices, `font-size-adjust` peut être utilisé pour garantir une taille plus cohérente entre les différentes polices sur une page. L'auteur recommande de le définir sur `ex-height 0.53` dans une réinitialisation CSS pour une meilleure cohérence typographique.

Lire plus
Développement

Lecteur RSS minimaliste : création d’un flux de blog personnalisé avec Deno

2025-06-26

Fatigué des lecteurs RSS lourds ? L’auteur a adopté une approche différente, en créant un lecteur RSS personnalisé à l’aide de Deno et d’un simple fichier texte. Il affiche uniquement les titres et les liens des trois derniers articles, sans stockage de texte intégral local ni marqueurs de lecture/non-lecture, et est automatiquement mis à jour quotidiennement via GitHub Actions. Le code est concis, facile à comprendre et à étendre, le rêve d’un minimaliste.

Lire plus
Développement

Compilations Rapides en Rust : Le Secret des CI en Moins de 10 Minutes

2025-06-20

Il est courant de se plaindre de la lenteur de compilation de Rust, mais l'auteur soutient que la plupart des projets Rust compilent beaucoup plus lentement qu'ils ne le devraient. Prenant rust-analyzer (200 000 lignes de code plus un million de lignes de dépendances) comme exemple, il a réussi à obtenir un pipeline CI de 8 minutes sur GitHub Actions. L'article détaille des stratégies pour optimiser les temps de compilation, notamment en tirant parti de la mise en cache CI, en divisant les tâches CI, en désactivant la compilation incrémentale et les informations de débogage, en réduisant les dépendances, en utilisant `cargo build -Z timings` pour le profilage, et en architecturant soigneusement le code pour éviter une instanciation excessive des génériques aux limites des crates. L'auteur souligne l'impact du temps de compilation sur la productivité des développeurs et recommande d'optimiser régulièrement les temps de compilation afin de maintenir les temps CI des grands projets Rust dans une fourchette raisonnable, par exemple, environ 10 minutes.

Lire plus

Le problème de coordination de l'open source : leçons du bureau Linux et du LSP

2025-06-20

L'auteur utilise son expérience avec NixOS et une application KDE comme point de départ pour discuter des défis de la coordination des logiciels open source dans l'environnement de bureau Linux. Il souligne l'absence de norme API unifiée sur le bureau Linux, ce qui conduit à un écosystème logiciel fragmenté, décrit comme une "machine à mouvement perpétuel à la Escher". Cela contraste avec le lancement du protocole de serveur de langage (LSP) par Microsoft il y a dix ans. Bien que l'implémentation ait été médiocre, sa simple existence a résolu le problème de coordination des fonctionnalités IDE, stimulant le progrès de l'industrie. L'auteur soutient que le manque de coordination de la communauté open source a conduit à une occasion manquée de créer un protocole IDE unifié avant le LSP. Le succès de Linux, cependant, est attribué à la norme API prédéfinie fournie par POSIX, réduisant les difficultés de coordination. Cet article incite à la réflexion sur les mécanismes de coordination de la communauté open source et les modèles de développement des écosystèmes logiciels. Catégorie : Technologie

Lire plus
Technologie

Deux règles empiriques pour un code efficace

2025-05-17

Cet article présente deux conseils pratiques pour améliorer l'efficacité du code : déplacer les conditions `if` vers le haut et les boucles `for` vers le bas. Déplacer les conditions `if` vers la fonction appelante réduit les branchements, simplifie le flux de contrôle et améliore la lisibilité. Déplacer les boucles `for` là où les données par lots sont traitées tire parti des avantages du traitement par lots, améliore les performances et débloque potentiellement la vectorisation. Ces deux conseils se complètent, améliorant efficacement l'efficacité du code, en particulier lors du traitement de grandes quantités de données.

Lire plus
Développement

Au-delà de la sélection scalaire : traitement par lots des flux d’événements pour l’efficacité

2025-05-15

L'auteur décrit l'inefficacité de l'anti-pattern de sélection scalaire dans la conception de services avec état, illustré par un serveur LSP. Le traitement des événements un par un entraîne des retards et un gaspillage de ressources. La solution proposée consiste à traiter les flux d'événements par lots. Une fonction `batch_stream` fusionne les événements entrants en lots, améliorant ainsi considérablement l'efficacité. Sous faible charge, elle se comporte comme un traitement d'événements uniques, mais sous forte charge, elle réduit considérablement la surcharge, augmentant ainsi les performances.

Lire plus
Développement événements pilotés

Comptime de Zig : métaprogrammation puissante mais limitée

2025-04-20

La fonctionnalité comptime de Zig est réputée pour ses capacités : génériques, compilation conditionnelle, etc. Cependant, elle est délibérément restrictive, interdisant la génération de code dynamique, les extensions de syntaxe personnalisées, les informations de type en temps d’exécution (RTTI) et les E/S. Cet article explore le raisonnement sous-jacent à ces limitations, montrant comment Zig réalise une métaprogrammation efficace et facile à comprendre grâce à l’évaluation partielle et à la spécialisation de type. Un exemple de fonction d’impression personnalisée illustre comment Zig effectue une réflexion en temps d’exécution type-safe sans RTTI. L’article conclut en louant l’élégance unique de Zig en matière de métaprogrammation ; bien que moins puissante que les alternatives, elle est remarquablement efficace et facile à utiliser en pratique.

Lire plus

Le débogueur en tant que REPL : Run to Cursor et Quick Evaluate Expression d'IntelliJ IDEA

2025-03-28

Fatigué des débogueurs traditionnels, notamment des limitations de gdb et lldb avec le code natif, l'auteur a découvert un flux de travail puissant dans IntelliJ IDEA. En combinant "Run to Cursor" et "Quick Evaluate Expression", le débogueur se transforme en un REPL. "Run to Cursor" exécute le programme jusqu'à la position du curseur, tandis que "Quick Evaluate Expression" permet d'évaluer des expressions (même du code nouvellement tapé !) dans le cadre de pile actuel. Cette approche remplace le débogage pas à pas par une interaction plus expérimentale et bidimensionnelle dans l'éditeur, en utilisant la complétion de code et en offrant une expérience de débogage bien plus efficace.

Lire plus
Développement

Privilégier les options longues dans les scripts

2025-03-22

De nombreux utilitaires en ligne de commande proposent des options courtes (-f) et des options longues (--force). Si les options courtes sont pratiques pour une utilisation interactive, les options longues sont bien supérieures dans les scripts. Leur meilleure lisibilité et leur nature explicative améliorent la maintenabilité et la compréhension. Par exemple, dans Git, `git switch --create release-{today} origin/main` est beaucoup plus clair que `git switch -c my-new-branch`, notamment dans les scripts complexes.

Lire plus

Rust Hardcore : Un traceur de rayons sans allocation mémoire dynamique

2025-01-30

Cet article détaille une étude de cas sur la création d’une application Rust utilisant uniquement une API minimale et artificiellement contrainte (pas d’allocation mémoire dynamique). L’auteur critique le RAII (Resource Acquisition Is Initialization) pour son manque d’organisation dans la gestion des ressources et propose un « mode hardcore » : diviser le programme en un binaire `std` et une bibliothèque `#![no_std] no_alloc`, en autorisant uniquement le binaire à demander directement des ressources au système d’exploitation. En utilisant un traceur de rayons jouet comme exemple, l’auteur explique méticuleusement la gestion des tampons de pixels, la parallélisation, l’allocateur de mémoire et l’analyse de scène dans ce « mode hardcore », aboutissant finalement à un traceur de rayons sans allocation mémoire dynamique.

Lire plus
Développement

Invariants : un outil puissant pour écrire du code correct

2025-01-12

Cet article explore le concept d'« invariants » en programmation et leurs applications. À partir d'un petit exemple — écrire une variante de recherche binaire qui calcule le point d'insertion —, l'auteur montre comment la définition et le maintien d'invariants conduisent à un code correct. Les invariants, explique l'article, sont des propriétés qui restent vraies tout au long de l'évolution dynamique d'un système, simplifiant le raisonnement en évitant les complexités liées à la considération de multiples chemins d'exécution. Des exemples de projets tels que Cargo, rust-analyzer et TigerBeetle illustrent les avantages de l'utilisation d'invariants dans les grands systèmes, tels qu'une meilleure maintenabilité et des performances accrues. L'auteur conclut en résumant l'importance des invariants dans la programmation à petite et grande échelle, soulignant leur valeur dans l'écriture de code correct et efficace.

Lire plus

Idée révolutionnaire : appliquer les principes de Magit au système de contrôle de version jj

2024-12-13

L'auteur propose une approche novatrice : appliquer l'interface de contrôle de version Magit d'Emacs (qui utilise des fichiers texte comme interface utilisateur) à l'écosystème naissant de contrôle de version jj. L'article souligne que l'interface utilisateur textuelle de Magit offre efficacité et portabilité. En tirant parti du protocole LSP, une expérience similaire à Magit peut être implémentée dans divers éditeurs, évitant ainsi le développement redondant. L'auteur prévoit la génération de fichiers texte spécifiques (tels que .jj/status.jj) et l'utilisation des fonctionnalités LSP, telles que les jetons sémantiques, les plages de pliage et le « aller à la définition », pour réaliser des opérations de contrôle de version similaires à Magit. L'objectif final est de créer une interface utilisateur efficace et multiplateforme pour le contrôle de version jj.

Lire plus
Développement