18 ms·
Rust 1.45
- trait 6y agohttps://github.com/SergioBenitez/Rocket https://github.com/SergioBenitez/Rocket on stable rust finally!
- mrmonkeyman 6y agoHigh speed to the first red light.. the database, IO, network.. I don't see the point of Rust here but whatever floats your boat.
- hellofunk 6y agoInteresting. Haven’t used rocket, but I am intrigued by warp since it has a websocket server as well.
- jjice 6y agoWhen I started learning Rust over a year ago now, Rocket was extremely appealing to me. I never subscribe to any GitHub threads that I'm not involved in, except for Rocket on stable. In general, stable proc macros is an awesome step for Rust.
- steveklabnik 6y agohttps://github.com/SergioBenitez/Rocket/milestone/8 https://github.com/SergioBenitez/Rocket/milestone/8 is what's on the milestone for the next release, I don't know how closely that actually tracks. I'm super excited though!
- rvz 6y agoGreat news, but it's not even 1.0 yet. Thus, it isn't stable enough for production use. At the moment, I'd rather use something like actix-web instead.
- neilsense 6y agoThat's not how versions work
- The_rationalist 6y ago>= 1.0 in semantic versioning universally means that it should be "stable enough"
- nicoburns 6y agoThe Rust ecosystem typically has much more conservative version numbers than other ecosystems though, and higher quality standards. There are several very high quality crates with 0.x version numbers.
- jhasse 6y agoThey are doing it wrong then.
- darksaints 6y agoOne could argue that if you are relying on magic number schemas to decide if a library is stable enough for your usecase, it is you that is doing it wrong.
- The_rationalist 6y agoIt's no longer magic number once you follow semver https://semver.org https://semver.org Of course it only offer limited information but this information can tell you whether you should be not confident in it. Pre 1.0 is such a signal.
- lumost 6y agoA fairer statement might be that the rust ecosystem has inconsistent version numbers. I've seen both flawless v.14s and awful v.7s. There are a few ways to figure out the difference like sorting by downloads on crates.io to find packages that are commonly used. There is a curious parallel to the rise of Go which had no versions in their ecosystem as the language was adopted.
- ldng 6y agoIMHO, it's a shame So Much time has been spent (~3 years ?) on async at the cost of basic features like multipart and CORS. But I understand it could be more fun for the devs :-)
- wtetzner 6y agoI think it makes sense to get your foundation and ergonomics correct before piling on features. Otherwise you end up building features that may need to be completely restructured/redone later.
- deleted 6y ago[deleted]
- ReactiveJelly 6y agoI recently switched from old sync versions of hyper and postgres to the new async versions. [1] It wasn't hard, but yeah it was not fun either. I can only imagine it's worse if you're actually writing the libraries and not just a CRUD app like I am [1] Apparently the postgres crate was a wrapper around tokio_postgres all along and I didn't notice. So to remove a dependency I switched to using tokio_postgres directly
- Spartan-S63 6y agoThey've really only spent about a year or so on async support in Rocket. They were waiting for async/await to stabilize and the async runtime story to centralize a bit (though they picked Tokio as the default). Features like CORS are available via third party fairings, but I could see them being incorporated in the future in the `rocket_contrib` portion. I think the goal is to keep the overall framework pretty light and put more things into the `rocket_contrib` portion.
- deleted 6y ago[deleted]
- angrygoat 6y agoThis rather niche fixing of unsafe behaviour is excellent: https://blog.rust-lang.org/2020/07/16/Rust-1.45.0.html#fixing-unsoundness-in-casts https://blog.rust-lang.org/2020/07/16/Rust-1.45.0.html#fixin... I spent a few years as a scientific programmer and this is exactly the sort of thing that just bites you on the behind in C/C++/Fortran: the undefined behaviour can actually manifest as noise in your output, or just really hard to track down, intermittent problems. A big win to get rid of it.
- ansible 6y agoIt is nice that they have defined behavior for that now. Though I try to always scrutinize any floating-point / integer conversions during code reviews. The default casting of a floating point value to integer is frequently not what you want, however. In the code we do, for example, you will usually round to the nearest integer instead, we don't normally need the more fancy rounding schemes.
- davrosthedalek 6y agoI'm not sure I understand this. Does it not produce a run time error? Why not? This looks very dangerous, because it essentially does the "nearest to right" thing. Say, you cast 256 to a u8, it's then saturated to 255. That's almost right, and a result might be wrong only by 0.5%. Much harder to detect than if it is set to 0.
- deleted 6y ago[deleted]
- deleted 6y ago[deleted]
- tinalumfoil 6y agoMost floating points aren't integers anyway, so if you think of it as casting 256 to the nearest u8 it's correct, same as rounding 0.25 to 0. NaN to 0 is a bit more concerning, but inconvienence and compatibility need to be weighed against catching every error (no type system will catch every bug).
- baseballdork 6y ago> array[i] will check to make sure that array has at least i elements. At least i+1 elements, right? Or am I getting caught up by one of the three hardest problems again?
- steveklabnik 6y agoNope, you're right, it was me that got caught up by it. :) Thanks, I'll fix that now. https://github.com/rust-lang/blog.rust-lang.org/commit/fe2414d86d55e0f6d259a7eb97bb1b4d6026ce5f https://github.com/rust-lang/blog.rust-lang.org/commit/fe241... (should roll out in a few minutes)
- staticassertion 6y agoAnd this is why we need bounds checking.
- kbenson 6y agoThe thing that keeps the "two hardest things in CS" joke alive and still funny is that it's so, so true.
- dagmx 6y agoEdit: brain not woken up yet. It’s because of zero indexing. ———- Original question: Out of curiosity, why the +1?
- person_of_color 6y agoAny algo-trading backtest frameworks in Rust?
- mas3god 6y agoAll you need for algotrading is to query an api. Rust would be a poor choice for that anyways, like using a semi truck to carry your bike around.
- lucasmullens 6y agoPerformance is super critical in high frequency trading, so Rust sounds like reasonable choice. Having your code run a millisecond faster means beating out a competitor with the same algorithm as you, getting you a better price.
- estebank 6y agoBe aware that Rust gives you the tools to be fast, it is not necessarily fast by default, although a lot of constructs it guides you towards usually help with that. You still need to profile your code to see what you need to optimize, whereas other languages with fewer knobs will perform optimizations that you otherwise need to manually annotate in your code in Rust. I prefer this approach, but it can be surprising to people used to the alternative.
- dilap 6y agoDo you have examples of this? I'd be curious to know if so. (I've played w/ Rust a little bit -- I implemented a Boggle board scorer + high-scoring board generator; Rust outperformed my C++ code! I was impressed.)
- estebank 6y agoOne example of the choice you have is how you can deal with generic data types: fn foo<T: Trait>(_: T){} fn foo(_: impl Trait) {} fn foo(_: &Trait) {} These three different fn definitions have two different behaviors and affect both the speed of the code and the speed of compilation and it depends entirely on how they are called. The first one is what the language calls generics: they are always monomorphized, which means that if you have three calls to `foo` with different types (that implement Trait) the compiler will expand three different functions with different types (code expansion). The second one is a separate syntax level feature (impl Trait) which was mainly added to introduce a new feature which is static opaque types, where the function determines what the underlying the return type will be, but the caller can only interact with it using the trait's API. [Aside] This is useful for cases like the following: fn it() -> impl Iterator<Item = i32> { vec![1, 2, 3].into_iter() } where you would otherwise have to specify the specific type: fn it() -> std::vec::IntoIter<i32> { vec![1, 2, 3].into_iter() } This example doesn't seem like much, but if you want to add a `map()` call to this you start to see the benefit: fn it() -> impl Iterator<Item = i32> { vec![1, 2, 3].into_iter().map(|x| x * x) } fn it() -> std::iter::Map<std::vec::IntoIter<i32>, fn(i32) -> i32> { vec![1, 2, 3].into_iter().map(|x| x * x) } The more types you nest the more the benefits come into play. [end of aside] Now, with that out of the way, the type of an impl Trait in argument is decided by the caller (not the function), so they are implemented internally exactly the same as type generics. The only difference is arguable nicer syntax in the definition and not being able to specify a type using the turbofish. For all intents and purposes, those two are the same feature. The third function is different, it uses a virtual table, with everything that implies: there's type erasure, there's only a single function in the expanded code (which makes compilation faster because the compiler doesn't need to do work), calling this function can be slower because the final executable has to perform some pointer chasing to call methods, instead of directly knowing where to call them. All of this to say: if you use `fn foo<T: Trait>(_: T)` or `fn foo(_: &Trait)` affects compilation and execute time, so you have to be aware of their distinction. This means that if you're not aware you might have slower code than you would with a compiler (like Swift, for example) which relies on heuristics to decide to do static or dynamic dispatch, but it also means that your code's performance characteristics won't change all of a sudden because you modified a tangentially related part of the code and suddenly crossed some threshold. Another example can be `.clone()`: is it slow? The answer is always "it depends". You might be cloning an `Arc`, which is cheap, you could be cloning a 10MB string, which is slow. But because we train ourselves to see clone as slow we might be worried or annoyed by `Arc`. We could make it `Copy`, but if we did that then you have less control over where the `Arc` gets copied which would make it harder to keep track of where the RC gets incremented. The language also doesn't automatically implement `Copy` for small structs, even though it could, which would make it easier to learn that part of the language (you don't learn to add derives early on), at the cost of baffling behavior (you might add a field and suddenly your struct isn't considered "small" anymore). Yet another example, you also have access to `Cow<'_, str>`, which lets you deal with both static and heap allocated strings in the same way in your code, but it pollutes your code, where the naïve thing to do would be to use `String` everywhere. My personal wish is for Rust to remain explicit as much as possible, but use lints to emit suggestions for the cases where a more "magic" language would change the emitted code. That way the code documents its behavior with fewer surprises.
- p4bl0 6y agoBy any chance if anyone is in the Paris area and is interested to teach Rust at university next year during the first semester. Please get in touch :).
- JustFinishedBSG 6y agoWhat university ? Would love to take the resulting course
- harikb 6y agoIs this undergrad? Genuinely curious, how will you get someone to understand what ownership helps avoid without them having experienced the pain on the other side? I guess with younger and younger kids learning programming these, may be there can handle more? I am not sure if my son would understand all of the intricacies in his first semester.
- sankha93 6y agoUniversity of Maryland teaches Rust for a single lecture as a part of their CMSC330 (Organization of Programming Languages) [1] undergraduate class. The lecture slides are available online [2]. [1] https://www.cs.umd.edu/class/spring2020/cmsc330/ https://www.cs.umd.edu/class/spring2020/cmsc330/ [2] https://www.cs.umd.edu/class/spring2020/cmsc330/lectures/25-rust-introduct.pdf https://www.cs.umd.edu/class/spring2020/cmsc330/lectures/25-...
- steveklabnik 6y ago
- deleted 6y ago[deleted]
- kgraves 6y agothis is extremely exciting, a truly wonderful release. well done rust team
- sitkack 6y ago> Rust 1.45.0 adds the ability to invoke procedural macros in three new places! Rust 1.45 will be the Rocket Release. It unblocks Rocket running on stable as tracked here https://github.com/SergioBenitez/Rocket/issues/19 https://github.com/SergioBenitez/Rocket/issues/19 This is so excellent, and I love seeing long term, multiyear goals get completed. It isn't just this release, but all the releases in between. The Rust team and community is amazing.
- hermanradtke 6y agoSadly, not quite there yet: https://github.com/SergioBenitez/Rocket/issues/19#issuecomment-659508247 https://github.com/SergioBenitez/Rocket/issues/19#issuecomme...
- steveklabnik 6y agohttps://github.com/SergioBenitez/Pear/pull/27#issuecomment-658156366 https://github.com/SergioBenitez/Pear/pull/27#issuecomment-6...
- timClicks 6y agoVery exciting.
- luhn 6y agoFor those out of the loop like me, Rocket is a web framework for Rust that apparently was using a lot of experimental features. https://rocket.rs/ https://rocket.rs/ Or maybe it's an explosive weapon crafted with metal pipe and gunpowder. https://rust.fandom.com/wiki/Rocket https://rust.fandom.com/wiki/Rocket
- moksly 6y agoHadn’t heard of it, but it looks a lot like flask. Good stuff, maybe I should consider looking into Rust after all.
- 6y ago
- adamnemecek 6y agoIf you have been on the fence about learning Rust, I encourage you to dive in. It is very productive.
- rgrs 6y agoHow is the build system? Is it stable and easy?
- steveklabnik 6y agoFor 99.9% of projects, a "cargo build" and you're done.
- mqus 6y agostable: depends on what you mean, but afaict, cargo is very stable, in both terms of interface and bugfree-ness. easy: far easier than gradle and maven, imho even easier than go. Definitely easier than cmake.
- computerphage 6y agoIn my experience, Cargo is much easier and more reliable than the systems I've used across Java/C++/Scala/Python/Go/JavaScript. It is such a pleasure to use.
- adamnemecek 6y agoThe build system and the package manager are the best of them all.
- ReactiveJelly 6y agoHere are the problems I've had with other build systems, as a noob, that I have not had with Cargo: - Having to learn weird syntax and constantly look up the reference manual (CMake) - Having to manually add source files (qmake) - Sometimes it just needs a clean and nobody knows why (Visual Studio) - Having to remember to set up debug and release builds and decide your directory layout for everything and figure out what 'a shadow build' is and who gives a crap since it all takes too much HDD space either way (qmake, CMake, make) Also having tests built-in is really nice. Rust is the only language where I bother writing tests. Everything else makes it too hard, as if entry points into your binary are supposed to be rare and expensive.
- fullstop 6y agoI keep seeing more and more news about Rust, and figure that perhaps it is time that I learn something new. 99% of my development work these days is C with the target being Linux/ARM with a small-ish memory model. Think 64 or 128MB of DDR. Does this fit within Rust's world? I've noticed that stripped binary sizes for a simple "Hello, World!" example are significantly larger with Rust. Is this just the way things are and the "cost of protection"? For reference, using rustc version 1.41.0, the stripped binary was 199KiB and the same thing in C (gcc 9.3) was 15KiB.
- pitaj 6y agoA significant portion of the size is formatting and panic unwinding code. Some of this can be reduced by using `panic=abort` but it is a known issue. Worth noting that a lot of the code size is a constant addition that won't really scale with your program code.
- fullstop 6y agoThanks, I'll take a look at this!
- steveklabnik 6y agoThe smallest Rust binary ever produced was 145 bytes. https://github.com/tormol/tiny-rust-executable https://github.com/tormol/tiny-rust-executable That is a bit extreme but it demonstrates the lower bound. There's a lot of things you can do to drop sizes, depending on the specifics of what you're doing and the tradeoffs you want to make. Architecture support is where stuff gets tougher than size, to be honest. ARM stuff is well supported though, and is only going to get better in the future. The sort of default "get started" board is the STM32F4 discovery, which has 1 meg of flash and 192k of RAM. Seems like you're well above that.
- hellofunk 6y ago> ARM stuff is well supported though FYI Rust (and Go) currently don’t work on the new Apple ARM macs. https://news.ycombinator.com/item?id=23856806 https://news.ycombinator.com/item?id=23856806
- snalty 6y agoI'm building an embedded project that currently runs a python script for automatic brightness. It takes a brightness value from a sensor over I2C, applies a function to get an appropriate LCD brightness value and then sends that to the display driver over a serial port. Would this be an appropriate project to write in Rust to learn the basics of this language?
- pas 6y agoYes. We used Rust to drive a few things via GPIO and USB-RS232 a few years ago on a Raspberry Pi, it was a pretty pleasant experience. Maybe take a look at this I2C lib: https://github.com/rust-embedded/rust-i2cdev https://github.com/rust-embedded/rust-i2cdev
- mjw1007 6y agoYes. Some of my first Rust projects were that sort of embedded thing.
- dbrgn 6y agoYes. Check out https://rust-embedded.github.io/book/ https://rust-embedded.github.io/book/.
- vvanders 6y agoYup, I've got a small little rust component that translates a couple industrial sensors on modbus + rtl_r443 over to an influx database and it's been happily running along for a few months now.
- cjhanks 6y agoDoesn't this mean that a conditional branch is added to all existing code which performs casting?
- oconnor663 6y agoI think in the specific case of casting a float to an int, more instructions will be added, but it doesn't have to be a branch. Here it looks like rustc emits a conditional move: https://godbolt.org/z/1cfqof https://godbolt.org/z/1cfqof
- rockmeamedee 6y agoThe post says The new API to cast in an unsafe manner is: let x: f32 = 1.0; let y: u8 = unsafe { x.to_int_unchecked() }; But as always, you should only use this method as a last resort. Just like with array access, the compiler can often optimize the checks away, making the safe and unsafe versions equivalent when the compiler can prove it. I believe for array access you can elide the bounds checking with an assert like assert!(len(arr) <= 255) let mut sum = 0; for i in 0..255 { sum += arr[i];//this access doesn't emit bounds checks in the compiled code } I'm guessing it would work like this with casts? assert!(x <= 255. && x >= 0); let y: u8 = x as u8; // no check
- steveklabnik 6y agoInterestingly enough, it looks like that does not in fact change how the check works https://godbolt.org/z/rdxrh1 https://godbolt.org/z/rdxrh1 Here's an example of how when it can detect it, it does the right thing: https://godbolt.org/z/hPqf69 https://godbolt.org/z/hPqf69 I am not an expert in these hints, maybe someone else knows!
- laszlokorte 6y agoIt should be `assert!(len(arr) >= 255)` (greater instead of less than), right?
- swagonomixxx 6y agoAssuming a unsigned byte, that range of values is between 0 and 255 inclusive, so `len(arr) <= 255` is correct.
- wtetzner 6y agoBut the loop goes up to 255. So if len(arr) == 10, then assert!(len(arr) <= 255) woulds succeed, but you'd get an out-of-bounds access if you tried to access arr at 11.
- wtetzner 6y agoIf you want to omit a bounds check, the compiler needs to know that the length of the array covers the upper bound of the loop, right?
- FartyMcFarter 6y ago> Just like with array access, the compiler can often optimize the checks away, making the safe and unsafe versions equivalent when the compiler can prove it. Can it "often" solve the halting problem as well? The hope that this kind of optimization will happen sounds a bit fanciful for any non-trivial part of a program.
- steveklabnik 6y agoYou would be surprised, at least with array access stuff. And, if it doesn't, you can often help it understand with a bit of work. Sometimes an assert before a loop or re-slicing something can take a check in the body of a loop and move it out to a single one. I ported a small C function to Rust recently that involved some looping, and all of the bounds checking was completely eliminated, even once I took the line-by-line port and turned it into a slightly higher level one with slices and iterators instead of pointer + length.
- pavehawk2007 6y agoRust has come a LOOOOOONG way. I'm really impressed with what they've accomplished in just a short time.
- thelastinuit 6y agoIF️RUST!
- devit 6y agoCan we please deprecate the "as" operator? Something so lossy and ill-conceived should not be a two-letter operator.
- steveklabnik 6y agoIt is possible, someone needs to do the RFC work. I would say that my personal take of the temperature is "vaguely pro but not a slam dunk", at least from the opinions I've seen. Only one way to find out.
- 95th 6y agoThen what do you propose for replacement? C++ style casts `(int) x` ?
- stefano_c 6y agoWhat would you suggest for replacing e.g. `u8 as usize`?
- steveklabnik 6y agoFor this one, you could use From/Into, because it cannot fail. For numerics that can fail, TryFrom/TryInto. The numeric casts are the easy part of this.
- cuddlybacon 6y agoAs someone who hasn't used Rust, I am curious about why Rust has macros. I use C++ at work, which admittedly isn't the language I use most, and macros are used quite a bit in the code base. I find they just make the code harder to read, reason about, debug, and sometimes even write. I don't see them really living up to their claimed value. Is there something different about Rust's macros that make them better?
- JeromeLon 6y agoThere is almost no intersection between the kind of things that can be done with the C++ macro system and the kind of things that can be done with the Rust macro system. They are not related. You can see them as another feature that is not available from C++.
- zozbot234 6y agoYou can get quite close to the use case for Rust macros by considering C++ template-based metaprogramming. Of course the biggest difference is that Rust macros have been designed from first principles, not as a clunky afterthought.
- kibwen 6y agoIndeed, Rust macros are a descendant of Scheme macros, not of C macros.
- 1ris 6y agoWriting macros (in any language) is a way of creating an abstraction. Creating abstractions is a way of automating the job of programming, making it ideally more efficient and less error prone. This is why people usually prefer java to basic. Marcos are a way of creating abstractions that are particular suited to be "concreted" by the compiler, making them a ideal match for programming languages that seek to be "close to the metal" like C, C++ and rust. C Macros are lacking because they are very primitive, e.g. they have not type system. They are also hardly turing complete. Its extremely hard to write a meaningful algorithm in them. IMHO the real macros of the C++ language are the templates and constexpr, althou they are limited in other ways. E.g. its hard to extend the syntax using them or do certain things like making the calling function return. They grow ever more powerful, with their own type system (concepts) and things like std::embed and static refection so they finally feel like a real language, alsbei a clumsy, pure functional language that feels alien a C++ programmer without exposure to haskell. Rust macros are actually meant to feel like Rust, not some ad-hoc bolted on language.
- deleted 6y ago[deleted]