Rust References - Few points - Request for comments

My mother is a special someone to me: she's my mother, after all. She is also unique in her DNA and stuff.

But she is one of 8 billion people in a planet. She is a human being. She is a person. She doesn't cease to be so just because she has other, additional special meaning.

(For making a more technical point, I could invoke the Liskov substitution principle at this point, but now that would be unhelpful.)

Anyway my point is that not knowing that references are pointers also leads to confusion. I intentionally didn't assert that they are "just like in C" or anything like that. Pointers are a much more general concept in computing, they aren't necessarily associated with any particular language.

1 Like

First, there's a distinction between what is true and technically correct, and what is useful:

A guy flying in a balloon is lost, and when flying over a village shouts to a villager below: "Where am I?" and the villager shouts back "You're in a balloon!"

And then, references are not pointers in exactly the same way pointers are not integers. They do fail the Liskov sustitution principle. They support some pointer-like operations, but not all. Specifically, a C pointer can either own or borrow, and such pointers can be used interchangeably. References can't, on principle. You can't even say the other way that pointer is a kind of a reference, because then you get circle-ellipse problem.

1 Like

Ideally I would like to remove those

Please don't imply that I'm trying to be pedantic. I'm not – I genuinely think that knowing why references are pointers is useful. I'd go as far as saying that it's necessary for building the right mental model. (Also, one can build a tree out of &Nodes, and I'm pretty sure I would do just that if I ever had the patience to build the AVR Rust toolchain and give it a shot on my ATmega328 board.)

I see this differently. To me, C pointers can't own, because C pointers don't have the ownership semantics aspect to their type. Do I get a type error in C if I try to move out from a value behind a pointer? No. Does a pointer I got from malloc() get automatically free()d when it goes out of scope? Also no. Do I get a compiler error when I copy a struct with a bunch of pointers which are supposed to be unique/"owning"? Still no. C doesn't even have the concepts of ownership or moving, so everything associated with these concepts is merely a question of convention.

Analogously, I'd say they can't borrow either – again, it's just not a thing in C, nothing enforces borrowing rules. So C pointers don't behave like a combination of owning and borrowing entities in Rust – they are simply completely ignorant of this dimension of typing and semantics.

To draw another analogy using human beings: I wouldn't call someone who's neither a doctor nor a lawyer an "expert in medicine and law," just because this person could perform both kinds of jobs equally badly.

What I mean to say is that Rust do auto de-referencing and from Programmer's point of view
that I can use t.f whether t : T or t : &T.

But I need to remember t is a reference and I cannot do t = q where q : T .

So based on discussion, can I conclude that
Rust references are "Pointers" ? or perhaps "Super Pointers" and Rust do auto-de-referncing ?

I'm not talking about mut or borrowing now.

You're using analogies of additive features (subclassing, being a doctor), but references are about restrictions (thus causing circle-ellipse problem in LSP). It's important what they don't allow compared to pointers.

I think this is-a pointer thing comes up because people really care about not copying, and this use-case overlaps with C's:

Borrowed Owned
&i32 Box<i32>
By reference &i32/int*
By value int

but equating that one case gives wrong mental model for what is not a reference. In C "not pointer" implies direct value and copying. In Rust "not reference" implies owning, saying nothing about indirection or copying.

Saying references are pointers suggests they exist on the Y axis (by-ref vs by-val) in the table above. But references in Rust exist on the other axis of ownership (by-ref vs owned). It happens that the by-ref case looks very similar, but they're part of different concepts, on different axis.

3 Likes

That's a brilliant insight. The differences between Rust's references and C`s pointers is multi-dimensional. Viewing those differences via projection into just one dimension is never going to provide sufficient understanding.

2 Likes

thanks for your explanation. I guess.. I getting the point

yes,...

On reflection, let's not let this discussion go too far off the rails.

discussion about whether references are pointers

By the same token, saying references are not pointers suggests the opposite: that they are copies. I would rather say "references are not just pointers", or "references are different from pointers", rather than simply saying "references are not pointers", which to my mind is even more likely to cause confusion. After all, if I were in a balloon and I shouted down to a person on the ground, "Where am I?" I certainly wouldn't want the answer to come back "You're not six miles west of Abilene!"

(Particularly if the intended meaning was "You're actually six miles west of Abilene and one hundred meters off the ground".)

But that is twisting my words. I never asserted that Rust references don't have additional properties to them. Those are exactly why they are useful, of course.

I disagree with this. These are inherently interrelated. How does owning not say anything about indirection or copying? An owning value means you can only move it, i.e. copying is not allowed. (Except for the very special case of Copy, which is just a subtype of Clone, and now that is really an orthogonal dimension.) It also means that the value in question itself is not behind indirection.

You are using Box as a counterexample, but I don't get why it should be a counterexample: it works perfectly consistently with other types. When you say let b = Box::new(42);, the Box-typed value in the variable b itself is definitely not behind indirection. It contains the indirection, but that is a completely different thing.

Or do you mean that ownership doesn't imply that a type has or has not pointers embedded in it? That doesn't work out as a difference, either. I could just as well create a typedef struct { void *inner; } Box in C, and then say the exact same things about it: when given Box b = Box { .inner = ptr }, the variable b is a value without indirection, and it contains a level of indirection, and that level of indirection is supposed to be unique, and it is an error to copy it.

The difference between C and Rust is "only" that C lets you do the wrong thing with its pointers. A pretty big difference in usability, but it doesn't imply that the two pieces of code do different things when used correctly, nor that they require a different mental model when it comes to understanding memory layout.

1 Like

But in the Rust book, the diagram implies that it is referring and there is a pointer in the diagram. As told by you the important point is that references are also about not owning.
So the dual view is required ?

I've replied in a separate thread to avoid flooding this one:

OP was creating notes for themselves, not creating a tutorial for others.

Sorry. That is not what I understood from "This is also my attempt to create material for persons who are new to programming." in the OP.

Whether I'm creating notes for myself or tutorial, the correctness of the notes is important from my perspective.

1 Like

You're right. I mis-read that sentence.

Sir, Absoluletely .. I agree .. But I'm pedantic (as I'm beginner) and trying to grasp the true construct.

Thanks for your effort in distilling the essence of concepts.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.