Skip to content

Instantly share code, notes, and snippets.

@pickfire
Last active September 18, 2020 04:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pickfire/3bcceeacf0bae22dd9f03c5053a976e3 to your computer and use it in GitHub Desktop.
Save pickfire/3bcceeacf0bae22dd9f03c5053a976e3 to your computer and use it in GitHub Desktop.
Rust 2021 Post

Rust 2021

When I first got into Rust, I didn't know what "safety" means at all. But when I try it out, I am surprised by one thing, when it compiles, it mostly works which I kinda knows what "safety" means after that. At that time, it was also interecting to see the word "zero-cost abstraction" which sounds cool.

Sometime later, when I got back into Rust, there is one project that I started working on and found interesting, which is one of those oxiding projects. https://github.com/rust-dc/fish-manpage-completions Python to Rust, I am familier with Python but Rust seemed to similar while porting it.

Lately, not sure why but I spend more time in Rust projects. I found https://github.com/maciejhirsz/beef (compact Cow) interesting so I try making my own https://github.com/pickfire/ve (compact Vec) but it wasn't exactly faster, I did it by hand-porting bit-by-bit from alloc vec library but it was not exactly faster, then I somehow found parts to improve.

What have I been doing in Rust?

  • Reviewing random (easy) pull requests coming in (not sure why but I nitpick documentation quite often)
  • Fixing docs and cleanup for alloc vec, I have some ideas when hand-porting it to ve
  • Looking into an eager join for Iterator like collect but not there yet
  • Doing some fix for rust suggestions, now async pub, next probably mut deref suggestion

Orthogonality and Discoverability

Let us start discussing the things for Call for Posts. This post mainly talks about orthogonality and discoverability.

Language features

Orthogonality

While using Rust for some time, I noticed that there quite some difference between str and slice, for example str can take in impl Pattern for some functions (E.g. contains) but the same counterparts available in slice cannot do the same, but instead takes in &T.

I get this issue while trying to change str to slice in https://github.com/pickfire/fs-ledger but I figured out it does not work and in the end I just stick with str since it already work given that I need to put in more effort for less effect.

Tooling improvements

Discoverability

Right now as I use fish shell, I mostly use alt-h to view manpages but as rustup comes with its custom man page selection based on different toolings, one needs to do rustup man just specifically for rust man pages which in turns made me more reluctant to view rust man pages.

Without viewing rust man pages (since I thought they are the same as -h), I missed how to do filtering for tests since I just quickly skimmed through the test section, at the end I figured out that all these were in the man pages, if I read man pages at first, I would have already learned --lib, --test <test> easily.


The next thing I would say is Rust have the same issues as other languages in terms of documentation and searching for the correct types, having composition probably make the issue worse since there are too many information. Say I have a type but I want to get another type, if it requires multiple steps then it may not be straightforward to know.

Of course right now one can do * -> String in Rust documentation, but what if there are multiple layers? Say you want to know slice -> * -> String for as many steps as it takes. Graph database looks like a good way to discover these types but I never seen anything for these even for other languages.

Usability

I like a lot about https://lib.rs, fast, dark-mode, feature discovery and stuff except the naming since I like the word crates more. I wonder why https://crates.io still stays the same in terms of performance (most likely because it have higher load) and features?

Organizational changes

Discoverability

I am not sure much about this since I am not in any team. Most of the time I just don't know who to ask since I cannot see who is in which team as only team members can see which team others are in. Even if someone reviewed my PR, I don't know if they are from that team, even my CC @rust-lang/doc or @rust-lang/rustdoc or @rust-lang/docs would not be bold and have a link, people outside the team probably cannot ping the team, or even if we did, we may not know if someone responded is from the team.

Ecosystem

Orthogonality

Serde is impressive, instead of defining serialization M * N times, one could just do M + N times. Still, as a serde user, switching between one crate and a different one with a different maintainer may not be as easy. Say, some serde crates expose Serializer and Deserializer types, some does not, some provides to_writer but some does not.

In my case, I was writing a converter between serialization types https://github.com/pickfire/babelfish, I noticed that different serde libraries for different formats does things differently (especially when it was by a different author). On the other hand, I really like how rust crypto ecosystem solves this, they are able to get a lot of crates https://github.com/RustCrypto/hashes standardized to have the same functions and style but feel sad to see that some crates name was already taken and they have no choice but to use another name.


I did mentioned that I like when it compiles, it mostly works? Sadly that does seemed to be less true in the ecosystem most likely after the ability to do reflection or Any type. Of course, the tradeoff was better ergonomics (extractors pattern) and slower speed and lesser safety (likely HashMap<Any, ??>) which I think is fair.

Most of the web frameworks and game frameworks (this case is a bit better) I saw nowdays do panic in runtime even though it have that information at compile time but if it was done probably the ergonomics may not be as good as now. Examples,

If route data is not set for a handler, using Data extractor would cause Internal Server Error response. actix-web

If you request a State for a T that is not managed, Rocket won't call the offending route. Instead, Rocket will log an error message and return a 500 error to the client. rocket

Surprisingly, tide seemed to be safe right now but not sure if the same will happen once AppState in https://rustasync.github.io/team/2018/10/16/tide-routing.html is implemented.

Same for game frameworks which have similar query system, like using a wrong type for Read<T>, or Write<T> in amethyst results a panic during runtime when the game starts, better unlike web frameworks which returns 500 only when the endpoints are called.

Code sample:

// cargo add actix-web actix-rt
use actix_web::{web, App, HttpServer, Responder};

async fn greet(_data: web::Data<String>) -> impl Responder {
    "Hello world"
}

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| App::new().route("/", web::get().to(greet)))
        .bind("127.0.0.1:8000")?
        .run()
        .await
}

Closing Notes

So far so good, a lot of interesting stuff have been coming up recently as discussed in https://blog.rust-lang.org/2020/09/03/Planning-2021-Roadmap.html, except it was missing cranelift which I am looking forward to. :D

@shanesveller
Copy link

Regarding documentation searching by function signature, the most unique and compelling example I know is Haskell's Hoogle .

@pickfire
Copy link
Author

I have heard of that, that sounds interesting but rust search already have that like I mentioned, but only for concrete type. The issue wasn't with finding the one single function if you know both the types (or even ctrl-f), sometimes the developer may need to run multiple functions in order to get the type, and the path / graph to get the types is something that I have never seen.

For example, how does one convert &[u8] to Path? Sometimes these requires 2 functions, especially those dealing with Path and it may not be as straightforward as running one single function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment