Bonjour 'Nal,
Tout a commencé quand j'ai voulu faire des choses un peu inhabituelles sur mon blog personnel (entre autres, écrire des maths avec une syntaxe personnalisée), et pour cela changer le moteur de blog. De Zola, un générateur de site statique dans la lignée de Jekyll, Hugo, etc., je suis passé à un petit script maison. J'ai décidé de l'écrire en Rust, car même si ce n'est pas le plus pratique comme langage de script, c'est un langage que j'adore et dans lequel je voulais justement acquérir plus d'aisance.
Comme la structure du site proposée par Zola me paraissait plutôt pratique, je l'ai plus ou moins conservée. Il y a des fichiers Markdown convertis en HTML, avec un en-tête en TOML pour les métadonnées (date, etc.) ; des templates (en l'occurrence en Tera) qui définissent le HTML autour du Markdown rendu et peuvent aussi constituer des pages à part entière ; et des fichiers quelconques qui sont simplement copiés (images, CSS, etc.).
Je commence donc à écrire mon script, un peu laborieusement car je n'ai pas touché à Rust depuis un moment. J'ajoute au fur et à mesure les dépendances dont j'ai besoin, en prenant des librairies parmi les plus courantes :
anyhow pour propager facilement les erreurs,
clap pour le parsing des arguments en ligne de commande du script,
heck pour convertir entre différents styles de nommage,
pulldown-cmark pour lire le Markdown et le convertir en HTML,
regex pour les expressions régulières, et lazy_static pour ne compiler une regex qu'une fois,
tera pour les templates (même engin que Zola),
toml pour lire le TOML,
walkdir pour lister un dossier récursivement.
Comme j'ai plutôt l'habitude d'écrire des scripts en Python, j'ai tendance à chercher « la librairie Rust qui correspond à tel module Python ». Par exemple, j'ai ajouté regex
sans me poser trop de questions (en pensant à import re
), et de même pour clap
(import argparse
) et walkdir
(from os import walk
).
À un moment donné, j'ai l'idée de regarder les dépendances transitives. Et là, surprise en examinant le Cargo.lock
: il y en a 126.
9 dépendances directes, ce n'est déjà pas rien, mais 126 dépendances au total, je trouve ça complètement excessif. Je sais qu'il y a des projets à 500 dépendances, en particulier en JavaScript, je sais qu'il y en a que ça ne dérange pas, mais je sais aussi ce qui est arrivé à left-pad, à polyfill.io, à xz, et d'autres, et je ne veux certainement pas passer le temps qu'il faudrait pour vérifier ne serait-ce que superficiellement qui sont les auteurs de toutes ces librairies et si je suis prêt à leur faire confiance. Je ne suis pas non plus en train d'écrire l'application Web d'une entreprise, mais un bête script générateur de blog. Pour le dire de manière plus éloquente, certes à un point où mon script ne marchait pas encore, j'avais plus de dépendances que de lignes de code.
En examinant cargo tree
, j'ai pu constater quelles librairies contribuaient le plus à cette explosion. D'abord, clap
:
└── clap v4.5.8
└── clap_builder v4.5.8
├── anstream v0.6.14
│ ├── anstyle v1.0.7
│ ├── anstyle-parse v0.2.4
│ │ └── utf8parse v0.2.2
│ ├── anstyle-query v1.1.0
│ ├── colorchoice v1.0.1
│ ├── is_terminal_polyfill v1.70.0
│ └── utf8parse v0.2.2
├── anstyle v1.0.7
├── clap_lex v0.7.1
└── strsim v0.11.1
Aussitôt remplacée par pico-args, qui n'est pas tout à fait aussi pratique mais n'a aucune dépendance et ne fait même pas 700 lignes de code. (En plus, je fais confiance à l'auteur, qui a aussi écrit une excellente librairie de rendu SVG, resvg.)
Ensuite, il y a tera
:
└── tera v1.20.0
├── chrono v0.4.38
│ ├── iana-time-zone v0.1.60
│ └── num-traits v0.2.19
│ [build-dependencies]
│ └── autocfg v1.3.0
├── chrono-tz v0.9.0
│ ├── chrono v0.4.38 (*)
│ └── phf v0.11.2
│ └── phf_shared v0.11.2
│ └── siphasher v0.3.11
│ [build-dependencies]
│ └── chrono-tz-build v0.3.0
│ ├── parse-zoneinfo v0.3.1
│ │ └── regex v1.10.5
│ │ ├── regex-automata v0.4.7
│ │ │ └── regex-syntax v0.8.4
│ │ └── regex-syntax v0.8.4
│ ├── phf v0.11.2 (*)
│ └── phf_codegen v0.11.2
│ ├── phf_generator v0.11.2
│ │ ├── phf_shared v0.11.2 (*)
│ │ └── rand v0.8.5
│ │ └── rand_core v0.6.4
│ └── phf_shared v0.11.2 (*)
├── globwalk v0.9.1
│ ├── bitflags v2.6.0
│ ├── ignore v0.4.22
│ │ ├── crossbeam-deque v0.8.5
│ │ │ ├── crossbeam-epoch v0.9.18
│ │ │ │ └── crossbeam-utils v0.8.20
│ │ │ └── crossbeam-utils v0.8.20
│ │ ├── globset v0.4.14
│ │ │ ├── aho-corasick v1.1.3
│ │ │ │ └── memchr v2.7.4
│ │ │ ├── bstr v1.9.1
│ │ │ │ └── memchr v2.7.4
│ │ │ ├── log v0.4.22
│ │ │ ├── regex-automata v0.4.7
│ │ │ │ ├── aho-corasick v1.1.3 (*)
│ │ │ │ ├── memchr v2.7.4
│ │ │ │ └── regex-syntax v0.8.4
│ │ │ └── regex-syntax v0.8.4
│ │ ├── log v0.4.22
│ │ ├── memchr v2.7.4
│ │ ├── regex-automata v0.4.7 (*)
│ │ ├── same-file v1.0.6
│ │ └── walkdir v2.5.0
│ │ └── same-file v1.0.6
│ └── walkdir v2.5.0 (*)
├── humansize v2.1.3
│ └── libm v0.2.8
├── lazy_static v1.5.0
├── percent-encoding v2.3.1
├── pest v2.7.10
│ ├── memchr v2.7.4
│ ├── thiserror v1.0.61
│ │ └── thiserror-impl v1.0.61 (proc-macro)
│ │ ├── proc-macro2 v1.0.86
│ │ │ └── unicode-ident v1.0.12
│ │ ├── quote v1.0.36
│ │ │ └── proc-macro2 v1.0.86 (*)
│ │ └── syn v2.0.68
│ │ ├── proc-macro2 v1.0.86 (*)
│ │ ├── quote v1.0.36 (*)
│ │ └── unicode-ident v1.0.12
│ └── ucd-trie v0.1.6
├── pest_derive v2.7.10 (proc-macro)
│ ├── pest v2.7.10 (*)
│ └── pest_generator v2.7.10
│ ├── pest v2.7.10 (*)
│ ├── pest_meta v2.7.10
│ │ ├── once_cell v1.19.0
│ │ └── pest v2.7.10 (*)
│ │ [build-dependencies]
│ │ └── sha2 v0.10.8
│ │ ├── cfg-if v1.0.0
│ │ ├── cpufeatures v0.2.12
│ │ └── digest v0.10.7
│ │ ├── block-buffer v0.10.4
│ │ │ └── generic-array v0.14.7
│ │ │ └── typenum v1.17.0
│ │ │ [build-dependencies]
│ │ │ └── version_check v0.9.4
│ │ └── crypto-common v0.1.6
│ │ ├── generic-array v0.14.7 (*)
│ │ └── typenum v1.17.0
│ ├── proc-macro2 v1.0.86 (*)
│ ├── quote v1.0.36 (*)
│ └── syn v2.0.68 (*)
├── rand v0.8.5
│ ├── libc v0.2.155
│ ├── rand_chacha v0.3.1
│ │ ├── ppv-lite86 v0.2.17
│ │ └── rand_core v0.6.4
│ │ └── getrandom v0.2.15
│ │ ├── cfg-if v1.0.0
│ │ └── libc v0.2.155
│ └── rand_core v0.6.4 (*)
├── regex v1.10.5
│ ├── aho-corasick v1.1.3 (*)
│ ├── memchr v2.7.4
│ ├── regex-automata v0.4.7 (*)
│ └── regex-syntax v0.8.4
├── serde v1.0.203
├── serde_json v1.0.120
│ ├── itoa v1.0.11
│ ├── ryu v1.0.18
│ └── serde v1.0.203
├── slug v0.1.5
│ └── deunicode v1.6.0
└── unic-segment v0.9.0
└── unic-ucd-segment v0.9.0
├── unic-char-property v0.9.0
│ └── unic-char-range v0.9.0
├── unic-char-range v0.9.0
└── unic-ucd-version v0.9.0
└── unic-common v0.9.0
Sérieusement, c'est juste effrayant. Je me suis tourné vers Minijinja, qui fait plus ou moins la même chose avec une seule dépendance obligatoire — et qui en fait un but explicite (« Minijinja is a powerful but minimal dependency template engine »), l'auteur, un développeur connu, ayant écrit sa peur face à l'explosion des micro-dépendances. Au départ, j'ai utilisé une fonctionnalité optionnelle de Minijinja qui rajoute deux dépendances, pour avoir une certaine API, puis j'ai refactorisé mon code pour ne pas en avoir besoin.
Ensuite, il y a le cas de regex
:
└── regex v1.10.5
├── aho-corasick v1.1.3
│ └── memchr v2.7.4
├── memchr v2.7.4
├── regex-automata v0.4.7
│ ├── aho-corasick v1.1.3 (*)
│ ├── memchr v2.7.4
│ └── regex-syntax v0.8.4
└── regex-syntax v0.8.4
Contrairement à Tera, ça ne me fait pas hurler, surtout que toutes ces librairies sont du même auteur — Andrew Gallant — et essentiellement crées pour les besoins de regex
. Je vois un peu qui est Andrew Gallant, il est connu comme étant l'auteur de ripgrep, et regex
est une merveille de performance qui fait justement le succès de ripgrep. D'un autre côté, j'avais ajouté la dépendance à regex
par réflexe pythonicien, mais je n'en avais besoin que pour une seule expression régulière toute bête, que j'ai facilement remplacée par deux appels à str::split_once
. Du même coup, j'ai éliminé la dépendance à lazy-static
, dont j'ai appris par ailleurs qu'elle se remplaçait facilement par OnceCell
qui est dans la bibliothèque standard.
Il y avait encore walkdir
:
└── walkdir v2.5.0
└── same-file v1.0.6
(en fait, quelques dépendances de plus sous Windows). D'un côté, ce n'est pas monstrueux (et c'est encore du Andrew Gallant), d'un autre côté, ce n'est tout de même pas bien compliqué d'implémenter la lecture récursive d'un dossier. Je me suis empressé de le faire, en 50 lignes de code, et de retirer cette dépendance.
J'ai aussi remplacé heck
par un bête .replace('-', "_")
après m'être assuré que cela convenait dans mon cas.
Bilan : je n'ai « plus que » 24 dépendances, pour 5 dépendances directes : anyhow
, minijinja
, pico-args
, pulldown-cmark
et toml
. L'arbre est celui-ci :
├── anyhow v1.0.86
├── minijinja v2.0.2
│ └── serde v1.0.203
├── pico-args v0.5.0
├── pulldown-cmark v0.11.0
│ ├── bitflags v2.5.0
│ ├── memchr v2.7.4
│ ├── pulldown-cmark-escape v0.11.0
│ └── unicase v2.7.0
│ [build-dependencies]
│ └── version_check v0.9.4
└── toml v0.8.14
├── serde v1.0.203
├── serde_spanned v0.6.6
│ └── serde v1.0.203
├── toml_datetime v0.6.6
│ └── serde v1.0.203
└── toml_edit v0.22.14
├── indexmap v2.2.6
│ ├── equivalent v1.0.1
│ └── hashbrown v0.14.5
├── serde v1.0.203
├── serde_spanned v0.6.6 (*)
├── toml_datetime v0.6.6 (*)
└── winnow v0.6.13
Les deux plus gros contributeurs sont pulldown-cmark
et toml
. Ces deux bibliothèques sont utilisées respectivement par rustdoc
(l'outil standard de documentation d'API en Rust, utilisé par absolument tout le monde) et par Cargo lui-même, donc j'ai plutôt confiance en ces deux librairies.
Quelle est la conclusion ? Que ce n'est pas bien difficile, dans beaucoup de cas, de se passer d'une dépendance. J'ai l'impression qu'il y a une culture, dans une partie du monde informatique, de prendre les dépendances trop à la légère. J'ai pris Rust comme exemple, mais je crois comprendre que JavaScript est encore pire. Que les outils comme Cargo rendent très facile l'utilisation de librairies, c'est fantastique (en Python c'est plus compliqué, et ne parlons même pas de C ou C++), mais il ne faut pas abuser des bonnes choses. Chaque dépendance a un coût, celui de la mettre à jour et de s'adapter si elle change son API, et elle porte un risque, celui d'être utilisée pour propager du code malveillant, ou tout simplement d'avoir des vulnérabilité (à force d'importer de plus en plus de code dans son projet, on augmente du même coup la surface d'attaque potentielle). Quand on a 130 dépendances, il est irréaliste de les auditer individuellement. Les outils comme cargo audit
sont une très bonne chose, mais si on peut s'en passer, c'est encore mieux.
# Merci
Posté par nathanaelh . Évalué à 10.
Merci pour ce retour d'expérience. Je partage la même inquiétude sur le nombre très élevé des dépendances indirectes, et les difficultés que ça apporte pour la fiabilité, la maintenance. Je développe une petite application en Flutter pour mobile, et c'est un sujet que je regarde régulièrement. Il m'arrive parfois de rajouter quelques lignes de codes pour éviter d'ajouter une dépendance.
# Les limites de l'exercice
Posté par Vincent Danjean . Évalué à 10.
Toute la difficulté est de savoir où placer la limite.
Moins de dépendances, c'est effectivement moins de code (surface d'attaque moindre) et moins de personnes extérieures à qui faire confiance. Le journal l'explique très bien. Et, quand on peut obtenir moins de dépendances juste en changeant la bibliothèque qu'on utilise, c'est très bien.
Mais si on enlève des dépendances en réécrivant soi-même le code de la bibliothèque, là, on peut partir dans l'excès inverse : on risque de recoder mal ce qui a été codé bien par une équipe compétente. On perd la force du travail d'équipe, le partage du travail.
La frontière est mince. Dans le journal, les exemples donnés semblent raisonnables (grosses bibliothèques enlevées en (re)codant quelques cas particuliers) mais il serait facile d'aller trop loin si on ne fait pas attention. J'ai vu nombres d'étudiants recoder (très) mal des fonctionnalités de bibliothèques pour de mauvaises raisons (ignorance de l'existant, c'est plus rigolo de tout (re)faire soi-même, etc.)
Dans le contexte d'enseignement, ça peut être bien (on apprend quand on (re)code), mais dans un contexte plus professionnel (stage, emploi), ça peut vite apporter des problèmes (performances, sécurité, maintenabilité, etc.)
[^] # Re: Les limites de l'exercice
Posté par fearan . Évalué à 10.
et
justement c'est quand on est étudiant que c'est une excellente raison! ça permet d'apprendre;
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
# Éternel problème des SPOF
Posté par David Demelier (site web personnel) . Évalué à 10.
J'aime pas spécialement Rust (surtout pour sa syntaxe, donc complètement subjectif) mais j'ai rien contre le langage directement. Par contre je déteste les crates.io et l'écosystème qui en est lié. Déjà parce qu'il faut obligatoirement un compte GitHub pour publier mais parce qu'il est conçu comme npm, on fait des modules de 10 lignes et on en revient à télécharger la terre entière pour un projet quelconque.
Alors pour Rust on va dire que c'est moins grave car les LTO et la compilation fait que cela reste moins bloat que les projets nodejs mais ça n'en est pas moins énervant. Plus il y a de pièces en mouvements dans un moteur, plus il y a de risques. Le gros problème est évidemment lié au SPOF. N'importe qui avec une simple dépendance peut introduire une backdoor en rien de temps.
Ce qui me chiffonne le plus c'est l'aspect mise à jour de sécurité. Là où des bibliothèque partagées permettent de sécuriser un système avec une simple mise à jour de la
.(dll|so|dylib)
, les projets Rust doivent tous être recompilés. On va dire que ce n'est pas mieux avec les projets externes directement intégrés dans un projet mais ça doit rester anecdotique.Aucune solution n'est parfaite mais pour moi tous les écosystèmes basés sur ce concept comme Rust, Go et npm sont vérolés de base en plus d'être des plaies pour les packagers Linux/*BSD.
git is great because linus did it, mercurial is better because he didn't
[^] # Re: Éternel problème des SPOF
Posté par ff9097 . Évalué à 5.
Il n'est plus possible de garder cette logique de bibliothèques partagées avec Rust ? C'est forcément des binaires statiques ?
[^] # Re: Éternel problème des SPOF
Posté par dcp . Évalué à 3.
Je n'en suis pas sûr, et j'ai une très grosse flemme d'aller vérifier, donc faîtes-vous plaisir, corrigez moi :-D
J'ai cru comprendre que la stabilité de l'ABI n'était pas une priorité de Rust (pour le moment), ce qui expliquerait qu'il ne produit que des binaires statiques.
[^] # Re: Éternel problème des SPOF
Posté par jeanas (site web personnel, Mastodon) . Évalué à 6.
Cargo est parfaitement capable de créer et d'utiliser des librairies dynamiques, mais en gros les seuls qui le font sont ceux qui ont besoin de FFI avec d'autres langages (souvent C, mais aussi tout langage capable de comprendre l'ABI C, comme C++ ou Python).
Déjà, le principe même de vouloir mettre à jour une librairie dynamique sans recompiler ses dépendants est fondamentalement en conflit avec la monomorphisation des génériques, c'est-à-dire le fait qu'une même fonction dans la librairie peut être appelée avec des types différents dans le dépendant, non connus à l'avance, ce qui nécessite de la recompiler une fois par type avec lequel elle est utilisée dans le dépendant. C'est la même chose en C++ avec les templates. Toute tentative de créer une librairie dynamique à l'ABI stable se heurte à ce problème, qui rend le code pas du tout idiomatique parce que les génériques sont partout dans le langage.
[^] # Re: Éternel problème des SPOF
Posté par lym . Évalué à 3.
Je dois dire que je n'aimais pas trop Rust aussi pour la syntaxe et sa volonté de traiter le problème largement résolu de la gestion mémoire en C via des outils externes. Puis sur des projets industriels concurrentiels, ou on taille les ressources d'un système embarqué pour 80% de charge prévisible initialement et arriver au delà des 90% une fois toutes les features développées, je dirais que tant que le C gardera un avantage performance (même quelques %) il ne sera pas délogé. Surtout pour des choses stables ou les outils d'analyse de code actuels un peu longs à passer ne sont pas un problème vs ce qu'on gagne à l’exécution.
Mais alors voir saborder tout le concept de librairie partagée côté mutualisation niveau stockage, mais plus encore ce que la gestion de mémoire virtuelle des processeurs modernes optimise entre process les utilisant (mutualisation empreinte en RAM cette fois), alors là c'est même pas la peine de se faire chier à l'apprendre: C'est mort né pour du bas niveau et n'a de sens que pour de l'applicatif monolithique, surtout frontal réseau et évoluant vite: Pas étonnant vu que c'est Mozilla qui s'y est collé…
[^] # Re: Éternel problème des SPOF
Posté par xryl669 . Évalué à 2.
Pour les bibliothèques partagées, moi, je suis carrément contre. L'enfer des bibliothèques partagées, c'est l'impossibilité de faire évoluer l'API/ABI de celle-ci. C'est à dire que ni les signatures des fonctions ni le comportement ne peut changer, sans quoi, soit ça casse le code dépendant, soit ça casse le fonctionnement du code dépendant.
Il y a un OS très connu qui était justement connu pour l'instabilité des applications, le problème de compatibilité des installations et c'est justement lui qui a donné le nom que nous utilisons actuellement pour ces m….s : dll.
L'idée, au départ semblait bonne, pourquoi payer plusieurs fois pour le même code?
Mais, une fois mise sur la sellette, on se rend compte que cette économie de bout de chandelle interdit toute évolution d'un code que l'on ne maîtrise plus. Un effort important de documentation doit être fait pour expliquer les effets indirects du code (qui se souvient des crash de l'explorer de fichier à cause d'un plugin IExplorer qui n'a pas supporté une évolution des modules COM…)
Au final, la légendaire stabilité de OSX/MacOS provient principalement dans le fait de ne pas faire de DLL partagées (il y a bien des "frameworks" bas niveau partagés, mais ceux ci sont limités et en général, il y a une couche d'abstraction pour l'utilisation dans votre langage de programmation préféré). Une application = un dossier contenant le binaire et toutes ses dépendances.
Sous linux, on a souvent ces problèmes également (et ce, malgré tout le travail du curage des distributions). Qui n'a pas eu de problème d'une AppImage qui contient une référence vers un driver OpenGL qui est compilé avec une version plus ancienne que le système et donc empêche la version du système d'être utiliséeet échoue au lancement?.
Tout ça à cause du fait que les drivers graphiques récents charge un .so alors que tout le reste de l'application est buildé en statique.
Bref, si le .so ou .dll pouvait crever, on s'en porterait que mieux, AMHA.
En fait, même dans l'embarqué, où l'espace disque est limité, les .so ne font pas sens. Souvent on peut construire le système entier en une seule build, les .so ne servent à rien.
[^] # Re: Éternel problème des SPOF
Posté par BAud (site web personnel) . Évalué à 6.
les bibliothèques partagées libres te permettent de les embarquer en statique si tu as besoin d'une version plus récente que le système : le meilleur (?) des deux mondes.
[^] # Re: Éternel problème des SPOF
Posté par Gil Cot ✔ (site web personnel, Mastodon) . Évalué à 3.
Sous Linux (ce qui n’était pas le cas sous la fenêtre mais les choses ont peut-être changé) on pratique le SameVer d’une part et on peut avoir plusieurs versions de bibliothèques partagées installées. Du coup c'est ton AppImage qui me pose plus question qu’autre chose.
Justement dans l’embarqué on n’est pas dans le contexte d’installer des applications de sources diverses et qui utiliseraient des versions différentes d’interface si ? Parce-que ton Linux tu peux le build aussi de la même façon et avoir les mêmes avantages et inconvénients.
“It is seldom that liberty of any kind is lost all at once.” ― David Hume
# Un peu de nuance
Posté par Fabien . Évalué à 5.
Quand on regarde le retour du cargo tree sur tera, regex-syntax v0.8.4 apparaît plusieurs fois.
La même lib (avec la même version) est utilisée par plusieurs dépendances de tera, pourtant tu n'auras qu'une seule lib installée.
Pour clap vs pico-args, c'est un choix perso au détriment des fonctionnalités.
Je comprend la réflexion du trop de dep, mais il faut parfois relativiser:
préférer une crate sans dep mais qui réimplémente tout dans son coin ou une crate avec des dépendances (qui ont plus de chance d'être revues par plus de dev).
Du coup, tu préfères une n-ième crate pour un runtime async sans dépendance face à tokio? Le deuxième ayant certainement plus de reviews que le premier.
Personnellement, je suis passé de la politique "moins de dep" à "que des dep maintenues", je m'appuie sur les indicateurs (nombre de téléchargement et surtout date du dernier update) de crates.io
Tu peux aussi avoir d'autres critères comme cargo-geiger et cargo-crev.
[^] # Re: Un peu de nuance
Posté par jeanas (site web personnel, Mastodon) . Évalué à 6.
C'est vrai. Note toutefois que ces doublons ne sont pas décomptés dans mon total de 126 (j'ai juste fait
rg "name =" Cargo.lock | wc -l
).Et je ne dis pas que les dépendances sont « mal » (au contraire, c'est un soulagement d'avoir enfin un langage de bas niveau où c'est facile d'utiliser des dépendances). Je critique plus une certaine culture d'en ajouter sans prendre en compte leur coût. Je suis tout à fait prêt à utiliser tokio, ou regex, ou pulldown-cmark, ou toml. Je suis sceptique sur Tera parce que les dépendances me paraissent excessives rapportées au service rendu.
[^] # Re: Un peu de nuance
Posté par Ontologia (site web personnel) . Évalué à 6.
J'ai souvenance d'une librairie js installable avec npm qui te fournissait une fonction te disant si un nombre était pair ou impair…
« Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker
[^] # Re: Un peu de nuance
Posté par David Delassus (site web personnel) . Évalué à 10.
Non c'est 2 librairies :
Heureusement, il existe des libs permettant de les différencier :
https://link-society.com - https://kubirds.com - https://github.com/link-society/flowg
[^] # Re: Un peu de nuance
Posté par BAud (site web personnel) . Évalué à 6.
les librairies, c'est ceux qui vendent des bouquins ; les bibliothèque c'est là où on peut les emprunter et consulter, non ? ;-)
[^] # Re: Un peu de nuance
Posté par David Delassus (site web personnel) . Évalué à 0.
Une librairie c'est aussi la francisation du terme anglais "library" qui veut dire bibliothèque, contrairement à "book shop".
Donc, ne pas confondre librairie et librairie. Tout comme il ne faut pas confondre cuisinière (la machine) et cuisinière (la personne).
https://link-society.com - https://kubirds.com - https://github.com/link-society/flowg
[^] # Re: Un peu de nuance
Posté par BAud (site web personnel) . Évalué à 4. Dernière modification le 03 juillet 2024 à 18:51.
cela s'appelle un anglicisme (je ne rejette pas l'archaïsme pour autant) :-) ce qui est confirmé sur librairie
pour autant je maintiens que le terme bibliothèque est plus approprié (cf. 7 bien mieux décrit et défini), comme indiqué sur traductions classiques auquel tu peux ajouter tous les termes ayant leur équivalent français (éventuellement anglicisé ?)
tu te fâcheras avec qui tu veux, je ne suis plus là -----> [ ]
le cuisinier, c'est quel meuble — à des fins d'équité ? /o\
[^] # Re: Un peu de nuance
Posté par David Delassus (site web personnel) . Évalué à -2.
1) Anglicisme c'est un emprunt à l'anglais, ici c'est un mot anglais re-traduit en français, donc bien une francisation et non un anglicisme. Quitte à être chiant, autant l'être jusqu'au bout non ?
2) Je suis pas le seul a utiliser ce mot dans ce sens, pourquoi me reprendre moi et pas les autres ?
3) Tu as ton avis, une bibliothèque c'est à propos de livres (bibli), ici on n'a pas de lives. On a parfaitement le droit de ne pas adhérer aux traductions classiques de LinuxFR
4) En fait, je n'adhère même pas à cette manie de tout vouloir traduire. cadriciel ? sérieusement ?
Ce genre d'équité à la mord-moi-le-noeud, je m'en contre fiche.
Bref, t'as eu envie d'être chiant et trolleur alors qu'on n'est pas Vendredi. C'est triste de voir les traditions se perdre.
https://link-society.com - https://kubirds.com - https://github.com/link-society/flowg
[^] # Re: Un peu de nuance
Posté par BAud (site web personnel) . Évalué à 4.
à chiant, chiant 1/2
avec les RTT, c'est tous les jours 'dredi :-)
[^] # Re: Un peu de nuance
Posté par Ontologia (site web personnel) . Évalué à 5.
La question que je me pose, c'est est-ce que l'auteur l'a écrit pour faire une blague ou sérieusement ?
Le package is_even import is_odd !!o_O
C'est du délire. Après on s'étonne que l'appli rame… (à mois que js sache inliner, mais j'en doute)
D'un autre côté c'est pas grave : on fait appel à des types comme moi à 500€/jour pour auditer l'appli quand elle rame trop…
Tout ça pour pas écrire toto % 2 == 0
🙄
« Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker
[^] # Re: Un peu de nuance
Posté par alberic89 🐧 . Évalué à 4.
Encore plus efficace :
(x & 1) === 0
L'informatique n'est pas une science exacte, on n'est jamais à l'abri d'un succès
[^] # Re: Un peu de nuance
Posté par xryl669 . Évalué à 4.
Et vos 2 exemples de code montrent que vous auriez dû utiliser cette dépendance car vous avez faux tout les deux.
Pour tester une valeur, dans un langage non typé, il faut s'assurer du type, sinon les règles d'autoconversion des types vont vous manger les doigts. En gros, il faut tester si le paramètre est un nombre (ou convertible vers un nombre), via
isNaN(x)
ou autre et agir en conséquence. Donc la bonne réponse devrait plutôt êtreconst isEven = x => typeof(x) == "number" ? ((+x&1)==0) : false
En gros, vos réponses démontrent clairement que le point d'une des premières réponses à l'article est vrai, à vouloir faire sans dépendances, on reproduit les bugs que les dépendances, plus testées, ont déjà corrigés.
# walkdir, la place est dans la bibliothèque standard ?
Posté par Thomas Douillard . Évalué à 7.
Dans ce cas particulier, certes c'est ptete pas la mort à réimplémenter, mais le fait que ça se retrouve dans ton logiciel à la fois et dans ses dépendances montre que ça a peut-être sa place dans la bibliothèque standard.
[^] # Re: walkdir, la place est dans la bibliothèque standard ?
Posté par Fabien . Évalué à 3.
Non, ça se fait en quelques lignes avec une fonction récursive et un itérateur.
Je suppose que dans les 50 lignes produites par l'auteur, il y a plus que ça.
Mais je suppose aussi que ces 50 lignes proposent beaucoup moins que walkdir.
La std Rust n'a jamais eu pour but de répondre à toutes les demandes même basiques.
Par contre, elle permet de créer les outils/lib appropriés.
Dans le cas de walkdir, faudrait gérer les Linux/Max/Windows/.. et toutes les spécificités de ces plateformes.
On en revient au même, c'est au dev de choisir ce qu'il a besoin.
[^] # Re: walkdir, la place est dans la bibliothèque standard ?
Posté par Thomas Douillard . Évalué à 5.
Ça pose la question de l'étendue souhaitable d'une bibliothèque standard. Si tu ne mets pas dedans certains trucs très utilisés en pratique par les devs, au delà d'essayer de maintenir ce qui est essentiel à un langage, tu mets le poids du développement et de la maintenance sur une communauté décentralisée, ça a des risques de fragmentation, de garantie de maintenance, ou de réinventage de roue sous prétexte d'éviter des dépendances qu'on peut illustrer ici.
[^] # Re: walkdir, la place est dans la bibliothèque standard ?
Posté par Fabien . Évalué à 3.
A l'inverse, trop en mettre dans la lib std peut décourager le développement d'alternatives.
Rust a choisi de fournir une lib "minimaliste". Mais elle n'est pas figée.
L'auteur du post parle de lazy_static qui était la ref du genre. Elle a été améliorée par la crate Once_cell qui maintenant se retrouve dans std.
On peut aussi citer futures.
Si Rust n'avait pas supprimé les greenthreads de la std, est-ce que tokio et les autres runtimes async auraient vu le jour?
Il existe donc les 2 approches chacune avec leurs avantages/inconvénients, faut bien en choisir une.
[^] # Re: walkdir, la place est dans la bibliothèque standard ?
Posté par SpaceFox (site web personnel, Mastodon) . Évalué à 6.
Pour moi c’est un faux problème ; par exemple en Java, la gestion des dates était historiquement daubée (bien que beaucoup – trop – de gens s’en accommodaient) ; conséquence : des gens ont écrit Joda-Time, qui a été repris d’une façon très proche dans l’API standard à partir de Java 8 sous le libellé JSR-310.
La connaissance libre : https://zestedesavoir.com
[^] # Re: walkdir, la place est dans la bibliothèque standard ?
Posté par devnewton 🍺 (site web personnel) . Évalué à 9.
Peut être que les langages devraient lancer des concours pour choisir les libs à intégrer en standard ?
Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.
[^] # Re: walkdir, la place est dans la bibliothèque standard ?
Posté par jeanas (site web personnel, Mastodon) . Évalué à 3. Dernière modification le 02 juillet 2024 à 15:08.
Il y a une issue pour ça : https://github.com/rust-lang/rust/issues/69684
Le souci, c'est que les cas simples (comme le mien) sont faciles à implémenter, mais fournir une API qui couvre à peu près bien tous les cas intéressants est beaucoup, beaucoup plus compliqué. Il faut notamment penser à : ce qui se passe quand on rencontre un symlink vers un dossier, ce qui se passe quand on n'a pas les permissions, proposer une manière de limiter la profondeur de recherche, ou de filtrer des dossiers au fur et à mesure qu'ils sont lus (pour éviter de descendre dedans), etc. Donc je peux comprendre que ce soit trop pour la stdlib, même si ça se discute.
Non, il n'y a vraiment rien de plus que la base de la base (OK, 40 lignes, pas 50) :
C'est juste que les itérateurs sont un poil verbeux, mais rien de très notable.
[^] # Re: walkdir, la place est dans la bibliothèque standard ?
Posté par Fabien . Évalué à 3.
On pourrait vouloir inclure ce code minimaliste en std et pourtant il est déjà opiniâtre, il force la récursivité.
Faudrait une option pour gérer ce cas, et tant qu'on y est ajoutons aussi ce cas et ….
Pas facile de décider, mais on a le choix des crates.
Au passage, parfois (cas géré par le dev de ta dépendance) tu peux réduire les dépendances de tes dépendances en jouant avec les features,
tu désactives default-features et tu n'actives que celles nécessaires.
[^] # Re: walkdir, la place est dans la bibliothèque standard ?
Posté par Elfir3 . Évalué à 10.
En fait, il faudrait un pack de libs qui s'occupent des trucs de base qu'on voudrait voir inclus dans la std, mais qu'on ose pas trop. Genre on appellerait ça "boost" pour le gain en productivité de ceux qui ont l'habitude de piocher dedans.
[^] # Re: walkdir, la place est dans la bibliothèque standard ?
Posté par xryl669 . Évalué à 1.
Ah, je vois pas de récursivité dans le code posté, au contraire, il est complètement itératif.
Par contre, il a des bugs, car
is_dir
suit les liens symboliques, donc il peut ne jamais sortir (et donc crasher par manque de mémoire) si tu as une boucle dans tes répertoires. Mais pour les besoins de l'auteur, qui maîtrise son arborescence de fichiers, c'est un bon compromis je suppose.# Le cas d'école JQuery de Javascript
Posté par abriotde (site web personnel, Mastodon) . Évalué à 5. Dernière modification le 02 juillet 2024 à 23:46.
Le cas d'école JQuery de Javascript représente, je pense, bien un autre problème non abordé des dépendances : La lourdeur inutile ou inefficience.
Typiquement en Javascript, on a longtemps eu le problème de la compatibilité du code entre Mozilla Firefox et IE de Microsoft. Pour régler ce problème est arrivé JQuery, qui a vraiment été une bénédiction. Avec lui tout devenait facile. Il a même inventé des choses génial pour parcourir le DOM ou le modifier… Oui mais cela avait un coup en terme de perfs… et il a été sur-utilisé… pire 2 librairies peuvent dépendre de JQuery mais de versions différentes, résultat le navigateur est obligé de charger les 2 différentes ce" qui est autant de coût en terme de réseau (Pas de cache), de RAM et même de processeur.
Heureusement, IE, s'est mis à respecter les standard et en plus Javascript s'est amélioré et à intégré des fonctionnalité JQuery… mais les développeurs continue a l'utiliser alors qu'il n'apporte plus grand chose. Enfin au moins dans la plupart des cas.
En Rust ce problème ce retrouve un peu moins au niveau de l'exécution proprement dites car c'est compilé… cependant cela se retrouve au niveau du temps de compilation (et calcul de dépendances) et surtout cela se retrouve en terme de lourdeur. Pour prendre l'exemple des Regexp, est-il bien nécessaire d'embarquer tout le code hyper optimisé de regexp avec cache si comme tu le dis un split ou deux suffisent. Parce que certes le binaire n'embarquera pas le code mort, mais toutes la gestion de cache et des optims ne sont pas du code mort juste du code qui n'a aucun intérêt pour un cas simple
Sous licence Creative common. Lisez, copiez, modifiez faites en ce que vous voulez.
[^] # Re: Le cas d'école JQuery de Javascript
Posté par David Delassus (site web personnel) . Évalué à 3.
La faute à celui qui audit pas ses dépendances ;)
Il y a d'abord l'argument subjectif : l'API de jQuery est plus sexy/concise/lisible que l'API vanilla.
Et ensuite, il y a l'argument un peu moins subjectif : jQuery apporte encore beaucoup, notamment tout un écosystème de plugin :
Quand tu as un site majoritairement statique, avec quelques petits endroit ou un widget interactif peu être sympa, ne pas avoir à utiliser React/Vue/Angular qui est bien plus intrusif, c'est pas déconnant.
https://link-society.com - https://kubirds.com - https://github.com/link-society/flowg
[^] # Re: Le cas d'école JQuery de Javascript
Posté par abriotde (site web personnel, Mastodon) . Évalué à 1.
Oui mais généralement, les IHM web sont développées avec d'autres framework qui embarquent leurs propre solutions.
Sinon, pour un datepicker par exemple, ok, mais la librairies peut-être compilé avec seulement les dépendances du date-picker.
Une grande partie de l'explication est surtout dans l'habitude voire la méconnaissance.
Sous licence Creative common. Lisez, copiez, modifiez faites en ce que vous voulez.
[^] # Re: Le cas d'école JQuery de Javascript
Posté par Walter . Évalué à 4.
html implémente un "datepicker". Il fait correctement le travail.
https://developer.mozilla.org/fr/docs/Web/HTML/Element/input/date
[^] # Re: Le cas d'école JQuery de Javascript
Posté par Luc-Skywalker . Évalué à 2.
Super, merci du tuyau.
J'ai vu du coup qu'un sélecteur de couleur est aussi disponible en HTML natif.
Je dirais que ça doit bien faire 7 ou 8 ans que je n'ai pas fait un site internet. Mais je me souviens d'être passé par jQuery + plugins pour avoir ces fonctionnalités.
"Si tous les cons volaient, il ferait nuit" F. Dard
# Framework
Posté par Sylvain Colinet (site web personnel) . Évalué à 5.
Les framework sont pour moi une bonne alternative, j'utilise beaucoup Qt (C++ est inutilisable de base de toute façon) et quand je code en Rust ou autre je regrette de pas avoir autant de fonctionnalité disponible en un seul endroit.
Je pense que ça va à l'encontre de la pensée de gens qui sont en mode "mais rust compile que ce que tu utilises, et pourquoi j'utiliserais un truc de 100mb pour avoir 3 boutons". D'ailleurs c'est un peu aller à l'encontre de ça de tout séparer, genre la dépendance regex à plein de sous dépendance qui pourrait surrement être groupé dans la même crate.
[^] # Re: Framework
Posté par abriotde (site web personnel, Mastodon) . Évalué à 4.
C++ fonctionne très bien sans Qt ou sans framework. C'est juste une surcouche qui apporte une solution unifié. Et aussi tente de palier les "manques" de C++ (introduction de smart-pointer et autres) un peu comme JQuery en son temps pour Javascript. C'est bien mais pas obligatoire.
Rust est encore récent, il commence à avoir des framework dans certains domaine (Web ou graphiques). Mais Rust ne souffre pas des défauts de C++, il n'a donc pas besoin d'un framework général comme l'est Qt.
Sous licence Creative common. Lisez, copiez, modifiez faites en ce que vous voulez.
[^] # Re: Framework
Posté par AnthonyRabine (site web personnel) . Évalué à 1.
Alors c'est de moins en moins vrai pour Qt car le C++ évolue bien et Qt n'est plus aussi utile que dans le passé. D'ailleurs beaucoup de code dans le coeur de Qt utilise du C++ moderne.
Par exemple, les ajouts de std::filesystem, les threads, le network…
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.