News for hackers. Stuff that matters.
Re:What Rust Can Do That Other Languages Can't by akie on Monday February 06, 2017 @03:48AM (#13577681)
I have no idea what this means, and I have a masters in Computer Science and 20 years of industry experience. Enlighten me?
Re:What Rust Can Do That Other Languages Can't by m1el on Monday February 06, 2017 @04:15AM (#13577836)
Let's translate this code to C++:

    class X {
      public:
        Y* getY(void) {
          return &y;
        }
      private:
        Y y;
      };
    }
`getY` returns a pointer to the struct field, this field is allocated as a part of the struct. There is no way (in C++) to verify that this pointer does not outlive the struct itself. In other words, your pointer may become stale, and the compiler has no way to check for it.

Rust has a resource ownership model (borrow checker) that allows it to check at compile time that references do not outlive the data.

Re:What Rust Can Do That Other Languages Can't by humanrebar on Monday February 06, 2017 @07:04AM (#13578665)
A little closer would be to use a shared_ptr<X> and shared_ptr<Y> that share the same reference count (1). It's not exactly the same thing, though, since Rust gives you some safe usage checks that you don't get with shared_ptr. That is, vanilla Rust objects have lifetime semantics closer to unique_ptr than shared_ptr.

(1): See constructor number 7 here, which was designed for this purpose: http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_pt...

Re:What Rust Can Do That Other Languages Can't by dbaupp on Monday February 06, 2017 @03:44PM (#13583682)
It also isn't the same in that it comes with the cost of allocation and reference counting.
Re:What Rust Can Do That Other Languages Can't by akie on Monday February 06, 2017 @04:20AM (#13577864)
Ah, I see! Thank you.
Re:What Rust Can Do That Other Languages Can't by blub on Monday February 06, 2017 @07:45AM (#13578925)
Both the original example and your translation exhibit poor API design: it's an antipattern to return mutable references to member variables. This would remove all encapsulation, which is probably the most important principle of OOP.

Nevertheless, a better solution was pointed out in an answer on the blog and by humanrebar.

Re:What Rust Can Do That Other Languages Can't by erikdesjardins on Monday February 06, 2017 @09:33AM (#13579698)
The original example does not return a mutable reference; in Rust you must explicitly opt in to mutability. Compare [1] and [2].

[1]: https://play.rust-lang.org/?gist=78e7af18c6fc7d37d9df96be63a...

[2]: https://play.rust-lang.org/?gist=2072a18b674685f20c9d1504a88...

Re:What Rust Can Do That Other Languages Can't by blub on Monday February 06, 2017 @10:48AM (#13580489)
Oh ok, my bad.

Then the C++ translation above should probably be a const& in C++, which is acceptable. The returned reference could in that case be stored, but it's risky and a bad practice.

Re:What Rust Can Do That Other Languages Can't by nallerooth on Monday February 06, 2017 @07:05AM (#13578678)
Thanks!
Re:What Rust Can Do That Other Languages Can't by rubber_duck on Monday February 06, 2017 @03:56AM (#13577720)
In C++ it's quite easy to get burned by keeping a reference to something where the owner went out of scope eg.

   class Foo {
      int bar;
      int& getBar() { return bar; } 
   }
if you take ref of bar and Foo goes out of scope well fuck. It gets even worse, eg. :

    vector<int> foo;
    int& bar = foo[i];
    foo.push_back(1) 
that last line can cause foo to reallocate the buffer and bar is then invalid, meanwhile that code will compile without warnings (well I'm guessing it will I haven't done C++ in a year :) )
Re:What Rust Can Do That Other Languages Can't by satbyy on Monday February 06, 2017 @04:22AM (#13577871)
Just hit 'Run' here: http://rextester.com/BDGO47890

You can see the program crash

