Today I learned: It only takes about 35µs to spawn a thread in #RustLang (on my machine) 🚀
Might help you to decide whether you should run something in parallel or not ⚙️
Of course, this is not the whole overhead. You might need some kind of synchronization etc.
@b5b38449@8b926eed I think that this is just an internal thinking (that I would probably also suffer from). But at the end, this is not a promise. At least one brought the idea and maybe even initialized it with a draft PR. Someone (including the maintainers) can pick it up if they really like it.
Maybe we should normalize draft PRs then. We shouldn't submit PRs only when they are ready.
@2851d133@e203a2da I get it, but my point is that one should learn to deal with ownership and borrowing first.
But I only did one tiny project in Bevy, so I would recommend listening to you since you have more experience in Bevy :D
@e203a2da To be honest, I am not sure if a #bevy project would be a good first Rust project.
Although Bevy is the leading Rust game engine that I would recommend, I found it not well documented YET. It is not the fault of the project since it is in a rather early stage.
Therefore, I would rather recommend starting with something other than game development for better documentation and more tutorials.
@e203a2da There is no logical reason for not using them. I created a PR once that used a multiline comment and had to change it to one line comments because of "convention". This is also the style in the standard library. I am fine with it. I think of it as something that could be used but is not a convention.
@8b926eed I will definitely respect that and try to remember it.
Excuse me if I lack background knowledge, but could you maybe explain why? You don't have to though ❤️ I just want to be educated on this subject.
Is there a prober ping library fully written in #Rust?
I wonder why we already have very good HTTP clients (like reqwest) but binaries like #gping still run the ping command:
https://github.com/orf/gping
I ended up calling the ping command too, but a well maintained library would be nice :D
#RustLang
@703c815a I use #GitUI for about 95% of Git usage. The rest is done with simple Git commands.
Check it out:
https://github.com/extrawurst/gitui
Inside #Zellij, I always have GitUI as a second tab.
I even have Zellij layouts to automate opening such tabs and panes for each project :D
With Zellij, there is no need to reinvent the wheel as "integrations". Just use other CLIs or TUIs in your terminal workspace :D
@d05bf930 Check out this awesome video which talks about transformations between Result and Option:
https://www.youtube.com/watch?v=s5S2Ed5T-dc
`ok()` gives you the Ok variant as an Option. You loose information about the error.
You can't use `ok()` on an Option because you need to specify an error. You need to give it information. Therefore, you can use `ok_or`.
But if your error has to be computed (like a String which allocates), then you want that computation to be lazy with `ok_or_else` and only run on None.
https://cdn.fosstodon.org/media_attachments/files/111/130/690/663/922/659/original/7596e529390f2955.png
@d05bf930 I have to agree that async closures are a pain. And their error messages are misleading. Maybe @536e35c5 could vibe in 🤍
Async Rust is not complete. This is a fact. You might find workarounds for missing features (like the async_trait crate) though.
Unrelated to your post, but although async Rust is not complete, I think that the implemented part of async in stable Rust gets unfair criticism. And Rust teams are working on filling the gaps ❤️
@d05bf930 Sorry for my spam. I really enjoyed your post. Some things are presented unfairly, but you are telling your subjective experience. We need more people talking about their experience with Rust to improve this experience for future fellows ❤️ :ferris:
@d05bf930 To be honest, I am confused. You say that you like the "batteries included" approach and yet you complain about having too many functions/methods.
Yes, the standard library is extensive and I still learn about new functions. But honestly, rustdoc is the best docs tool I have ever seen compared to other languages, especially for navigation. It is a matter of entering "docs.rs/std" in the browser, pressing Shift+s for search and then using the side bar of the picked search result.
@d05bf930 I have to agree that async closures are a pain. And their error messages are misleading. Maybe @536e35c5 could vibe in 🤍
Async Rust is not complete. This is a fact. You might find workarounds for missing features (like the async_trait crate) though.
Unrelated to your post, but although async Rust is not complete, I think that the implemented part of async in stable Rust gets unfair criticism. And Rust teams are working on filling the gaps ❤️
@d05bf930 I get the confusion with needing pub(super) for testing private functions. But this is why your structuring of tests is not the "idiomatic"/common one.
@d05bf930 To be honest, I am confused. You say that you like the "batteries included" approach and yet you complain about having too many functions/methods.
Yes, the standard library is extensive and I still learn about new functions. But honestly, rustdoc is the best docs tool I have ever seen compared to other languages, especially for navigation. It is a matter of entering "docs.rs/std" in the browser, pressing Shift+s for search and then using the side bar of the picked search result.
@d05bf930 So you normally only consider variant 2 for a module. Later on, if you want submodules in that module, you just create a directory next to it with the same name. That's it.
mod.rs is legacy for backwards compatibility and inline modules are almost only for tests in the same file. Now that I thought about it, I find it brilliant :P
@d05bf930 I get the confusion with needing pub(super) for testing private functions. But this is why your structuring of tests is not the "idiomatic"/common one.
@d05bf930 One might ask, why not just put the file `submod.rs` inside the `submod` directory (instead of next to it or `mod.rs` inside it)?
Well, that would make having a submodule with the same name (submod::submod) impossible with variant 2! (Not that I would recommend that design)
More importantly, it makes expanding from variant 2 to variant 3 very easy! Or actually, it makes variant 3 only an extension of 2.
@d05bf930 So you normally only consider variant 2 for a module. Later on, if you want submodules in that module, you just create a directory next to it with the same name. That's it.
mod.rs is legacy for backwards compatibility and inline modules are almost only for tests in the same file. Now that I thought about it, I find it brilliant :P
@d05bf930 The first variant with a an inline module is almost only used for tests that you want have in the same file but with namespacing.
The second variant is obviously useful to have a file as a module without needing to create a directory if it doesn't have submodules.
I explained variant 3 and 4.
@d05bf930 One might ask, why not just put the file `submod.rs` inside the `submod` directory (instead of next to it or `mod.rs` inside it)?
Well, that would make having a submodule with the same name (submod::submod) impossible with variant 2! (Not that I would recommend that design)
More importantly, it makes expanding from variant 2 to variant 3 very easy! Or actually, it makes variant 3 only an extension of 2.
@d05bf930 About modules:
I used mod.rs too until I had more than two mod.rs files open in my editor and I lost it. You don't even have to open multiple mod.rs files to be confused. If you have one open in a hidden tab, do you know which mod.rs file this is? I ended up closing mod.rs files quickly after editing them. Then I found about the solution with the file `submod.rs` next to the directory `submod`.
@d05bf930 The first variant with a an inline module is almost only used for tests that you want have in the same file but with namespacing.
The second variant is obviously useful to have a file as a module without needing to create a directory if it doesn't have submodules.
I explained variant 3 and 4.
@d05bf930 " I really wish that Rust would just auto-discover tests wherever you happen to put them"
You can annotate any function with #[test] and Rust will run it as a test. It doesn't have to be in a test module.
@d05bf930 About modules:
I used mod.rs too until I had more than two mod.rs files open in my editor and I lost it. You don't even have to open multiple mod.rs files to be confused. If you have one open in a hidden tab, do you know which mod.rs file this is? I ended up closing mod.rs files quickly after editing them. Then I found about the solution with the file `submod.rs` next to the directory `submod`.
@d05bf930 " I really wish that Rust would just auto-discover tests wherever you happen to put them"
You can annotate any function with #[test] and Rust will run it as a test. It doesn't have to be in a test module.
@61f067c1 I expected you to reply since this is related to Cargo 🤍
Did I get this right that I would run the command in the `publish.rs` file to generate these static files? How would Cargo know that these files are generated by `publish.rs`?
What do you think about including reproducible files that are not tracked by Git in a published crate?
It is about including static files like bundled JS and CSS in the published crate. In my opinion, since these files are auto-generated and reproducible, they shouldn't be on Git.
Here is an example:
https://docs.rs/crate/oxitraffic/0.4.5/source/static/
#RustLang #Rust
@91a2d17f Rust offers both, channels and locking with a Mutex or RwLock. There also more flexible channels in crossbeam:
https://github.com/crossbeam-rs/crossbeam
It doesn't force you to use the easier and less error prone channels, but it also makes sharing memory much easier. It is proven that data races are not possible in Rust. On the other hand, Go knows about the problem and tell you to run a program with an optin tool as long until a data race is detected (if it was reached):
https://go.dev/doc/articles/race_detector
@91a2d17f Go also has a Mutex. Because a Mutex is more low level than a channel. Some things can't be done with channel or require a lot of copying/cloning. Yes, one could say that you should use channels by default, but in Rust, you don't have to use them to be able to right data race free concurrent programs.
@91a2d17f Rust offers both, channels and locking with a Mutex or RwLock. There also more flexible channels in crossbeam:
https://github.com/crossbeam-rs/crossbeam
It doesn't force you to use the easier and less error prone channels, but it also makes sharing memory much easier. It is proven that data races are not possible in Rust. On the other hand, Go knows about the problem and tell you to run a program with an optin tool as long until a data race is detected (if it was reached):
https://go.dev/doc/articles/race_detector
Create a slice from a reference without copying in #Rust
&T -> &[T]
https://www.youtube.com/watch?v=sZnCfIiOXAw
Promising channel! This is his second #RustLang video. Leave a subscribe :ablobcatheart:
@bf55f1f1 The Cargo.toml will not necessarily tell you about that if the feature "full" in Tokio was used. One needs to check where the runtime is spawned (noramally at the main function). The multithreaded version is the default. Otherwise you would see this explicit annotation:
#[tokio::main(flavor = "current_thread")]
I am sorry if I am missing something, but I don't get how the runtime that you normally start yourself (for example in Axum) is hidden.
@bf55f1f1 But starting a runtime involves some overhead. Did I get it right that you would start a runtime for each request?
I am not familiar with iron though and only tried a recent version of Rocket.
About the hidden runtime: Why do you think that it is hidden? For me, it is very implicit since you annotate your main function with a tokio macro. Maybe because of the macro hiding how the runtime is launched? One can see its equivalence here: https://docs.rs/tokio/latest/tokio/attr.main.html#usage
@bf55f1f1 So I guess that only people would use it who are already familiar with Rust and convinced by it and they want to build a backend. But then, if they are already sold on Rust, wouldn't they just learn async?
The route for newcomers before they can work with Axum and SQLx is longer than other routes which don't include async. But for people who are familiar with Rust, it is just one step: Learning async. And I think that we currently have a problem of documentation here as you mentioned.
@bf55f1f1 My conclusion would be:
- Improve the documentation of async
- Make this difficulty levels clear to newcomers to climb up step by step: sync single threaded < sync multithreaded < async single threaded < async multithreaded
- Stabalize missing async features like async traits (work in progress)
- Try to reach having libraries agnostic regarding the async runtime (lowest priority for me personally since we have Tokio)
@bf55f1f1 If such a framework is targeted to newcomers, do you think many newcomers try Rust because of its reliability etc? I don't think so. I think that many of them, especially in the web ecosystem, come for the performance and low resource consumption. I would guess that most of them already have experience in Node, Python and Ruby. They know a slow solution. Why would they use that framework?
@bf55f1f1 So I guess that only people would use it who are already familiar with Rust and convinced by it and they want to build a backend. But then, if they are already sold on Rust, wouldn't they just learn async?
The route for newcomers before they can work with Axum and SQLx is longer than other routes which don't include async. But for people who are familiar with Rust, it is just one step: Learning async. And I think that we currently have a problem of documentation here as you mentioned.
@bf55f1f1 One could create a new web framework that is synchronous which offers trivial parallelization (launch multiple instances). But how do you share state then without a database? A required database increases the complexity.
And what about performance? Such a framework would not have the same performance like Axum. Who would use it then?
@bf55f1f1 If such a framework is targeted to newcomers, do you think many newcomers try Rust because of its reliability etc? I don't think so. I think that many of them, especially in the web ecosystem, come for the performance and low resource consumption. I would guess that most of them already have experience in Node, Python and Ruby. They know a slow solution. Why would they use that framework?
@bf55f1f1 "I would like to see more web frameworks that are synchronous by default and allow you to opt into async as needed."
I don't think that this is possible without maintaining two separate codebases/APIs like reqwest does. reqwest is just a client. But maintaining two APIs in parallel for a whole framework?
@bf55f1f1 One could create a new web framework that is synchronous which offers trivial parallelization (launch multiple instances). But how do you share state then without a database? A required database increases the complexity.
And what about performance? Such a framework would not have the same performance like Axum. Who would use it then?
@ba157608 I like plain text as a default, but when sending a long email especially to a group as an announcement, I want to highlight specific points. Markdown would be awesome, but instead we have HTML. Very good idea to have a whole webpage as an email…
@6e0bd04c Oh, man, sorry for not replying. Things got complicated on my side. I had an exam. Now, I am on a trip in China.
I want to start it one day. I will ping you then and see if you also have time :D
@80f08b97 I wasn't able to understand Rust code before reading the book and learning the theory behind the language. It is not a language that one can just dive into and directly start hacking.
Knowledge in other languages helps while learning, but it is not enough on its own.
Plus, as someone said, LSP is often necessary for browsing code, not only for Rust though.
I would also love to help if there are concrete questions 🤍
Notes by Mo :ferris: :tux: | export