Rust 0.11 est sorti le 2 juillet 2014 ! Pour rappel, Rust est un langage de programmation système qui vise la performance et la sûreté. Il est développé par Mozilla, en parallèle d'un nouveau moteur de rendu expérimental écrit en Rust, Servo.
Rust est open source. Son développement est fait de façon ouverte sur GitHub et le code source est publié sous double licence Apache 2.0 et licence MIT.
Sommaire
Rapide présentation de Rust
Objectifs du langage
L’objectif de Rust est d’être un langage pour l’écriture de programmes systèmes, habituellement écrits en C++. Tout comme C++, Rust permet un contrôle explicite de la gestion de la mémoire et d’autres fonctionnalités du système d’exploitation et du matériel, pour écrire des programmes les plus efficaces possibles.
Rust diffère cependant de C++ en mettant l’accent sur la sûreté : grâce à un système de types fort et à l’intégration dans ce système de types de nombre d’idiomes de gestion de la mémoire (on y retrouve les sémantiques d’ownership, de move, mais également des concepts plus innovants comme l’analyse des lifetimes), le compilateur est capable de détecter à la compilation un très grand nombre d’erreurs qui en C++ auraient pu mener à des bugs, voire à des failles de sécurité potentielles.
En outre, Rust amène également au monde de la programmation système et impérative certaines fonctionnalités récentes issues de la programmation fonctionnelle : types algébriques, filtrage par motif (pattern matching), fermetures lexicales (closures), etc.
En bref, Rust se veut un remplaçant à C++ : moins complexe, plus sûr et plus moderne.
Rust étant développé au sein de Mozilla, on peut se demander s’il est prévu que Rust soit utilisé dans FirefoxOS, ce n’est pas encore le cas, bien que des essais aient été faits.
Exemple
Voilà un exemple d’une implémentation simpliste de ls
:
use std::os;
fn list_dir(path: &Path) {
match std::io::fs::walk_dir(path) {
// Le chemin donné par l’utilisateur n’est pas valide
None => fail!("Unable to retrieve path: {}", path.display()),
// Le chemin donné par l’utilisateur est valide, on liste les fichiers dedans
Some(dir) => for file in dir {
println!("{}", file.display());
}
}
}
fn main() {
// On récupère les arguments passé via la ligne de commande
let argv = os::args();
// On vérifie que le nombre d’arguments donnés est bien conforme à ce qu’on attend.
match argv.len() {
// S’il n’y a pas d’argument, on utilise le répertoire courant comme répertoire à traiter
1 => list_dir(&os::getcwd()),
// S’il y a un argument, on le considère comme répertoire à traiter.
2 => list_dir(&Path::new(argv[1])),
// Sinon, on considère que l’utilisateur tape avec des moufles.
_ => {
println!("You must specify exactly zero or one path");
os::set_exit_status(1);
}
}
}
La communauté Rust
Rust est développé par Mozilla, qui emploie une équipe à plein temps pour travailler sur le langage, mais aussi par de très nombreux contributeurs : de 51 pour la version 0.1, 450 pour la 0.10 à 559 pour cette dernière version. Des statistiques plus détaillées sont disponibles sur le site RustStat.
Plusieurs moyens de communication existent sur Internet :
- les canaux IRC Rust sur irc.mozilla.org :
-
#rust
— discussion générale ; -
#rust-gamedev
— développement de jeux ; -
#rust-internals
— compilateur et bibliothèques ; -
#rust-osdev
— développement de systèmes d’exploitation ; -
#rust-fr
— communauté Rust francophone ;
-
- la communauté Rust sur Reddit ;
- sur Twitter, les mots-clés
#rustlang
et les comptes@rustlang
et@rustlang_fr
(peu utilisés) ; - le wiki ;
- un site pour les coréens : http://rust-kr.org/.
Rust a aussi des pages sur Google Plus et sur Facebook, ainsi qu’un mot-clé #rustlang
, mais il n’y a pas d’activité particulière dans ces pages ; ce sont des rappels de Reddit.
On peut aussi remarquer que désormais LinuxFr.org fait partie de la mouvance avec sa propre étiquette rust
;) qui permet de retrouver facilement toutes les dépêches et tous les journaux abordant ce sujet.
Les échanges se font aussi directement lors d’évènemements.
Installation
Le tutoriel officiel détaille l’installation sur les différentes plateformes, cependant il faut aller dans le wiki pour avoir plus de détails.
Les procédures d’installation déjà en place pour la version 0.8 (pour Windows, Ubuntu, Arch Linux et Gentoo) décrites dans la dépêche ad hoc sont toujours valables et ont été mises à jour pour cette version. Dès l’annonce, les paquets pour Ubuntu ont été générés dans le PPA hansjorg/rust
, une compilation pour Arch est disponible dans le dépôt community
et pour Gentoo, l’overlay rust
contient un ebuild pour cette version.
Voici rapidement les commandes à utiliser pour installer la dernière version :
# Sous tout type de Linux 64bits
curl -O http://static.rust-lang.org/dist/rust-0.11.0-x86_64-unknown-linux-gnu.tar.gz
tar xfz rust-0.11.0-x86_64-unknown-linux-gnu.tar.gz
(cd rust-0.11.0-x86_64-unknown-linux-gnu/ && sudo ./install.sh)
# Sous Arch, disponible dans les paquets officiels
# Sous Gentoo
sudo layman -a rust
sudo emerge --autounmask =rust-0.11.0
# Sous Ubuntu
sudo add-apt-repository ppa:hansjorg/rust
sudo apt-get update
sudo apt-get install rust-0.11
Pour Fedora, vous pouvez compiler en Rust en regardant ici ou là.
Changements du langage
De nombreux changements de syntaxe, de sémantique, de bibliothèques sont advenus depuis la dernière version. Par exemple, le développeur de Angolmois a dénombré les changements qu’il a dû apporter à son code entre chaque version, depuis la 0.6. Moins de changements de code ont été nécessaires entre la 0.10 et la 0.11.
Syntaxe
Le symbole ~
a été remplacé par le type Box<T>
pour dénoter les owned boxes, et par le mot-clé box
pour l’allocation. De plus, les tableaux ~[T]
et les chaines ~[str]
ont été remplacées respectivement par Vec<T>
et String
. Comme il s’agit d’un changement très important et souvent mal compris par la communauté, voici une brève explication :
La précédente syntaxe causait de nombreuses confusions, du fait que ~[T]
et ~str
étaient en fait des structures particulières, et non pas de simple pointeurs ~
vers [T]
ou str
, ces derniers n’étant pas des types en Rust. Ceci menait à la bizarrerie syntaxique suivante :
// x est de type ~str, une chaîne allouée sur le tas, redimensionnable
// du fait qu’elle possède la mémoire pointée
// de même, y est de type ~[T], un vecteur redimensionnable alloué sur le tas
let x = ~"foo";
let y = ~[1, 2, 3];
// x est de type ~(&'static str), un pointeur vers une zone allouée sur le
// tas contenant un pointeur vers une chaîne statique
// y est de type ~([T, .. 3]), un pointeur vers une zone allouée sur le tas
// contenant un tableau statique à 3 éléments
let x = ~("foo");
let y = ~([1, 2, 3]);
Les structures ~[T]
et ~str
étaient en fait des structures situées sur la pile, contenant 3 champs :
- un pointeur vers une zone mémoire sur le tas ;
- la taille de cette zone, ou « capacité » ;
- et la partie de cette zone occupée par des données valides, soit la longueur de la chaine ou du tableau.
Ces structures implémentent des chaines et des tableaux dits « redimensionnables », car lors d’un ajout, si la capacité n’est plus suffisante, on met à jour le pointeur vers une zone plus grande, et on recopie depuis l’ancienne. Puisque ces structures possèdent leurs données et disposent de sémantiques de déplacement, personne ne possède de pointeur sur l’ancienne zone, qui peut alors être libérée en toute sûreté.
La sémantique de Rust étant devenue suffisamment puissante pour permettre d’exprimer ces propriétés sur des types tiers, ces structures ne nécessitent plus en aucun cas d’être intégrées au compilateur, et ont été déplacées vers la bibliothèque standard, sous les noms de String
et de Vec<T>
. On peut d’ailleurs noter que String
n’est qu’une couche d’abstraction sur Vec<u8>
fournissant des méthodes supplémentaires pour garantir que les données sont une chaîne UTF-8 valide.
De même, la syntaxe ~
pour représenter un simple pointeur vers le tas possédant la zone pointée (owned box, ou owning pointer), a été remplacée par Box<T>
pour désigner le type et par l’expression box foo
réalisant une allocation dynamique et renvoyant un Box<T>
.
Cette syntaxe n’ayant plus rien en commun avec String
et Vec
, il n’y a plus de confusion possible. Si foo est de type T
, box foo
renverra toujours un Box<T>
(équivalent de l’ancien ~T
), de même que box (foo)
.
let x = box "foo"; // x est de type Box<&'static str>.
let x = box ("foo"); // pareil.
let x = box 5; // x est de type Box<int>.
Si l’on désire maintenant utiliser les chaînes et les tableaux redimensionnables, il faut être explicite et utiliser les noms String
et Vec
:
// la méthode from_str alloue une zone de mémoire suffisamment grande
// et y recopie le contenu d’une autre chaine, ici une chaine statique
// foo est de type String
let foo = String::from_str("foo");
// from_slice alloue une zone de mémoire suffisamment grande et y recopie
// le contenu d’un autre tableau, ici un tableau statique
// bar est de type Vec<int>
let bar = Vec::from_slice([1, 2, 3]);
// on pourrait également utiliser cette version, équivalente, qui utilise
// la macro vec!, fournissant une façon pratique d’initialiser des Vec
let bar = vec!(1, 2, 3);
Cette nouvelle syntaxe montre bien que String
et Vec
sont en fait des structures sur la pile référençant une zone mémoire redimensionnable sur le tas.
Ces types sont munis d’un destructeur, ce qui garantit qu’ils disposent de déplacement (move semantics) et qu’ils possèdent les données pointées.
Ceci évite donc la confusion entre ces types et Box<T>
qui n’ont rien à voir entre eux.
Par ailleurs, écrire let x = ~"foo"
pouvait faire oublier au programmeur qu’il s’agissait d’une opération couteuse. On avait l’impression qu’il suffisait de prendre un pointeur sur une string, alors qu’il faut en fait allouer une zone sur le tas de la bonne taille, puis recopier la chaine. String::from_str est plus explicite, d’autant plus qu’elle est documentée, du fait qu’elle soit dans la bibliothèque standard et non une fonctionnalité intégrée au langage.
Enfin, bien que ~[]
et ~str
soient encore disponibles pour le moment, ils devraient être supprimés rapidement. Leur utilisation dans la base de code du compilateur et de la bibliothèque standard a déjà été pratiquement supprimée.
Notons que le pointeur @
qui a été placé derrière une feature gate (il devait être activé explicitement pour pouvoir être utilisé) lors de la sortie de rust 0.10 a été lui aussi été complètement supprimé.
Unboxed closures
Le système de fermetures (ou closures) de Rust a été complètement repensé.
Rust offrait actuellement deux types de fermetures : les stack closures et les « procédures ».
Les stack closures, qui capturaient les variables libres depuis leur environnement par référence. Ce type de fermetures était très utilisé dans du code Rust, mais du fait qu’elle ne possédaient pas leur environnement, elles n’étaient pas à proprement parler des valeurs de première classe. En particulier, il n’était possible de renvoyer une clôture sur la pile (stack closure) qu’à condition de la lier à une durée de vie (lifetime).
// la fonction get_adder prend un entier et renvoie une fermeture
// additionnant cet entier (capturé) à un autre passé en argument
fn get_adder(x: uint) -> (|uint| -> uint) {
// on renvoie une fonction prenant y et renvoyant x + y
// x est ici capturé par référence
|y| { x + y }
}
fn main() {
let add5 = get_adder(5);
let r = add5(3);
}
Ce code produisait une erreur du borrow-checker. Si ce code avait été exécuté, l’appel de add5 aurait tenté d’accéder à x via une référence pointant vers une zone mémoire qui n’est plus valide, x étant détruit à la fin de la fonction get_adder
. On aurait pu paramétrer les types par des lifetimes et passer x à get_adder
par référence, mais cela n’aurait pas totalement résolu le problème. Il n’aurait en aucun cas été possible d’utiliser add5 en dehors de la portée des variables capturées (ici, x).
Les « procédures » (notées proc
), qui capturaient leur environnement par copie (en effectuant éventuellement un move). Ces fermetures étaient des valeurs de premier ordre, mais elles permettaient ensuite au code de la fermeture d’effectuer un move depuis les variables capturées au moment où la fermeture était exécutée. Ceci permettait à ces fermetures d’utiliser leur environnement de n’importe quelle façon, mais ne permettait de les appeler qu’une seule fois, car leur environnement était « consommé » par l’appel de la fermeture, du fait des moves possibles.
fn get_proc(x: uint) -> (proc(uint) -> uint) {
proc(y) { x + y }
// x a été capturé par valeur. Si x avait été
// doté de move semantics, toute utilisation de
// x ici aurait été une erreur car il aurait été
// déplacé dans l’environnement de la fermeture
}
fn main() {
let add5 = get_proc(5);
let huit = add5(3);
// erreur: l’appel de la procédure prend l’environnement par move
// rustc détecte ici l’utilisation d’une valeur déplacée et émet
// une erreur. Les procs ne sont donc appelables qu’une seule fois
let neuf = add5(4);
}
La proposition des unboxed closures rend le système de fermetures bien plus souple.
Toutes les fermetures captureront désormais leur environnement par copie. Les références étant des valeurs comme les autres en Rust, il sera toujours possible de capturer par référence en capturant explicitement une référence plutôt que la variable :
fn get_adder(x: uint) -> (|uint| -> uint) {
// x est ici capturé par valeur (copie). Si x avait été
// d’un type doté de sémantiques de déplacement, il n’aurait
// plus été utilisable autrement que par la fermeture car
// il aurait été déplacé vers son environnement, tout comme
// dans l’exemple avec proc
|y| { x + y }
}
// il est possible d’obtenir une capture par référence en capturant
// explicitement une valeur dont le type est une référence. On fait
// alors une copie de la référence
// cet exemple reproduira le comportement précédent. La fermeture
// est liée à la durée de vie de x
fn get_adder_ref(x: uint) -> (|uint| -> uint) {
// on crée explicitement une référence
let ref_on_x = &x;
// la fermeture capture une copie de la référence
// et pas une copie de x
|y| { *ref_on_x + y }
}
Les unboxed closures seront implémentées comme des objets ayant chacun leur type unique contenant leur environnement. Pour refléter leur capacité à être invoquées comme des fonctions, elles devront maintenant implémenter un trait. Plusieurs traits seront introduits, pour représenter tous les cas possibles d’utilisation.
Tout d'abord, Fn
: au moment de l’appel, le code reçoit son environnement via une référence mutable. La fermeture peut donc muter son environnement, mais ne peut pas effectuer de move depuis l’environnement. La fermeture est donc appelable plusieurs fois. Ce trait reflète les sémantiques d’appel des anciennes stack closures, tout en permettant de choisir au moment de la création de la fermeture si la copie se fait par copie ou par référence.
FnShared
est similaire au précédent, à l’exception que la fermeture reçoit une référence immutable sur son environnement. Elle ne peut donc pas le modifier. L’avantage principal de ces fermetures est qu’elles peuvent être échangées de façon sûre entre différentes tâches s’exécutant de façon concurrente, d’où son nom.
Enfin, FnOnce
implémente des sémantiques d’appel des anciennes procédures en passant à la fermeture son environnement par valeur. La fermeture peut alors librement effectuer des moves depuis l’environnement, qui est alors consommé. Une fermeture ne pourra être appelée qu’une seule fois via ce trait.
La syntaxe des fermetures ne sera donc plus que du sucre syntaxique sur la déclaration d’un type implémentant le trait approprié et la création d’une valeur unique de ce type. Mais il sera également possible de créer à la main de tels objets, et d’implémenter par exemple plusieurs comportements possibles. (à vérifier)
Le système de types de Rust ayant connaissance des sémantiques de déplacement, l’implémentation des unboxed closures ne requerra pratiquement aucune modification du système de types. Les règles actuelles garantissent déjà le comportement décrit ci-dessus en fonction de la façon dont l’environnement est passé au code de la fermeture lors de l’appel.
Bibliothèque standard
La bibliothèque standard a été découpée en plusieurs petites bibliothèques indépendantes. libcore
, qui contient les fonctionnalités les plus basiques de la bibliothèque d’exécution (runtime library) du langage est ainsi autonome, et peut être utilisée dans des contextes tels que les systèmes d’exploitation ou la programmation embarquée.
Rust dispose maintenant d’une implémentation des expressions rationnelles, inspirée de RE2. Elle a été intégrée dans la distribution officielle en tant que libregex
. libregex_macros
fournit une extension de syntaxe, regex!
, qui permet à rustc
de compiler les expressions rationnelles en même temps que le reste du code.
En vrac, quelques autres modifications notables :
- attention !
test::BenchHarness
a été renommée entest::Bencher
; - la définition des vecteurs doit être plus précise :
[1, 2]
n’est plus acceptée, il faut spécifier le type, par exemple ainsi[1u, 2]
; - utilisation de
Result<T, Error>
dans les types de retour de l’interfaceSerialize
; - ajout d’une caisse GraphViz ;
- réduction de la taille des exécutables ;
- si vous vous demandez ce que Rust et Lovecraft on en commun, allez voir par ici ;
-
première bibliothèque stabilisée pour la version 1.0 :
std::mem
.
Autour du langage
Le code du dépôt Rust sur Github (compilateur, bibliothèque standard, tests unitaires et de performance ainsi que les tutoriels) a atteint les 30 000 commits le 25 juin. Voici un florilège des évènements notables :
- prise en charge de Windows 64 bits ;
- le site Are we web yet?
- un rapprochement avec Dart ?
- refonte de la documentation ;
- nouvelle URL pour la documentation : http://doc.rust-lang.org/ ;
- deux équipes ont choisi Rust dans la compétition Hello World Open ;
- le code de Rust est désormais hébergé sur Github ;
- Rust apparait en bonne position dans une comparaison de performances d’implémentations dans différents langages ;
- enfin, un petit guide pour la compilation croisée vers ARM.
Computer Language Benchmarks Game
Ce test de performance dont nous avions parlé dans la précédente dépêche sur Rust continue d’être mis à jour. Les sources des programmes de test sont en effet inclus dans les sources même de Rust (voir les fichiers shoutout-*
). Les instructions SIMD sont ajoutées aux tests à l’aide du module std::unstable::simd
, le test shootout-mandelbrot
s’exécute ainsi presque deux fois plus vite.
Test | × | CPU secs | Elapsed secs | Memory KB | Code B | ≈ CPU Load |
---|---|---|---|---|---|---|
Fasta | 1.7 | 4.66 | 4.66 | 780 | 1283 | 0% - 1% - 1% - 100% |
Pidigits | 7.2 | 12.48 | 12.49 | 1,708 | 677 | 0% - 1% - 0% - 100% |
Mandelbrot | 10 | 52.22 | 52.23 | 780 | 633 | 1% - 100% - 0% - 0% |
http://www.reddit.com/r/rust/comments/27dc75/what_happened_to_the_shootout_benchmarks/
Travis-CI
Les tests sur Travis-CI utilisant rust-nightly sont restés bloqués à la version du 18 avril. Travis-CI utilise Ubuntu Precise comme environnement et la construction automatique sur Launchpad s’est arrêtée car la version de gcc est trop ancienne. Le script configure
de Rust ne prenait pas en charge la définition des variables d’environnement CC
/CXX
pour changer de version de compilateur. Des correctifs ont été proposés le 2 mai et intégrés depuis. La construction continue chez Launchpad a repris début juin.
Cargo
Cargo est le nouveau gestionnaire de paquets annoncé le 17 mars. Yehuda Katz et Carl Lerche réalisent son développement.
Le 21 juin, le gestionnaire n’est pas encore en version alpha mais permet de résoudre les dépendances et de les récupérer depuis Git. La version alpha est publiée le 23 juin en même temps que le site web associé pour sa documentation : crates.io. Un PPA pour Ubuntu est disponible à ppa:cmrx64/cargo, pour notamment pouvoir utiliser Cargo sur Travis-CI.
Servo
Servo est un projet expérimental de Mozilla visant à construire un moteur de navigateur Web pour la nouvelle génération d’appareils : téléphones portables, processeurs multicœurs et GPU haute-performance, en tirant parti de la sûreté de Rust, et de ses facilités pour exprimer la concurrence. Il est actuellement développé pour Mac OS X et Linux 64 bits. Il a récemment passé avec succès le test Acid2, comme planifié dans les objectifs du second trimestre.
Servo: Designing and Implementing a Parallel Browser.
Liens
Récapitulatifs
This Week in Rust
Si vous voulez suivre le mouvement de tout ce qui se passe à propos de Rust sans avoir à lire le détail des commits, des annonces sur la liste de diffusion, de Reddit ou de Twitter, le blog This Week in Rust fait une synthèse hebdomadaire des nouveautés et actualités autour de Rust :
- 05/04 ;
- 13/04 ;
- 26/04 ;
- 05/05 ;
- 11/05 ;
- 17/05 ;
- 24/05 ;
- This Week in Rust devient un site à part : http://this-week-in-rust.org/ ;
- 10/06 ;
- 14/06 ;
- 22/06 ;
- 30/06.
Meeting Weekly
https://github.com/mozilla/rust/wiki/Meetings
Évènements
De nombreux évènements sont organisés autour de Rust. La rencontre parisienne se répète tous les 3es lundis du mois dans les locaux de Mozilla.
- Paris, le 21 avril — Rust MeetUp ;
- Londres, du 25 au 28 avril — Ludum Dare 29 ;
- San Francisco, le 8 mai — Rust MeetUp : vidéos disponibles sur air.mozilla : Testing Rust and Fuzzing compilers de John Regehr, QuickCheck de Andrew Gallant et Testing Hackathon de Erick Tryzelaar ;
- Paris, le 19 mai — Rust MeetUp, sur Servo ;
- Pittsburgh, le 19 mai — Rust MeetUp : Code and Supply ;
- Seattle, le 22 mai — Rust MeetUp ;
- Paris, le 16 juin — Rust MeetUp ;
- San Francisco, le 10 juin — Dinnerup ;
- Brooklyn, le 21 juin — Rust MeetUp ;
- Pittsburgh, le 23 juin — Rust MeetUp : Code and Supply ;
- Londres, le 26 juin — First Rust MeetUp in London : Awesome Rust, Servo: the parallel browser engine ;
- San Francisco, le 26 juin — Rust Meetup, vidéos disponibles sur air.mozilla.org : Library Ecosystem for Rust Game Development, OpenGL and Rust, Voyager, Reducing VR latency with Rust ;
- Lisbonne, le 2 juillet — Rust MeetUp : Goals and crash course through the tutorial ;
- San Francisco, juillet — Rust Meetup : WebTech ;
- Seattle, le 7 juillet — Rust MeetUp ;
- Hanovre, le 10 juillet — Rust MeetUp ;
- Paris, le 21 juillet — Rust MeetUp ;
Présentations
Il y aura peut-être bientôt des cours de Programmation Fonctionnelle Système en Rust à Mozilla Paris.
- A More Detailed Tour of the Rust Compiler
- Rust Me, I’m a Developer
- Guaranteeing memory safety in Rust de Nicholas Matsakis
- Programmation système robuste avec Rust de Geoffroy Couprie et Clément Delafargue à Devoxx France
- What is Rust for?
- Snowmew’s Architecture : Part 1, Part 2. Snowmew est un moteur de jeu.
Tutoriels et documentation
- Getting Rusty
- Une présentation, proposée par Steve Klabnik, a été ajoutée sur le site : A 30-minute Introduction to Rust. Elle porte sur les points clefs de Rust : la possession des données (ownership), la sémantique de déplacement ("move semantics"), et l’emprunt de données (borrowing). Steve Klabnik vient par ailleurs d’être embauché par Mozilla pour six mois afin de contribuer à la documentation à partir du 23 juin.
- Nouveau tutoriel Rust by example
- Rust for C++ programmers :
- Rust class, un cours de système dans lequel Rust est utilisé.
- Practicality With Rust: Setting Up A Project
- La documentation Rust est disponible sur Dash (visualiseur de documentation hors-ligne sur Mac).
Projets
- rust-http va être réécrit en une boîte à outils pour le développement web : teepee.rs. Les réflexions sur sa conception sont partagées sur le blog de Chris Morgan : a careful look at the HTTP/1.1 Status-Line, My first look at the Status-Line, header representation.
- rust-rosetta continue d’implémenter des exemples de Rosetta Code. 89 exemples sont disponibles au 8 juillet.
Nouveaux projets
- rust-empty, un makefile basique pour commencer un projet Rust.
- greffon IntelliJ pour la prise en charge de Rust.
- Un compte Twitter a été ouvert pour publier des astuces sur Rust.
- Rust est disponible sur site d’entrainement à la programmation exercism.io.
- Godbolt, un compilateur interactif de code Rust (affiche le code assembleur résultant).
- Un snake pour GameBoy Advance, il est probable que d’autres jeux très basiques suivront.
- ClearCrypt, une bibliothèque de chiffrement de transport utilisant CurveCP ou Noise.
- rust-nanomsg, une bibliothèque pour nanomsg.
- Dans Atom,
- atom-racer ajoute la complétion de code pour Rust dans Atom, l’éditeur de GitHub récemment libéré, en utilisant Racer et Autocomplete+
- atom-language-rust ajoute la coloration syntaxique.
- iomrascálaí une IA pour les jeux Go/Weiqi/Baduk.
- criterion.rs, une bibliothèque de test de performance traduite de la bibliothèque Haskell criterion.
- scheme.rs, une implémentation de Scheme en Rust.
- rspt, un moteur de rendu physique utilisant OpenGL 2.1, Licence ??.
- Floor, un cadriciel web inspiré de ExpressJS, licence MIT.
Conclusion
La liste des améliorations pour cette version de Rust n’est pas bien longue: modification des types Vector
s, et les String
s en préparation des types à taille dynamique (DST), la suppression de ~
et continuation du découpage de la bibliothèque standard de Rust. Tout cela a nécessité beaucoup de travail de fond, et c’est le signe que Rust gagne en maturité.
Côté communauté, on a des développeurs payés par Mozilla et Samsung qui travaillent sur Rust et Servo, des dizaines de nouveaux projets, la prise en charge de Rust dans de plus en plus de logiciels et d’environnements, et une présence sur le web toujours plus importante, Rust semble promis à un bel avenir.
Aller plus loin
- Site officiel de Rust (407 clics)
- Annonce de la version 0.11 (32 clics)
- Tag `rust` sur Linuxfr (journaux et dépêches sur Rust) (113 clics)
# Bravo pour la dépêche
Posté par Pol' uX (site web personnel) . Évalué à 7.
Du beau boulot. Plein de nouveaux onglets ouverts dans mon navigateur en fin de lecture. :)
Adhérer à l'April, ça vous tente ?
# GitHub
Posté par Olivier Renaud . Évalué à 10.
Pour être plus précis, le projet Rust est depuis très longtemps sur GitHub. Ce qui a récemment changé, c'est qu'il faisait partie du groupe GitHub mozilla, et qu'il a été déplacé dans son propre groupe rust-lang. On trouve dans ce groupe tous les dépots liés à Rust : Cargo, le site web de rust-lang.org, les RFCs, les dépendances du compilateur, etc…
[^] # Re: GitHub
Posté par ariasuni . Évalué à 4.
Oui c'est visiblement une erreur. L'idée originale, c'était:
Écrit en Bépo selon l’orthographe de 1990
# Forum officiel Rust
Posté par Sébastien Douche . Évalué à 7.
En plus des différents lieux cités (mls, IRC…) il existe maintenant un forum officiel : discuss.rust-lang.org.
Personnellement j'aurais préféré une ml, je hais les forums (push vs pull).
# boxed/unboxed ou expansion
Posté par Nicolas Boulay (site web personnel) . Évalué à 1.
Je n'ai pas bien compris l'usage de Box, est-ce qu'il s'agit du même système d'expand de Lisaac, qui permet d'éviter les cochonneries de type natif de Java (int != Integer) ?
Dans Lisaac, c'était hyper puissant, de faire la différence entre un layout mémoire "en dure" et un arbre de pointeur tel que se présente une arborescence d'objet. Typiquement, cela permettait à l'OS Isaac de coder les pixels de l'interface graphique comme des objets, sans perte de vitesse par rapport au C.
"La première sécurité est la liberté"
[^] # Re: boxed/unboxed ou expansion
Posté par claudex . Évalué à 3.
Ça n'a rien à voir,
Box<>
en Rust, c'est une allocation sur le tas.« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: boxed/unboxed ou expansion
Posté par devnewton 🍺 (site web personnel) . Évalué à 2.
Pourquoi avoir choisi ce mot box?
Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.
[^] # Re: boxed/unboxed ou expansion
Posté par ariasuni . Évalué à 3.
Parce que boxed et unboxed c’est le vocabulaire utilisé également par d’autres langages de programmation. D’autre part, ça montre bien la façon de fonctionner de Rust: lorsque la boite est supprimée, la valeur qui était à l’intérieur (boxed) est supprimée également. Et si on veut récupérer la valeur qui est à l’intérieur, on fait une copie à l’extérieur de la boite (on obtient une valeur unboxed).
Écrit en Bépo selon l’orthographe de 1990
[^] # Re: boxed/unboxed ou expansion
Posté par LupusMic (site web personnel, Mastodon) . Évalué à 1.
Quels langages utilisent cette sémantique ?
[^] # Re: boxed/unboxed ou expansion
Posté par Nicolas Boulay (site web personnel) . Évalué à 2.
C++ mélange un peu tout(transmission par valeur = expansion, transmission par pointeur = box).
Cela détermine qui gère la mémoire. La destruction d'un arbre d'objet "boxed" nécessite un GC pour savoir ce qui peut être réellement effacer. Une structure en expension avec les valeurs dedans sont détruit ensemble d'un seul coup.
En java int n'est pas boxer, Integer l'est. Cela permet par exemple d'utiliser des conteneur qui utilise le type de base Object, qui ne peut pas prendre un int. Cette blague existe pour tous les types de base.
En Ocaml, la box est complètement masquée. Les integer et les pointeurs sont codé avec un bit pour les distinguer, le reste est boxé. Le compilo peut savoir unboxer automatiquement les flottant et les tableaux de double. La box ne fait pas trop de perte de performance en Ocaml, car par défaut, une valeur n'est pas modifiable, on peut ainsi utiliser le pointeur sur la donné de base à la place, sans risque.
"La première sécurité est la liberté"
[^] # Re: boxed/unboxed ou expansion
Posté par LupusMic (site web personnel, Mastodon) . Évalué à 1.
Bon, du coup je ne comprends toujours pas cette notion.
En C++, il y a deux natures de variables : les automatiques, les dynamiques. Les variables automatiques sont automatiquement allouées lors de l'exécution du code. En général, ce sont les variables de porté locale, et sont allouées sur la pile :
Les variables dynamiques sont elles allouées à l'aide de new (ou malloc, ou mmap, ou équivalent) :
On remarquera que dans cet exemple, une variable automatique est nécessaire pour contenir l'adresse de l'objet instancié.
Ensuite tu as std::auto_ptr, std::shared_ptr, std::unique_ptr, boost::scoped_ptr qui permettent de gérer automatiquement la libération de l'objet quand l'objet n'est plus référencé.
Bref, qu'est-ce qui est « boxé », et en quoi l'objet est en boîte ou non ?
[^] # Re: boxed/unboxed ou expansion
Posté par Mildred (site web personnel) . Évalué à 1.
Donc si je comprends bien,
Box<>
est l'inverse duExpanded
. Un typeExpanded
est un type sur la pile et un type nonExpanded
correspond a un pointeur vers une zone mémoire sur le tas (équivalent duBox<>
donc)[^] # Re: boxed/unboxed ou expansion
Posté par Nicolas Boulay (site web personnel) . Évalué à 2.
"Boxed" est le terme classique notament en java. Cela veut dire que chaque objet est dans sa propre zone mémoire, est n'est inclus dans d'autre structure qu'uniquement au travers de pointeurs. Dans le cas de petit objet, c'est une catastrophe pour les performances. "Expended" permet de rester full objet, mais sans la "box" (et une restriction sur l'héritage dynamique aussi).
Expended n'est donc pas uniquement une allocation sur la pile.
"La première sécurité est la liberté"
[^] # Re: boxed/unboxed ou expansion
Posté par ariasuni . Évalué à 2. Dernière modification le 15 juillet 2014 à 14:58.
En Rust, les types natifs ont les mêmes propriétés que les objets (on peut leur implémenter des méthodes) sans surconsommation mémoire ou processeur. Il est donc possible d’avoir une variable de type
Box<int>
, qui est un pointeur vers un entier alloué sur le tas.Écrit en Bépo selon l’orthographe de 1990
[^] # Re: boxed/unboxed ou expansion
Posté par El Titi . Évalué à 3.
Pourquoi t'exprimes-tu à l'imparfait ?
Lisaac est-il mort ?
Plus de troll sur le meilleur langage du monde … Sniff !!!
[^] # Re: boxed/unboxed ou expansion
Posté par Nicolas Boulay (site web personnel) . Évalué à 3.
Disparu avec son créateur.
"La première sécurité est la liberté"
# Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par reno . Évalué à -1.
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par ariasuni . Évalué à 2.
Je pense que c’est majoritairement en rapport avec l’internationalisation. On peut vouloir changer le nom des variables parfois, ou la façon dont on accède à un nom par exemple (dans un cas ça sera directement une chaine, dans l’autre une entrée d’un tableau…). On peut vouloir changer la valeur qui apparaitra dans la chaine sans changer la variable, dans ce cas-là soit on met le calcul dans la chaine dans ta proposition, soit on créé une nouvelle variable. Pour une traduction, c’est plus facile d’avoir un nom signifiant qu’un nom de variable (avec éventuellement un calcul abscons).
Pour plus d’infos sur les possibilités, voir la doc.
Écrit en Bépo selon l’orthographe de 1990
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par reno . Évalué à 2.
Euh, il me semble que tout ce que tu dis, on peut le faire en Perl avec en plus l'avantage que tu as une syntaxe lisible pour les programmes tout simple ou tu n'as pas l'internationalisation..
De plus je ne vois pas l'avantage de faire printf!("{u}, u = v); par rapport à
my $u = $v;
print("$u");
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par claudex . Évalué à 3.
Je trouve intéressant de pouvoir faire
Je trouve ça plus lisible. Et je trouve aussi plus lisible de pouvoir n'avoir que
{}
, ça permet de distinguer plus facilement la partie statique de la partie variable.« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par reno . Évalué à 1.
Pouvoir faire ça, ok ça peut être intéressant, mais ne pouvoir faire QUE ça, c'est ça qui me choque, pourquoi je ne peut pas faire println!("plop: {ma_variable}");
au lieu de devoir faire println!("plop: {u}", u = ma_variable);
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par claudex . Évalué à 4.
Ça me semble normal si on ne veut éviter les variables globales. En fait la chaîne est passée à la fonction fmt qui ne connait bien sûr pas les variables déclarées, c'est donc normale de spécifier quelles variables doivent être passées.
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par reno . Évalué à 3.
Note que ce n'est pas une fonction, c'est une macro donc comme c'est a la compilation, je pense qu'on peut extraire le nom de la variable de la chaine et c'est le compilateur qui hurle plus tard si la variable n'est pas déclarée..
En D, un mixin doit pouvoir faire ça.
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par whity . Évalué à 3.
En vrac :
- comme l’a dit sinma, dans le cas de l’internationalisation, tu rends ta chaîne dépendante d’un paramètre nommé qui lui est indépendant de ton code -> couplage faible, évolution plus facile.
- en cas de refactorisation de code, tu peux changer la manière dont est calculée la variable sans changer la chaîne.
- toujours dans le cadre d’une refactorisation de code, il sera beaucoup plus facile pour l’analyseur de déterminer quand et où est utilisée une variable que si elle peut apparaître n’importe où dans une chaîne.
Rust est conçu et pensé pour permettre de vérifier un maximum de chose dès la compilation. On est à des années lumière de la philosophie de perl de ce côté là. La syntaxe des chaînes en fait partie. Libre à toi de la trouver contraignante, personnellement elle ne me choque pas. Les placeholders nommés, c’est même un gain par rapport à ce qu’on a dans la plupart des langages.
Mes commentaires sont en wtfpl. Une licence sur les commentaires, sérieux ? o_0
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par reno . Évalué à 4.
La plupart des langages?
Ça ne me parait pas un argument valide pour un nouveau langage, il devrait autant que possible reprendre le meilleur des langages existants!
Ah, j'imagine que certains trouvent la comparaison de Rust avec Perl ou Ruby biaisée car ces derniers sont interprétés, mais avec Scala la syntaxe est similaire..
Qui préfère lire
println!("texte {}", variable) ou println!("texte {v}, v = variable); (Rust)
a
println(s"texte $variable") ou println(s"texte ${variable}") (Scala)
?
Quand le nombre de variables augmente, je trouve la version Scala/Perl/Ruby bien plus lisible..
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par claudex . Évalué à 2.
Et bien moi, c'est justement l'inverse. Surtout quand je dois chercher une faute d'orthographe dans la chaîne.
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par reno . Évalué à 3.
Ah? Ça ne me gène pas beaucoup personnellement..
Et les conséquences d'une faute d’orthographe me paraissent bien plus anecdotique que les conséquences d'un mauvais ordonnancement des variables, ce qui est très classique avec ce type de format string: modifier la chaine sans modifier la liste des variables en conséquence ou vice versa..
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par neil . Évalué à 2.
L’avantage de la syntaxe non-Rust c’est qu’on peut introduire des failles de sécu en changeant LC_LANG.
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par reno . Évalué à 4.
Tu peux expliquer/détailler par un exemple concret?
En Scala par exemple..
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par ariasuni . Évalué à 3.
Je pense que tu as mal lu:
Les placeholders nommés, ça vient d’autres langages (comme Python par exemple).
Écrit en Bépo selon l’orthographe de 1990
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par Fabimaru (site web personnel) . Évalué à 2.
Ce n'est pas pour l'internationalisation. «print!» est une macro (comme le point d'exclamation l'indique) qui va vérifier que les paramètres de la chaine de formatage sont corrects. Par exemple avec "{0} {1}" il doit y avoir deux paramètres additionnels. Cette vérification est faite à la compilation (ce qui est bien, comme ça ça n'implique pas un surcout d'analyse de la chaine à l'exécution).
Par contre, on est obligé de mettre une chaine littérale, sinon:
error: format argument must be a string literal.
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par Sébastien Douche . Évalué à 1.
Ah ?! Moi c'est leur x::y::z que je ne peux pas voir en peinture :).
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par ariasuni . Évalué à 1.
Sinon on peut continuer à lister toutes les choses que vous n’aimez pas dans Rust au lieu de ce concentrer ce sur quoi il est vraiment innovant (le prend pas pour toi, hein).
Hé oui, la syntaxe d’un langage ne peut pas être parfaite. Mais globalement, soit ils reprennent une syntaxe existante, soit ils en inventent une qui a du sens par rapport aux objectifs du langage.
Écrit en Bépo selon l’orthographe de 1990
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par Stibb . Évalué à 1.
Python utilise une syntax similaire et elle est effectivement très puissante:
"toto {tata}".format(tata="tutu")
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par reno . Évalué à 1.
Puissante, puissante.. Ça se discute.
Je ne vois pas trop en quoi c'est plus puissant que l'équivalent en Scala (la même chose existe en Perl, Ruby):
tata="tutu"
"toto ${tata}"
mis à part que la syntaxe Python/Rust viole la règle DRY (ne pas se répéter)..
Si tu as une variable avec un nom bien clair alors "toto ${ma_variable}" est court et bien lisible mais la syntaxe Python/Rust impose d'ajouter un renommage supplémentaire même dans ce cas ("toto {foo}",foo=ma_variable)..
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par flan (site web personnel) . Évalué à 2. Dernière modification le 21 juillet 2014 à 22:58.
Ça permet de passer toutes les variables dans un dictionnaire, sans forcément les connaître à l'avance. De plus, elle permet un formatage supplémentaire grâce aux indications (nombre de chiffres, remplissage avec des espaces, …). Petit exemple rapide en Python
La syntaxe "toto ${ma_variable}" impose que ma_variable soit définie quand tu te sers de la chaîne de caractère. La syntaxe Python n'importe aucune contrainte sur les variables.mes_variables = {'ma_variable': 42, 'foo': -1}
"toto %(ma_variable)s %03(foo)d" % mes_variables
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par xcomcmdr . Évalué à 0.
Je trouve toujours la syntaxe "toto #{ma_variable}" beaucoup plus lisible.
La version python, c'est bien, mais je ne vois pas l'intérêt (l'exemple est trop court ;-) ), surtout face à la perte de lisibilité.
"Quand certains râlent contre systemd, d'autres s'attaquent aux vrais problèmes." (merci Sinma !)
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par reno . Évalué à 1.
Ce qui est rarement utile.. Rendre moins lisible et moins maintenable la syntaxe la plus utilisée pour une possibilité rarement utilisée, bof!
Et alors? Avoir des formats strings lisibles n’empêche pas d'avoir des formatages supplémentaire..
En Scala, ça donne ça: println(f"$name%s is $height%2.2f meters tall")
J'ai l'impression qu'il y en a pas mal qui se disent, c'est comme ça que c'est fait en Python donc c'est forcément bien!
Désolé mais si la lisibilité est subjective, la maintenable ne l'est pas elle et
1) mettre les variables séparément des chaines ("foo {} faa {}",var1,var2) est moins maintenable que ("foo $var1 faa $var2")
2) en utilisant les places holders nommés tu peux récupérer la maintenabilité ("foo {u} faa {v}",u = var1, v = var2) MAIS c'est au prix d'une verbosité et d'une redondance supplémentaire par rapport à ("foo $var1 faa $var2") (si le nom des variable est trop moche pour mettre directement dans la format string c'est un problème entre la chaise et le clavier, pas un problème de langage).
Alors OK, les places holder nommés permettent quelques trucs supplémentaires utile dans 1% des cas, mais ça reste une syntaxe pas terrible pour le cas par défaut.
De mon point de vue, les concepteurs de Python ont merdé sur ce point là, ça arrive et après c'est difficile de changer donc ils sont coincés OK, mais que les dev de Rust copient Python sans améliorer la syntaxe par défaut là..
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par claudex . Évalué à 7.
Franchement, je trouve ça illisible.
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par reno . Évalué à 3.
Comme je le disais, la lisibilité c'est subjectif, bien que n'utilisant pas Scala je trouve ça plus lisible que la version Python, alors?
Alors ça ne veut RIEN dire, la lisibilité c'est plus une question d'habitude qu'autre chose.
Par contre la maintenabilité ça c'est moins arbitraire, et je pense que mes arguments sur le manque de maintenabilité de {} en Python ou la verbosité des place holders obligatoires sont plus objectif.
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par claudex . Évalué à 4.
Non ce n'est pas qu'une question d'habitude. Et la lisibilité joue beaucoup pour la maintenabilité.
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par reno . Évalué à 3.
Explique alors que je préfère la lisibilité de la version Scala/Perl/Ruby et toi celle de la version Python/Rust?
La lisibilité est principalement subjective dans beaucoup de cas..
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par claudex . Évalué à 4.
Je n'ai pas dit que ce n'était pas subjectif mais que ce n'était pas (qu')une question d'habitude.
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par xcomcmdr . Évalué à 1.
Sauf que dans la version Python/Rust/truc on se répété, ce qui nuit à la maintenabilité (DRY, tout ça).
"Quand certains râlent contre systemd, d'autres s'attaquent aux vrais problèmes." (merci Sinma !)
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par flan (site web personnel) . Évalué à 2.
Bien au contraire.
* tu peux réutiliser tes chaînes de caractères pour faire de l'internationalisation (et mettre des noms de paramètres différents pour le traducteur)
* tu peux balader ta chaîne sans la formater immédiatement (impossible avec la version $variable)
* le formatage est une opération explicite (par défaut, tu n'as pas à faire attention à un quelconque caractère spécial, c'est un nid à failles)
* tu choisis explicitement les variables que tu utilises dans ton formatage, pas besoin de vérifier que ça réutilise une variable qui n'a plus de sens
* les variables utilisées pour le formatage peuvent être baladées facilement sous forme d'une HashMap (dictionnaire Python).
* tu n'as aucune contrainte sur les noms de tes variables
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par Stibb . Évalué à 1.
Pour plus d'information, se référer à la PEP 3101:
http://legacy.python.org/dev/peps/pep-3101/
[^] # Re: Un peu de bike shedding: je n'aime pas leur syntaxe des format string
Posté par ziliss . Évalué à 3.
D'un autre côté, avec une coloration syntaxique ça doit bien améliorer la lisibilité.
# Et bha ...
Posté par Kwiknclean . Évalué à 2.
… ça m'a l'air tout de même beaucoup claire à lire que C++ quand même : )
[^] # Re: Et bha ...
Posté par Lutin . Évalué à 7.
Même les résultats de l'IOCCC sont plus lisibles que du C++ moderne.
[^] # Re: Et bha ...
Posté par keyser.dyson . Évalué à 1.
Effectivement, c'est beaucoup mieux.
L'avantage du C++ sur les nouveaux langages compilés type Rust ou Go reste la portabilité. Ca passe partout.
[^] # Re: Et bha ...
Posté par LupusMic (site web personnel, Mastodon) . Évalué à 1.
En quoi est-ce plus clair que du C++ ? Il y a bien plus d'abréviations cryptiques en Rust qu'en C++.
[^] # Re: Et bha ...
Posté par ariasuni . Évalué à 2.
Pourrais-tu préciser quels sont les «abréviations cryptiques» de Rust?
Écrit en Bépo selon l’orthographe de 1990
[^] # Re: Et bha ...
Posté par LupusMic (site web personnel, Mastodon) . Évalué à 1.
D'accord, ceux-là sont généralement assez bien compris dans le monde IT :
Mais là, je me demande quel est le projet :
Bref, je n'aime pas les abréviations, car elles introduisent une incertitude. J'en utilises, évidement, mais en très petit nombre, et de préférences définies dans leur scope d'usage.
Avoir des abréviations définies au niveau du langage est un appel aux utilisateurs du langage à en inventer d'autres. C en est plein, encore aujourd'hui des gens ont eu leur cerveau plié par cette convention qui avait une raison d'être. Oui, avait, nous ne sommes plus limités par des contraintes de place.
[^] # Re: Et bha ...
Posté par claudex . Évalué à 5.
ces abréviations sont tout aussi bien comprises que les autres.
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: Et bha ...
Posté par LupusMic (site web personnel, Mastodon) . Évalué à 1.
Le problème n'est pas qu'elles ne peuvent pas être comprises : c'est qu'elles accrochent en première lecture.
Rust est censé ne pas reproduire les erreurs du passé, rendre le code moins propices aux erreurs. Alors pourquoi employer des abréviations ?
[^] # Re: Et bha ...
Posté par tyoup . Évalué à 1.
Grâce à ça le compilo fait beaucoup moins d'io, c'est pour ça qu'il va si vite ;-) comparativement java est très lent au runtime parcequ'il gère des nom de classe très très longs (SaxParserHandlerFactoryFactoryProxyAdapter quand même… Et je vous épargne le nom du package :-D).
[^] # Re: Et bha ...
Posté par LupusMic (site web personnel, Mastodon) . Évalué à 2.
Quel est le rapport avec la choucroute ? Tu crois sincèrement que tu gagnes significativement des IO en économisant 3 caractères sur un identifier ?
Le monde Java, et par extension le monde des frameworks PHP, est terrifiant. Mais j'ose penser qu'il est possible d'avoir une voie médiane.
De plus, en C++, la longueur d'un identifier n'a pas d'influence sur le runtime stripé. Mais Java tente de fournir des fonctionnalités inutiles mais appréciées qui nécessite la manipulation des identifiers de 10 km de long.
[^] # Re: Et bha ...
Posté par ariasuni . Évalué à 2.
Hé bien c’est quand même vachement utile quand tu déclares une variable de type
Vec<Vec<Vec<int>>>
(contrevector<vector<vector<int>>>>
en C++).En C/C++/Java on utilise même pas de mot-clé spécifique pour les fonctions, en Python on utilise
def
, etc. Globalement,fn
est clairement le plus compréhensible.Et pour
proc
etmut
c’est pareil, ce sont des mots-clés de base à apprendre comme dans tous les langages, pas de quoi en faire un fromage. Surtout qu’avec le contexte .Pour les autres, tu apprends une fois ce que ça veut dire et c’est bon, c’est juste que c’est pas aussi verbeux que dans les autres .
Plus facilement compréhensible qu’
it
sans être aussi long qu’iterator
. Et ce n’est pas la première fois que je voisiter
…J’utilise des noms de variables en général assez long, mais pour le langage je n’ai pas besoin que les mots-clés et types les plus utilisés soient très long, au contraire je préfère qu’ils soient courts pour me faciliter la tâche.
D’autre part, je n’ai pas énormément utilisé le langage mais ça ne m’a posé aucune difficulté. Pas plus que les abréviations telles que
std
,def
,var
,int
,len
,str
, etc. Je pense que tu n’as pas testé et que si tu testerais, tu te rendrais compte que ce n’est pas absolument pas un problème.Écrit en Bépo selon l’orthographe de 1990
[^] # Re: Et bha ...
Posté par LupusMic (site web personnel, Mastodon) . Évalué à 1.
Ah ben j'avais zappé ta réponse, désolé.
Je ne trouve pas
Vec<Vec<Vec<int>>>
plus clair quevector<vector<vector<int>>>>
, si au moins tu avais donné la version canoniquestd::vector<std::vector<std::vector<int>>>>
;) De toute façon, on ne déclare pas ça, c'est à encapsuler.Je ne vois pas trop l'intérêt d'un mot clé pour déclarer une fonction. Pour une classe/structure non plus d'ailleurs, mais bon.
Le plus gros problème que ça me pose, c'est que ça donne un mauvais exemple à suivre.
[^] # Re: Et bha ...
Posté par ariasuni . Évalué à 3.
C’est quand même plus sympa de pas avoir une ligne qui fait trois kilomètres. Les tableaux étant une fonctionnalité tout de même assez basique, il est logique d’avoir une syntaxe qui va avec.
En plus ton code il est faux, t’as mis un chevron en trop à la fin sur tes deux exemples. :P
Plus facile de rechercher avec grep, analyse syntaxique plus simple, plus logique.
On cherche une fonction? cherchons un
fn
. On cherche une variable? cherchons unlet
. On cherche une structure? cherchons unstruct
.Les trucs courts pour le langage (quelques mots-clés/nom de fonctions couramment utilisés qui existent dans tous les langages et que tout le monde comprend), les trucs longs et explicites pour le développement ensuite (ce qui va nécessiter plus de détails, plus d’informations pour bien comprendre ce que le développeur fait).
Après si le développeur fait n’importe quoi, on peut difficilement accuser la langage, qui essaie de mettre le moins d’entraves possibles entre le programmeur entre le programme. De plus, le tutoriel Rust — et n’importe quel bon tutoriel ou bouquin — n’encourage absolument pas à ce genre de pratique, au contraire.
Écrit en Bépo selon l’orthographe de 1990
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.