Re:What Rust Can Do That Other Languages Can't by rubber_duck on Monday February 06, 2017 @06:55AM (#13578615)
Nice, but the example crashes because you take a reference to uninitialized vector, if you initialize it and grow the vector I found that it will either keep "working fine" if you don't expect the data to change or randomly give garbage data - depending on compiler/stdlib - especially since the time when the buffer grows is implementation defined.

Here is a better example : http://rextester.com/MAJDQ8375

On VC++ it will return : Reference is 0 but value is 9

On clang it will return : Reference is 32579632 but value is 9

So let's say I wasn't mutating the 0 index, VC example would work fine at runtime and then clang would suddenly start giving garbage results. This has caused me week of debugging in a big code base.

Re:What Rust Can Do That Other Languages Can't by satbyy on Monday February 06, 2017 @09:22AM (#13579603)
Thanks for the catch!
Re:What Rust Can Do That Other Languages Can't by akie on Monday February 06, 2017 @04:21AM (#13577866)
Thank you! That clarifies it quite a bit. My C/C++ is too rusty to remember these internals...
Re:What Rust Can Do That Other Languages Can't by saghm on Monday February 06, 2017 @02:45PM (#13583165)
> My C/C++ is too rusty

Pun intended?

Re:What Rust Can Do That Other Languages Can't by usrusr on Monday February 06, 2017 @08:02AM (#13579036)
It's about safely exposing innards.

Are you are familiar with the substring problem in Java? Before 1.7.0_06, substrings where created using an offset into the buffer of the original string. Nice O(1) substring creation, the textbook example for benefits of immutability. Unfortunately, if you have long-lived, but short substrings taken out of short-lived, but long parent strings, the garbage collector won't find much to collect, since the substrings keep references to their parent buffers. This was no showstopper, but without immutability or in an environment with unmanaged memory it might very well be.

This Rust snippet is about similar cases of subcomponent sharing, just on a shorter timescale: the subcomponent is exposed in a way that allows the compiler to enforce that nobody keeps a reference for longer than it is guaranteed to be valid. You may look, you may even touch, but if you want to look again you have to ask again.

Other languages get by without this by garbage collection, by excessive precautionary copying or by simply hoping that the caller won't do anything stupid. Rust is unique in achieving the same runtime behavior as the latter but without the uncertainty. As a bonus, those un-keepable references cannot escape across concurrency borders so that in-place mutability becomes a lot more manageable.

Re:What Rust Can Do That Other Languages Can't by tatterdemalion on Monday February 06, 2017 @03:56AM (#13577715)
This is not a great way to ask a question. Your degrees and years of experience are not relevant to understanding the subject matter of this post. In order to enlighten you, we'd need to know what specifically was confusing about this article to you. What did you not understand?
Re:What Rust Can Do That Other Languages Can't by HerraBRE on Monday February 06, 2017 @05:48AM (#13578300)
I think it was actually a nice nod to all the folks who haven't got that much experience, and maybe felt silly for not understanding the code snippet. :)
Re:What Rust Can Do That Other Languages Can't by orf on Monday February 06, 2017 @03:57AM (#13577724)
I'd hope someone with that much experience would be able to grok at least some of it? I guess it isn't explained that well though.

As I understand it, if you have a structure that has a pointer to something (like a User struct pointing to an array of permissions or some such), and the memory pointed to will be freed when the structure is freed.

There is a case where code can keep a reference to this pointer around longer than the user struct it belongs to, so when code tries to use it it references an invalid pointer. This is bad. Rust takes care of this in some clever ways, so you cant have a pointer/reference that outlives it's parent.

Re:What Rust Can Do That Other Languages Can't by tatterdemalion on Monday February 06, 2017 @04:00AM (#13577743)
You've missed a critical point in the article: the structure does not have a pointer to something it has a member inline within its stack representation.

Any garbage collector could (with some overhead) prevent invalid memory access when we're talking about an object with a pointer to another object. Rust is able to validate the correctness of pointers to offsets within the stack representation of an object.

(Rust also validates the correctness of references to heap allocated objects as well, of course!)