8 ms·
Rust for C++ programmers – part 3: primitive types and operators
- camus2 13y agowhat about rust for webapps? are there any frameworks out there?
- mercurial 13y agoNot really. A lot of the infrastructure has kept changing for a while (eg, the IO facilities were recently rewritten), so code for older versions of Rust (like [1]) fall behind and do not get updated anymore. With Chris Morgan's rust-http library (which I think is also used by Servo), you should have the base on which to build a web framework. Somebody apparently wrote (and still maintains) a pure Rust Postgresql driver ([2]), so you could in theory write a simple CRUD webapp, if you're willing to write the routing yourself. 1: https://github.com/erickt/mre https://github.com/erickt/mre 2: https://github.com/sfackler/rust-postgres https://github.com/sfackler/rust-postgres
- b0b_d0e 13y agoKinda, yes, but not really. Currently, the best http framework in Rust is rust-http (https://github.com/chris-morgan/rust-http https://github.com/chris-morgan/rust-http) and it has the things needed for handling requests and sending responses. But as far as actual full featured web frameworks, there is only one that I know of (discounting mre since it hasn't been updated in a long time) and that's because I am the creator of it. oxidize (https://github.com/jroweboy/oxidize https://github.com/jroweboy/oxidize) aims to be an inherently safe and fast web framework inspired by several other frameworks, but I don't consider oxidize to be even in a pre alpha state right now (pre alpha to me means, don't try to write code with it cause it will change drastically in the near future). I've rewritten the code for it twice already and a third time is sitting in a branch that doesn't compile right now. Progress has been a little slow lately since it became a group project for a class of mine, and that meant that I needed to manage several people working on it rather than actually contributing code. Over the summer I hope to get it in a good state and then make a post about it and fill out documentation, make tests, submit it to techempower benchmarks, and other necessities. Having said that, I'm not confident yet that you want to be coding a web site in rust. In the name of safety, rust's compiler can be very difficult to please and in the name of speed it doesn't compile blazingly fast as well. Some people may have a different opinion from me, but besides writing a web app to learn the rust language, what advantages for the web does rust give you that go or haskell doesn't? When you are writing a web app, developer productivity is priority number one (in my opinion), and having to fight the borrow/lifetime checker and trying to find out why your struct doesn't fulfil `Send` are not things I would like to have to do when I'm making a web site. The tradeoff will be that hopefully a web site written in rust will be both fast and concurrently safe, but you will be sacrificing developer productivity for the reasons mentioned above. Irregardless of those issues, I'm still very determined to make a rust web framework that is both fast and easy to develop for (probably by providing examples of common web idioms in oxidize so people can see how to do it), just, I want people that use my framework to be aware of the tradeoffs that they will make. In short, I consider oxidize an experiment in trying to make a powerful, expressive, and extensible web framework in rust, and along the way I've started to question whether this will have any practical applications, but in spite of that, I still am trying to achieve the previous listed goals.
- mercurial 13y agoWhat I like about it is that it's pretty devoid of macros. I'm curious as to how you are planning to handle the environment of the webapp (configuration, connection pool, business objects...), given that you settled for plain functions with a given signature.
- b0b_d0e 13y agoThats the rework that I'm working on! I'm debating between making a context trait and having the static function signature include a context instead of a request and the everything request related would be included/appended in the context, or having the user implement "controller" trait on their struct that has a method I will call after settling the routes (something like https://github.com/jroweboy/oxidize/blob/incoming/tmp/matchblockheroes.rs#L37 https://github.com/jroweboy/oxidize/blob/incoming/tmp/matchb... where maybe a macro can generate this method from the urls. Note that this code doesn't compile though :) While I was initially fond of the latter, it's been very painful to work with in practice and I don't see it actually working, so I think that I'll be testing out to see if I can rework the static functions to have a context. I think the hardest part is that I want to eliminate any need to have any static variables, but that means I have to store them all in a struct that requires Send to be fulfilled and thats more over head for programmers. In the near future, I will be looking into using the different parts of rust-http directly rather than implementing the server trait to see if I can gain any benefits from that :)
- mercurial 13y agoPersonally, I'd be inclined to have the context separate from the request, since they're really two different things. Also, you could introduce a FromRequest trait (trivially implemented by Request, returning self) to allow the user to build structures directly from a request (and its converse ToResponse), giving your function a signature of: fn (context: Context, req: FromRequest) -> ToResponse trait FromRequest { fn from_request<'a>(req: &'a Request) -> &'a Self; } impl FromRequest for Request { fn from_request<'a>(req: &'a Request) -> &'a Request { req } } This would remove a lot of boilerplate for well-behaved applications. You'll also need a notion of middleware, which I guess would take a Request and return either a ToResponse or a request (eg, an authentication handler ought to return the response immediately in case of authentication failure), and similarly on the way out, something taking a Response and returning a Response.
- deleted 13y ago[deleted]
- chrismorgan 13y agoAt present it's largely Watch This Space. The language isn't stable enough yet and there are still a few pieces that need writing, anyway.
- mercurial 13y agoHaving been the victim of a fun Javascript bug recently (something like ("1" + 10)*2), I must say that I agree that type coercion is the wrong thing to do 99% of the time (probably with the exception of attempting to divide integers).
- saurik 13y agoIt isn't as much about the coercion as the consistency: the division case returning a float when given integers is fine if the division operator always does that. Some languages (VB being an example; I wish more were) have a "string concatenation" operator that is separate from numeric addition; 1 & 2 is always going to be "12".
- masklinn 13y agoA colleague recently went through that as well, a (JS) graphing package would sometimes display bar charts with an incorrect scale (it would pick the wrong maximum value, so part of the bars would be cut off). Turns out the package expected numbers, but sometimes a bug meant the data source would give arrays (of a single number each), the package's own max (using <) would perform a lexical comparison (comparison would coerce to string and a graph with a value at 800 and one at 1800 would pick a y-scale for 800 and cut off 1800) but further operations would coerce to number, so there was no error anywhere and most graphs looked correct.
- repsilat 13y agoAdd me to the list. The other day I was debugging some simple Python code that worked something like return 10000 if x > 10000 else x and it wasn't working because x was a string. Instead of raising an exception, though, Python decided that all strings are "greater than" all integers, and code was essentially equivalent to return x
- masklinn 13y ago> Instead of raising an exception, though, Python decided that all strings are "greater than" all integers Yep. That's one of the things they changed/fixed in Python 3, comparisons are not defined across and between any and all types: >>> "foo" > 3 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unorderable types: str() > int()
- sisalcat 13y agoFrom the project home page: "prevents almost all crashes (in theory)" How does it prevent index out of bounds errors and division by zero? No, not even in theory. What a ridiculous claim.
- adamnemecek 13y agoI mean you get an error but not a segfault. Rust crashes on division by zero but honestly, how many crashes have you encountered in the real world due to division by zero?
- pbsd 13y agoProbably quite a few. There's also more than just division by 0 to be wary of: http://blog.cmpxchg8b.com/2013/02/the-other-integer-overflow.html http://blog.cmpxchg8b.com/2013/02/the-other-integer-overflow...
- dbaupp 13y agoYou get a task failure (similar to an exception) on division by 0 too.
- berkut 13y agoQuite a few if you include what happens after a division by zero without proper checking / clamping. Had one the other day when renormalising a Cumulative distribution function wasn't taking into account a possible empty set, and the lookup of the index was invalid due to the division by zero.
- nrc 13y agoAll array indexing is bounds checked, so those kind of errors are prevented. We're still working on the story around overflow checking
- sisalcat 13y agoThis prevents buffer overflow errors, but not crashes.
- xioxox 13y agoI understand that there is probably a performance motivation for having int/uint having machine-dependent sizes. However, it seems to me that having different sizes on different platforms is a potential security hazard if the programmer doesn't think of this. It also gives rise to porting bugs. Isn't the idea of rust to make a securer language than C++? I would have thought mandating 32 or 64 bit for int/uint would make more sense, and if the programmer needs more or less they would have to think about that.
- Ygg2 13y agoI do remember a discussion on mailing list that all uint/int would be just fancy typing for u64/i64.
- simias 13y agoWouldn't that mean that the code would have a huge performance penalty when running on 32bit hardware? I think C99's way of handling that is fine, if you want to use whatever native width happens to be on your hardware you just use int/unsigned, otherwise you have stdint.h. Like C, rust could mandate a minimal range for each type in the standard, but setting the type width in stone seems dangerous to me, both for backwards and forwards compatibility.
- coldtea 13y ago>Wouldn't that mean that the code would have a huge performance penalty when running on 32bit hardware? Or it could just forget 32bit hardware altogether. Even mobile phones are going 64bit already -- and the language will be ready for production in 1-2 years, where even more platforms will be 64bit. It's not like they have to compromise just to be able to run on some embedded stuff.
- pcwalton 13y agoIt's not out of concern of performance. The idea was in fact to reduce correctness gotchas; ints are often used for indexing into arrays, and you want the size of the integer to reflect the maximum size of an array on your platform. What kind of security issues did you have in mind? Integer overflow can be a problem, but it is usually a memory safety issue, which Rust doesn't have due to bounds checks and iterators.