Re: Le coin des codeurs :nerd:
Publié : 18 mars 2021 00:18

Un forum réservé exclusivement aux sales casuals de merde ! \o/
https://forum.nintendojo.fr/
Le poussin a écrit : 20 mars 2021 02:55 Il y en a un qui a essayé, il a eu des problèmes.
Aux États-Unis un type a acheté la plaque d'immatriculation "NULL" pour le fun.
Un an plus tard il s'est mis à recevoir tous les PVs de véhicules non identifiés, pour des infractions datant parfois d'avant son achat.![]()
Qu'est-ce que tu appeles par "contrôle sur les erreurs" ? Il y a du typage fort, des exceptions, et la philosophie est de péter quand ça ne va pas plutôt que d'essayer de planquer les problèmes sous le tapis. Tu peux tout intercepter en fonction de tes besoins, pour contrôler ce que tu veux.
Les problèmes dans la gestion de dépendance vient plus souvent des écosystèmes et des mainteneurs des différents paquets que du langage lui-même.la gestion des dépendances
COPAIN !Golden cube a écrit : 23 mars 2021 22:59 Ce qui m'énerve le plus là dessus c'est des trucs débiles de fanboy de typage statique, de { et ;![]()
![]()
Il y a eu le passage de Python2 à Python3 qui a été très mal géré. Mais en dehors de ce cas isolé très particulier, les cassages de compatibilités du langage et de sa lib standard sont assez rares, portent sur des éléments assez marginaux, et sont d'abord dépréciés pendant plusieurs versions. À part le C, je n'ai jamais vu de langage assurant une backward compatibilité forte (même le C++ qui y tient pourtant beaucoup a fait des concessions). En général c'est du niveau de Python : on évite, avec passage par une phase de dépréciation, avec parfois une version qui casse plus que d'habitude.Golden cube a écrit : 23 mars 2021 22:59La philosophie de tout péter quand un truc ne leur plait pas est vraiment un des points que j'aime le moins dans ce langage.
Quelques Kio pour des petits programmes... mais quand tu as des grosses applications ça peut vite faire beaucoup ; pour de l'embarqué c'est plus problématique. Et il y a aussi (surtout ?) le temps de compilation qui s'en trouve rallongé.Niveau Rust, le fait de compiler statiquement à notre époque n'est pas spécialement rédhibitoire je trouve. Ce n'est pas comme si on était à quelques Kio prêt de nos jours...
Pour ce qui est du typage statique, les langages dynamiques travaillent sérieusement à fournir des alternatives, parce qu'il y a une réelle demamnde des développeurs, pour la maintenabilité. Que ça soit PHP, Python ou même JS (via TypeScript), le typage reste dynamique (parce que c'est tout de même pratique pour un langage de script), mais tu peux fournir une information qui sera vérifiée au runtime, ou alors par les outils de dev (linter, IDE, ...). Si les outils suivent, je trouve que c'est un bon compromis.Ce qui m'énerve le plus là dessus c'est des trucs débiles de fanboy de typage statique
Le typage fort, je vois pas comment on le fait et faire des blocs try/except imbriqués, c’est le cauchemar quand tu compares au vulgaire ? de Rust où tu renvoies quand y’a besoin de renvoyer et tu gères ça dans les fonctions appelantes.Le poussin a écrit : 23 mars 2021 19:24Qu'est-ce que tu appeles par "contrôle sur les erreurs" ? Il y a du typage fort, des exceptions, et la philosophie est de péter quand ça ne va pas plutôt que d'essayer de planquer les problèmes sous le tapis. Tu peux tout intercepter en fonction de tes besoins, pour contrôler ce que tu veux.
Et on parle de poetry ? Pipx ? Setuptools ? Ou la combo de tout ça ?Le poussin a écrit : 23 mars 2021 19:24Les problèmes dans la gestion de dépendance vient plus souvent des écosystèmes et des mainteneurs des différents paquets que du langage lui-même.la gestion des dépendances
- pip n'est pas parfait mais je le préfère largement à npm qui, les quelques fois où j'ai dû l'utiliser, ne garantissait même pas que les dépendances précisées étaient installées.
- C++ ne propose rien ; il existe une myriade de solutions concurrentes.
- Rust/cargo est un genre de mélange entre pip et npm : ça marche mais il n'y a pas de partage des dépendances, tout est compilé d'un bloc (statiquement ?) quitte à avoir 10 versions du même code (à compiler autant de fois)... Et si tu as des dépendances en C à compiler, tu te retrouves avec les galères usuelles de version de lib, link, etc. (sous Windows j'en parle même pas).
- PHP, Perl, Ruby ont des équivalents de pip (jamais trop testé, mais je ne doute que ça soit beaucoup mieux).
- Java/C# j'en sais rien.
- Go... même le versionning de protobuf par Google est incompréhensible.
Je ne sais pas gérer les erreurs inattendus autrement que par try/catch d'exceptions. Quelle est cette sorcellerie de "Result<Option>" ?Mortal a écrit : 24 mars 2021 09:55Le typage fort, je vois pas comment on le fait et faire des blocs try/except imbriqués, c’est le cauchemar quand tu compares au vulgaire ? de Rust où tu renvoies quand y’a besoin de renvoyer et tu gères ça dans les fonctions appelantes.Le poussin a écrit : 23 mars 2021 19:24Qu'est-ce que tu appeles par "contrôle sur les erreurs" ? Il y a du typage fort, des exceptions, et la philosophie est de péter quand ça ne va pas plutôt que d'essayer de planquer les problèmes sous le tapis. Tu peux tout intercepter en fonction de tes besoins, pour contrôler ce que tu veux.
Les try/catch, c’est vraiment des méthodes archaïques avec lesquelles j’ai de plus en plus de mal. Une fois que tu as goûté au Result<>/Option<>, c’est compliqué de revenir en arrière.
Result<T, E> et Option<T> sont des smartpointers. En gros Result<T, E> contient soit un type (Ok(T)) soit une erreur (Err(E)) et y’a plein de fonctions permettant de décapsuler ça intelligemment.nazlurf a écrit : 24 mars 2021 10:28 Je ne sais pas gérer les erreurs inattendus autrement que par try/catch d'exceptions. Quelle est cette sorcellerie de "Result<Option>" ?
Code : Tout sélectionner
fn cache_media(u: &str, t: &str) -> Result<String, Error> {
// create dir
if !Path::new(t).is_dir() {
create_dir_all(t)?;
}
// get file
let client = Client::new();
let mut response = client.get(u).send()?;
// create local file
[…]
let mut dest_file = File::create(&dest_filepath)?;
copy(&mut response, &mut dest_file)?;
Ok(dest_filepath)
}
Un T est forcément dans un Ok() alors qu’un E est forcément dans un Err(). D’où le renvoi de Ok(T) à la fin de la fonction. Tu peux même renvoyer Ok(()) si tu veux juste dire que ça a marché sans renvoyer quoique ce soit.
La compilation en rust est lente, c'est un problème (re)connu par la commuanuté de Rust.Le temps de compilation avec les machines actuelles franchement je ne pense pas que ce soit vraiment problématique.
En Rust, l'unité de compilation est la "crate". Il y a des optimisations du compilateur qui peut parfois reconnaître que certains bouts n'ont pas changé, mais ça n'est pas révolutionnaire non plus. Le temps de link est également assez important. Sur un petit projet perso avec du code un peu générique, ça prennait du temps. Tout dépend ce que tu es prêt à accepter bien sûr...Mon utilisation de Rust reste assez marginale mais j'imagine que dans tous les cas la chaine de compilation ne s'amuse pas à tout recompiler à chaque fois.
Du coup je ne pense pas que cela soit trop méchant quand tu développes dessus de manière régulière.
Les informations de type aident à détecter des erreurs humaines, qu'on fait tous. Sachant qu'elles sont facultatives, pourquoi s'en priver ? Elles ont un deuxième rôle très important : elles permettent de mieux documenter les interfaces.Souvent on fait le choix de rester sur la mauvaise technologie par facilité ou ignorance, ce n'est pas vraiment au langage de s'adapter à la connerie de ses utilisateurs je trouve.
Le typage en Python est fort, c'est un fait. Pour faire court il l'est parce qu'il n'y a pas de conversions implicites de types, ou la possibilité de comparer des choux et des carottes. PHP, Javascript ou le shell ont un typage faible : typiquement, `"42" == 42`.Le typage fort, je vois pas comment on le fait
Là où tu utilises `?` en Rust, tu peux juste laisser l'exception, c'est l'équivalent (tu "forwardes" l'erreur sans t'y intéresser ou chercher à la convertir).et faire des blocs try/except imbriqués, c’est le cauchemar quand tu compares au vulgaire ? de Rust où tu renvoies quand y’a besoin de renvoyer et tu gères ça dans les fonctions appelantes.
Ok, je comprends mieux ton point.C’est pas tellement pip (ou ses potes) qui est une purge (me suis mal exprimé, finalement, il fait son boulot), c’est tout le bordel qu’on a ajouté derrière
Je te crois volontiers j'ai juste fait quelques merdouilles dessus pour tester rapidement.Le poussin a écrit : 24 mars 2021 20:13La compilation en rust est lente, c'est un problème (re)connu par la commuanuté de Rust.Le temps de compilation avec les machines actuelles franchement je ne pense pas que ce soit vraiment problématique.
Et même avec les machines actuelles, ça reste un problème. Faire de Go un langage compilé rapidement était d'ailleurs un des objectifs de Google, parce que ça a des effets bénéfiques sur le développement en général (et pas uniquement de rentabiliser le temps des ingénieurs).
Ah... c'est pas foufou en effetLe poussin a écrit : 24 mars 2021 20:13En Rust, l'unité de compilation est la "crate". Il y a des optimisations du compilateur qui peut parfois reconnaître que certains bouts n'ont pas changé, mais ça n'est pas révolutionnaire non plus. Le temps de link est également assez important. Sur un petit projet perso avec du code un peu générique, ça prennait du temps. Tout dépend ce que tu es prêt à accepter bien sûr...Mon utilisation de Rust reste assez marginale mais j'imagine que dans tous les cas la chaine de compilation ne s'amuse pas à tout recompiler à chaque fois.
Du coup je ne pense pas que cela soit trop méchant quand tu développes dessus de manière régulière.
Là je dirais que ça dépend des approches. Quand je commence à me rendre compte qu'il me faut des surcouches sur la technologie que j'utilise (langage, protocole, etc) pour que ce soit fonctionnel et maintenable je me dis que je ne suis peut être pas parti sur la bonne architecture.Le poussin a écrit : 24 mars 2021 20:13Les informations de type aident à détecter des erreurs humaines, qu'on fait tous. Sachant qu'elles sont facultatives, pourquoi s'en priver ? Elles ont un deuxième rôle très important : elles permettent de mieux documenter les interfaces.Souvent on fait le choix de rester sur la mauvaise technologie par facilité ou ignorance, ce n'est pas vraiment au langage de s'adapter à la connerie de ses utilisateurs je trouve.
Ça n'est pas une fonctionnalité pour s'adapter aux mauvais développeurs. C'est aussi (surtout ?) plébicité par des développeurs aguerris, qui en voient les avantages. Sachant que le but n'est pas non plus de vouloir en mettre partout. Comme tout, c'est à utiliser à bon escient, quand c'est justifié.
Je rajouterais la famille C dans le pot des langages faiblement typésLe poussin a écrit : 24 mars 2021 20:13Le typage en Python est fort, c'est un fait. Pour faire court il l'est parce qu'il n'y a pas de conversions implicites de types, ou la possibilité de comparer des choux et des carottes. PHP, Javascript ou le shell ont un typage faible : typiquement, `"42" == 42`.Le typage fort, je vois pas comment on le fait
Pareil, j'ai l'impression que c'est la fusion de la remontée d'erreur par code fonction du C et les exceptions. C'est peut être génial à l'usage mais je n'ai pas assez pratiqué la chose pour avoir l'illumination.Le poussin a écrit : 24 mars 2021 20:13Là où tu utilises `?` en Rust, tu peux juste laisser l'exception, c'est l'équivalent (tu "forwardes" l'erreur sans t'y intéresser ou chercher à la convertir).et faire des blocs try/except imbriqués, c’est le cauchemar quand tu compares au vulgaire ? de Rust où tu renvoies quand y’a besoin de renvoyer et tu gères ça dans les fonctions appelantes.
Si tu veux tester/vérifier l'erreur, tu fais un try/except en Python et un match sur le type d'erreur en Rust, c'est kif-kif.
Au passage, la gestion d'erreur en Rust est... peu claire. Il n'y a pas de consensus sur les bonnes pratiques (j'ai cru lire qu'un groupe allait se former pour répondre au besoin), définir ses erreurs est assez lourd, ... Mais le langage est jeune, il faut le temps que ça se mette en place.
ça j'avais saisi ... j'ai pas compris comment, à l'utilisation de la méthode, tu sais s'il y a eu erreur ou pas. t'as que montré des appels où osef, si exception il y a, renvoie là à la couche du dessus.Mortal a écrit : 24 mars 2021 18:57Un T est forcément dans un Ok() alors qu’un E est forcément dans un Err(). D’où le renvoi de Ok(T) à la fin de la fonction. Tu peux même renvoyer Ok(()) si tu veux juste dire que ça a marché sans renvoyer quoique ce soit.
Code : Tout sélectionner
// get user timeline feed (Vec<tweet>)
let mut feed = get_user_timeline(&config, token, last_tweet_id).unwrap_or_else(|e|
panic!("Something went wrong when trying to retrieve {}’s timeline: {}", &config.twitter.username, e)
);
Code : Tout sélectionner
// build basic status by just yielding text and dereferencing contained urls
let mut status_text = match build_basic_status(tweet) {
Ok(t) => t,
Err(e) => {
println!("Could not create status from tweet {}: {}", tweet.id ,e);
continue;
},
};
Sous le capot c'est uniquement de la remontée de code d'erreur, mais typée, ce qui permet d'avoir un fonctionnement homogène.j'ai l'impression que c'est la fusion de la remontée d'erreur par code fonction du C et les exceptions
Rust utilise l'idiome RAII (Resource Acquisition Is Initialization), qui veut qu'une variable est détruite (avec appel du destructeur) quand elle sort du scope.Donc plus besoin d'un bloc finally ?