4 ms·
> you could forgo references altogether and code Rust as though it were C, with nothing but raw pointers, and it shouldn't take any more time to write than C D
by Const-me 10y ago
> you could forgo references altogether and code Rust as though it were C, with nothing but raw pointers, and it shouldn't take any more time to write than C
Disagree.
In C++ we have sophisticated debuggers, we have standard C library, STL with its containers, algorithms and lots more, boost and other third-party libraries.
When coding typical Rust, we have descent-quality standard library, also big set of third-party libraries.
When coding Rust as though it were C, we have almost nothing, because the rust’s standard library doesn’t expose unsafe API.
Unsafe Rust only takes same time to write as C++ if you’re coding something trivial, like a “Programming 101” homework. For anything even remotely useful, debugger and libraries make huge difference.
A single bounds checking feature (C++ has that with STL containers in debug builds, controlled by _GLIBCXX_DEBUG or _ITERATOR_DEBUG_LEVEL) can sometimes save hours.
- kibwen 10y ago> In C++ we have sophisticated debuggers What features do you look for in a sophisticated debugger? There's upstream support for Rust in GDB (https://np.reddit.com/r/rust/comments/4merw3/gdb_now_supports_debugging_programs_written_in/ https://np.reddit.com/r/rust/comments/4merw3/gdb_now_support...), I've seen people do reverse debugging with rr (http://huonw.github.io/blog/2015/10/rreverse-debugging/ http://huonw.github.io/blog/2015/10/rreverse-debugging/) as well as Valgrind, and the compiler knows how to emit debuginfo, and so should work with any tool that can read DWARF (like LLDB). Mozilla is investing even more into dedicated IDE support this year and the next. > the rust’s standard library doesn’t expose unsafe API What unsafe APIs would you like to see? Using Vec as an example, I see a function for constructing a Vec out of raw data (http://doc.rust-lang.org/std/vec/struct.Vec.html#method.from_raw_parts http://doc.rust-lang.org/std/vec/struct.Vec.html#method.from...), a function for mucking around with the private length field (http://doc.rust-lang.org/std/vec/struct.Vec.html#method.set_len http://doc.rust-lang.org/std/vec/struct.Vec.html#method.set_...), a function for receiving a raw pointer to the underlying buffer (http://doc.rust-lang.org/std/vec/struct.Vec.html#method.as_mut_ptr http://doc.rust-lang.org/std/vec/struct.Vec.html#method.as_m...)... we're far from opposed to adding low-level APIs for complete control over collections, all you need to do is ask for them and tell us why they'd be useful. :) > A single bounds checking feature I'm not sure what this is asking for. All Rust containers are bounds-checked by default.
- Const-me 10y ago> What unsafe APIs would you like to see? Well, here’s a simple example I’ve wrote above: “Some container that keeps some items + a linked list to track and evict the least recently used item from that container”. You know, LRU caches are everywhere. I remember in C++, I recently wrote something similar in three completely unrelated projects. Well, a linked list alone isn’t usually enough, but a linked list + unordered map that maps elements to list iterators do the job very well. To update the LRU order, I query the hashmap and get a list position, then I move that element to the list’s tail. And when I need to evict an element, I grab the list’s head and evict those. Note the following good things about this C++ solution: (1) All those operations (hashmap lookup, linked list reorder, linked list remove head) are O(1), i.e. I can have millions items in my cache, and still update my LRU order for practically no cost (a few pointer writes). (2) I didn’t wrote much code, only creatively combined what was already here in the C++ standard library. Now Rust. The safety means pointers to list nodes aren’t part of the list’s API. And without raw pointers, linked lists are nearly useless, because we can’t split or reorder them efficiently. If you’ll read the documentation for LinkedList<T>::split_off, you’ll find the complexity is O(n), while for most other languages, linked lists are famous for being able to do that for O(1). I’m not sure any efficient linked list API is possible within Rust memory management model, safe or unsafe.
- kibwen 10y ago> The safety means pointers to list nodes aren’t part of the list’s > API. A quick glance at LinkedList leads me to believe that there's no technical reason why we couldn't support a `split_at_node` function that takes a raw pointer to a list node (along with additional APIs that actually return raw pointers to list nodes, which themselves wouldn't need to be unsafe). And even if my intuition is wrong and there's some reason why the implementation of LinkedList in the standard library can't do this for some reason, I see no additional reason why some other implementation of linked lists couldn't do this. (The standard library implementation likely optimizes for convenience rather than power, given that our data structures guru has a complicated relationship with linked lists: http://cglab.ca/~abeinges/blah/too-many-lists/book/README.html#an-obligatory-public-service-announcement http://cglab.ca/~abeinges/blah/too-many-lists/book/README.ht... ). The fact that Rust doesn't favor these sorts of things hasn't stopped others from going ahead and writing implementations anyway: https://crates.io/search?q=intrusive https://crates.io/search?q=intrusive > I didn’t wrote much code, only creatively combined what > was already here in the C++ standard library. Rust definitely enjoys supporting this use case (heck, the stdlib even does it: http://doc.rust-lang.org/src/std/up/src/libstd/collections/hash/set.rs.html#105-107 http://doc.rust-lang.org/src/std/up/src/libstd/collections/h... ), but when it falls down please feel free to check to see if others have preceded you in scratching your itch: https://crates.io/search?q=lru https://crates.io/search?q=lru > I’m not sure any efficient linked list API is possible > within Rust memory management model, safe or unsafe. I'm still unsure what you're implying here, given that, again, unsafe code can use raw pointers willy-nilly (though as we've established, using the stdlib to compose data structures via raw pointers isn't always convenient).