6 ms·
I’m still learning Rust, but the idea of having to use unsafe features to implement something as simple as a linked list seems “wrong” to me. What am I missing?
by avidphantasm 4y ago
I’m still learning Rust, but the idea of having to use unsafe features to implement something as
simple as a linked
list seems “wrong” to me. What am I missing?
- karmakurtisaani 4y agoI kind of hit a wall with Rust after realizing that something like doubly linked lists are difficult because when two nodes are referring to a node between them, you don't have a clear owner. So basically all situations where you have two or more references to an object need to be thought out carefully, and for me it was a bit of a let down (even though I fully understand the reasoning behind it and why it's useful). For now I stick with languages with GC.
- sph 4y agoUnpopular opinion but the whole memory safe idea is more niche than HN commenters would have us believe. Most of us are writing web apps and services that do not have strict memory requirements nor catastrophic failure modes. Dynamic languages and GC'd languages cover most of what our employers are paying us for: web apps, backend services. It is ironic to build super safe software, then deploying them on kubernetes, written in a GC'd language prone to nil dereference errors. Rust has its place, but it's a very small place. These days computers are so fast there's companies worth billions built on Ruby and Python, if you go native with a GC language you'll cover 98% of your needs. Rust IMHO has gone too far towards safety at the expense of developer ergonomics and pragmatism. We're so expensive that adopting a subpar language that is easier to grok is often a savvier business decision.
- wheelerof4te 4y ago"It is ironic to build super safe software, then deploying them on kubernetes, written in a GC'd language prone to nil dereference errors." This is something that escapes a lot of people nowadays. Everyone uses a browser and they are inherently unsafe.
- pjmlp 4y agoI feel it is a bit ironic that Apple and Google rather introduce mitigations for C++ in their browser engines than introduce Rust into the codebase. Meaning that Firefox's gains with Rust will eventually be lost given its market adoption is slowing reaching zero.
- ssokolow 4y agoGoogle is investigating Rust as part of a multi-pronged strategy and, while it has the "this is not an official Google project" boilerplate, the `autocxx` crate (a header-parser/code-generator addon for the `cxx` interop crate) is by Google employees. https://docs.google.com/document/d/e/2PACX-1vRZr-HJcYmf2Y76DhewaiJOhRNpjGHCxliAQTBhFxzv1QTae9o8mhBmDl32CRIuaWZLt5kVeH9e9jXv/pub https://docs.google.com/document/d/e/2PACX-1vRZr-HJcYmf2Y76D... https://www.chromium.org/Home/chromium-security/memory-safety/rust-and-c-interoperability/ https://www.chromium.org/Home/chromium-security/memory-safet... https://github.com/google/autocxx https://github.com/google/autocxx
- solar-ice 4y ago> Most of us are writing web apps Indeed. I'm a Rust dev somewhere it actually matters (video dev - we have to process 60 frames a second, for hours/days on end, with completely predictable performance, without crashing once) and I'd never pick it if I just wanted to build a webapp where nothing really matters and if the whole thing falls over we can just put it in a retry loop. There's plenty of code out there that /cannot/ be written in Ruby/Python/Go/C#. Rust solves some really hard problems for people working on that type of code. But it's not what most people on HN are working on. I think the problem is that a lot of web developers do not really understand that this type of code exists, and that languages which do not target web development can be exciting.
- sph 4y agoYour video app is a perfect example of where Rust shines. I'd add embedded development, data-intensive, fault-intolerant systems and game engines are perfect for this language. But without even going as far as frontend web applications, stuff like backend services, system services, GUI applications, CLI applications, etc., don't actually need all that much memory safety and control over allocations.
- a_c_s 4y agoThis feels a bit like complaining that a tank is badly designed because nobody drives them on the highway... My understanding is that Rust was designed to be a safe(er) language to write low-level system code than C/C++, not to compete with Python/Ruby/Java for web development applications.
- pjmlp 4y agoTrue, yet what you see around HN and other places are people trying to use it for web development.
- netizen-936824 4y agoFront end or back end? I see nothing wrong with rust on the back end, not sure how it would even work on the front
- pjmlp 4y agoWebAssembly.
- crabbygrabby 4y agoBingo, it's a true systems language. That said, the fact that people can and do write web applications(for practical reasons) with it kind of says something about it's breadth.
- pjmlp 4y agoThe whole point of system languages is that they reach the whole stack.
- sph 4y agoI'm not complaining about Rust. It's a very good language. I'm complaining about everybody on programming forums, including HN, seeing Rust as the replacement for most, if not all languages. My opinion is that Rust's ideal problem space is much narrower than people think.
- bluGill 4y agoYou might be right for the majority, but there are many other large groups who don't have computers that are more than fast enough. There are a lot of interesting and complex problems that can be solved in something like rust that the languages you name cannot be used for. Right now I'm using C++, but rust is of real interest to me (as is ADA, which in some variants lets me prove my code correct)
- Hirrolot 4y agoCompletely agree! When you need to compute numbers or deal with raw bytes, you have C. When you need to be high-level, you have Python, Java, C#, etc. Rust is applicable only in areas where you need both a high-level and systems language. Examples include interpreters, operating systems, browsers, game engines, etc. The hype of Rust just exceeds its problem domain.
- foldr 4y agoThere seems to be a myth that Rust is unusual in being memory safe. All modern GCed languages are memory safe (assuming you don't do anything obviously unsafe like manipulate raw pointers, which some languages might let you do if you really want to). >It is ironic to build super safe software, then deploying them on kubernetes, written in a GC'd language prone to nil dereference errors. Nil dereference errors don't demonstrate an absence of memory safety. If the runtime checks for a nil reference before dereferencing and then raises an exception, that's perfectly safe.
- Shikadi 4y agoI'm not sure if you understand what safe means in this context. One common example is modifying a vector element by reference. If you grab a reference to an item, push something else to the vector, then try to access through that reference, the vector may have re allocated during the push and you're either no longer looking at valid memory because it's been freed, or you're looking at a stale copy of the element. I don't think the null handling in rust is about memory safety so much as it is their choice in error handling. If you come across a null pointer dereference and your code doesn't handle it, that's a hidden bug. Triggering an exception and handling it is a valid approach, but there are trade-offs. If no code handles the nil exception for example then it's no better than crashing as you would in C. Wrapping things up in try catch can lead to missing recoverable errors or unexpected states. The choice to disallow null is one to avoid common bugs, not one for memory safety, as far as I understand it.
- foldr 4y agoI'm 100% sure that I understand what safe means in this context. All modern GCed languages are memory safe and will not access invalid memory regions unless you use specifically unsafe features. > One common example is modifying a vector element by reference. If you grab a reference to an item, push something else to the vector, then try to access through that reference, the vector may have re allocated during the push and you're either no longer looking at valid memory because it's been freed, or you're looking at a stale copy of the element. There aren't that many languages which both use GC and allow you to take references to elements of a vector. Go would be one example. I can assure you that you cannot access undefined memory regions by doing this in Go. (What would happen is that the original allocation backing the vector would be retained in addition to the new allocation.) >If no code handles the nil exception for example then it's no better than crashing as you would in C C programs are not guaranteed to crash when a pointer has an invalid value. Dereferencing a NULL pointer will reliably cause a crash if you're running the code on top of a modern general purpose operating system with memory protection, but invalid pointers (which don't necessarily have to be NULL) have the potential to access arbitrary memory regions without raising any kind of error.
- crabbygrabby 4y agoSo here's a weird thought, why should you ever write your own doubly linked list? Why shouldn't you use one that a community of people has vetted and juiced for performance instead? In C what I just said is for some reason heresy. But yes you are right, anytime you have two or more accesses to a data structure you do have to think a little harder about it. Usually you just want to use a reference to that object, sometimes it makes sense to clone it, sometimes you want to pass it by value and return it by value. In the case of doubly linked lists you probably want to drop into unsafe code. I get it though, GC languages are more zen in that regard.
- fizzynut 4y agoWriting your own data structures allows you to write it to suit the specific needs/constraints of your problem/domain. Typically that means you get something that is significantly simpler, faster and with a different feature set. Libraries are typically optimized for generic use, so are often more complex, slow, and difficult to extend with new features (both coding wise or the features might not be suitable / have trade offs for other people).
- crabbygrabby 4y agoWon't let me reply to fizzynut, but this is a reply to you. Yes making data structures is important, and the reality of that is, there are people in the ecosystem creating fancy ones which can be leveraged for your use case. If that doesn't exist then yea you have to write them. Sometimes that's difficult(you need to use unsafe), sometimes it's easyish and you can use all safe(I did this for a graph type). It can be done(lots of people are doing it), but I think what it shows is, data structures can be difficult to do correctly. In a worst case scenario you could write it in asm inside rust if you really need a low level control, or write it in C/unsafe rust and ffi or just write it in. Basically worst case scenario in rust is writing something closer to C.
- fizzynut 4y agoLots of people writing their own data structures and libraries should be a reflection of the different needs and diversity of the ecosystem, but if it's a reflection of difficulty then it tends to lead to a much narrower ecosystem. That isn't to say a narrow ecosystem is necessarily bad, it can often be good if a particular language is used for a specific domain as all the libraries and data structures will likely be a better fit for your problems. Going outside of those constraints can often be very punishing in those languages though.
- moth-fuzz 4y agothe thing about Rust's ownership model is that a reference is not ownership, it's 'borrowing', and should be treated as such. But - and here's the kicker - the borrow happens as long as that reference is stored, not just when it's accessed i.e. dereferenced. This makes a number of data structures and patterns difficult and impossible to implement as you can't keep track of references to anything. You can't really make an opaque handle, for example, that can do operations through a stored reference. You have to store some ID or something and then when you want to do operations you need to pass the original container to the function anyway - so what's the point of even having reference types at that point? IMHO Rust's lifetime analysis should consider borrows only at the point of dereference, not just whenever you encounter an & symbol. They already do that with raw pointers - you can have as many pointers as you want but you only need to mark `unsafe` if you actually dereference one. So at least someone on the team knows how to make that work functionally.
- ModernMech 4y agoYou’re missing that you don’t have to use unsafe, you use a wrapper type which is essentially a smart reference-counted pointer. Rust makes these things explicit.
- llllllllllll9 4y agoyou're not missing anything.
- deleted 4y ago[deleted]
- iopq 4y agoBecause it's a library feature, exactly the thing you should use "unsafe" in, since it should be simple enough to be obviously correct