5 ms·
Would a novice to the language implement a highly concurrent HTTP service as their first ever task? I don't think so, most people start with "Hello world" progr
by tiniuclx 7y ago
Would a novice to the language implement a highly concurrent HTTP service as their first ever task? I don't think so, most people start with "Hello world" programs.
To understand the entirety of that first signature you need to grasp is:
1. The Result type, which returns the result of a successful computation or an error.
2. The Box container, which is basically just a safe pointer to some memory
3. Rust's way of doing polymorphism.
These are indeed some complex topics but I doubt most people start at that level. Sure, an absolute beginner would be dumbfounded by this, but working through even the first few chapters of the Rust book gives you enough knowledge of Result and Box to let you figure out what is going on.
- ngrilly 7y agoThanks!
- jedisct1 7y ago> Would a novice to the language implement a highly concurrent HTTP service as their first ever task? Why not? With Node or Go, this is trivial.
- empath75 7y agoNothing is trivial with rust.
- Dowwie 7y agoMany things aren't trivial, but some things are! For instance, the following is a program that uses a well-defined, user-friendly api for regex pattern matching. extern crate regex; // 1.1.8 fn main() { let pattern = regex::Regex::new("(?i)resource not found").unwrap(); let msg = "resource not found".to_string(); // didn't have to convert to String as &str suffices if pattern.is_match(&msg) { println!("found pattern in msg"); } else { println!("did not find pattern in msg"); } } Clearly, this is an easy example and when used in the wild, you'll have to account for error handling. However, whatever isn't trivial exists for a good reason. Trivial comes at a cost. One thing I like about Rust is that it lets a programmer decide what costs to assume.
- hu3 7y agoPerhaps we have different definitions of trivial but I don't find it trivial to cast a string to a string in variable declarations: let msg = "resource not found".to_string(); Is it necessary?
- steveklabnik 7y agoYou're not casting a string to a string, you're casting a &str to a String. > Is it necessary? In this code, it's not actually necessary, your parent converts it back to a &str later, when passing it to is_match. In other cases, it's very necessary; they're two different types, with different properties.
- hu3 7y agoThanks for explaining steve. I guess these things become second nature with practice.
- steveklabnik 7y agoYep! Rust has a few "rules of three" that appear again and again. This is an instance of there being three kinds of types: T, &T, and &mut T. That is, owned, borrowed, and mutably borrowed. In most examples of this, "T" is the same thing in all places, that is, i32, &i32, &mut i32, but in this case, "str" is built into the language. So you have String, &str, and &mut str. The naming is slightly off, because you're coming into the conflict of String being a standard library type, and str being a language type. We almost unified them before 1.0, but there wasn't a ton of benefit. The point is, yes, it is a bit confusing at first, you're totally right. I actually re-did the entire table of contents of The Rust Programming Language to re-focus them on strings due to this. But you're also right that after some practice, it's a non-issue that you never really spend mental effort on. The trick is, how many people will be willing to spend that time? Can we reduce that time? Time will tell :)
- Dowwie 7y agonope.
- tiniuclx 7y agoActix-web actually makes things a little bit easier. Here is their "Hello World" example https://github.com/actix/examples/blob/master/hello-world/src/main.rs https://github.com/actix/examples/blob/master/hello-world/sr... The HTTP Handler (the index function) returns some plaintext and prints to the server's console. Removing the print makes the function simpler than the one in the main article. Actix Web was designed from the get-go to be a highly concurrent HTTP framework, and I think it is the most mature Rust web framework. Of course, the boilerplate main still needs to be written, and the way it does things is a bit more profound. But at a high level, I believe it is quite clear that it is handling logging, URL routing and connecting to a port.
- enlyth 7y agoI don't see why not, making a simple HTTP server is fun and interactive, doesn't take much time and you can learn a lot if you don't know much about the language yet. Seeing that function signature, I can imagine why a lot of people avoid Rust just based on first impressions.
- steveklabnik 7y agoNot to mention, you wouldn't even have to see a signature like that in the first place. Many of Rust's frameworks can accept a variety of signatures for handlers, so for example, with actix-web: use actix_web::{web, App, HttpRequest, HttpServer}; async fn index(req: HttpRequest) -> &'static str { println!("REQ: {:?}", req); "Hello world!" } fn main() -> std::io::Result<()> { HttpServer::new(|| { App::new() .service(web::resource("/").to_async(index)) }) .bind("127.0.0.1:7879")? .run() } Five small notes: Actix runs on stable Rust, and so does not support async/await directly yet; this is what it will look like when it does. You need to write a bit more code to map between the 0.1 futures and stdlib futures to use it today. This will go away once async/await is stable. The async/await is not needed for something that simply returns a string, of course, but to keep it as close to the original example as possible... The `'static` is a bit unfortunate, but if you just write &str, the compiler will tell you to insert it. A small speedbump but shouldn't stop a newbie in their tracks entirely. This is an infallible handler, since we're just returning a string. You can use Results and such as well, when your handlers need it, but it doesn't have to come into play for the simplest of things, which reduces the overall burden. A lot of web frameworks in Rust let you return non-Strings too, which is actually a hard requirement or else you can't serve things like images. It's just that "hello world" is a string... It didn't make it on HN, but the latest Techempower benchmarks show Actix starting to run away with the competition: https://news.ycombinator.com/item?id=20399773 https://news.ycombinator.com/item?id=20399773
- tiniuclx 7y agoThank you for your reply, that was exactly what I was trying to show when I linked the Actix Web example in one of the child comments below!
- 0815test 7y ago> To understand the entirety of that first signature you need to grasp is: ... ...4. The unit type (), which is basically a 0-tuple, i.e. a type that carries no information, and generally replaces the use of `void` in C-like languages. (Rust also has a proper void type, i.e. a type for something that cannot occur, but that's denoted by ! and is quite different from the unit type.) It's not a hard concept, but it may be a bit unfamiliar if you havent worked with functionalish languages before.