New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Guide Redux: Pointers #15789

Closed
wants to merge 1 commit into
base: master
from

Conversation

Projects
None yet
@steveklabnik
Member

steveklabnik commented Jul 18, 2014

This is super, super WIP, but I'm going to go get lunch for a while, and figured I'd toss my work up here in case anyone wants to see my work as I do it.

This contains a new introductory section explaining the basics of pointers, and some pitfalls that Rust attempts to solve. I'd be interested in hearing how my explanation is, as well as if this belongs here. Pointers are such a crucial concept, I don't mind having a beginners' section on them in the main docs, even though our main audience is supposed to understand them already. Reasonable people may disagree, however.

@cburgdorf

This comment has been minimized.

Show comment
Hide comment
@cburgdorf

cburgdorf Jul 18, 2014

Contributor

👍 This is brilliant! I'm excited to read the rest of the pointer guide. I agree with Pascal that it would be nice to link to a explanation of Stack vs Heap there. It's probably out of the scope to describe such concepts here but how about just linking to this: http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap

Contributor

cburgdorf commented Jul 18, 2014

👍 This is brilliant! I'm excited to read the rest of the pointer guide. I agree with Pascal that it would be nice to link to a explanation of Stack vs Heap there. It's probably out of the scope to describe such concepts here but how about just linking to this: http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap

Pointers are useful in languages that are pass-by-value, rather than
pass-by-reference. Basically, languages can make two choices (this is made
up syntax, it's not Rust):

This comment has been minimized.

@kballard

kballard Jul 18, 2014

Contributor

How about "this is pseudocode", and then actually changing the syntax of the pseudocode to be more obviously non-Rust? e.g. something like

function foo(x) {
    x = 5
}

function main() {
    i := 1
    foo(i)
    // what is the value of i here?
}
@kballard

kballard Jul 18, 2014

Contributor

How about "this is pseudocode", and then actually changing the syntax of the pseudocode to be more obviously non-Rust? e.g. something like

function foo(x) {
    x = 5
}

function main() {
    i := 1
    foo(i)
    // what is the value of i here?
}

This comment has been minimized.

@cburgdorf

cburgdorf Jul 18, 2014

Contributor

I would probably not introduce things like := here and rather keep the "pseudocode" as simple as possible.

@cburgdorf

cburgdorf Jul 18, 2014

Contributor

I would probably not introduce things like := here and rather keep the "pseudocode" as simple as possible.

This comment has been minimized.

@kballard

kballard Jul 18, 2014

Contributor

I picked := because otherwise the reader may say "where did i come from?" I know that was actually my first question, "did i come from somewhere else or is this creating it?".

@kballard

kballard Jul 18, 2014

Contributor

I picked := because otherwise the reader may say "where did i come from?" I know that was actually my first question, "did i come from somewhere else or is this creating it?".

This comment has been minimized.

@steveklabnik

steveklabnik Jul 18, 2014

Member

I was actually wondering if I shouldn't just make the 'psuedocode' C. What do you think of that?

@steveklabnik

steveklabnik Jul 18, 2014

Member

I was actually wondering if I shouldn't just make the 'psuedocode' C. What do you think of that?

This comment has been minimized.

@cburgdorf

cburgdorf Jul 18, 2014

Contributor

Can you post in a comment how that would look like?

@cburgdorf

cburgdorf Jul 18, 2014

Contributor

Can you post in a comment how that would look like?

This comment has been minimized.

@steveklabnik

steveklabnik Jul 19, 2014

Member
void foo(int x) {
    x = 5;
}

int main(void) {
    int i = 1;
    foo(i);
    // what is the value of i here?
}

The issue with this is that C is not pass-by-reference, but we're about to pretend that it is for the sake of discussion...

@steveklabnik

steveklabnik Jul 19, 2014

Member
void foo(int x) {
    x = 5;
}

int main(void) {
    int i = 1;
    foo(i);
    // what is the value of i here?
}

The issue with this is that C is not pass-by-reference, but we're about to pretend that it is for the sake of discussion...

This comment has been minimized.

@bjeanes

bjeanes Jul 19, 2014

Javascript maybe? I'm actually not positive that Javascript doesn't pass by value for ints, but maybe using a more complex type like an array and pushing something to it will be clear enough and still simple enough

function foo(a) {
    a.push(1)
}

function main() {
    var a = [];
    foo(a)
    // what is the value of a here?
}
@bjeanes

bjeanes Jul 19, 2014

Javascript maybe? I'm actually not positive that Javascript doesn't pass by value for ints, but maybe using a more complex type like an array and pushing something to it will be clear enough and still simple enough

function foo(a) {
    a.push(1)
}

function main() {
    var a = [];
    foo(a)
    // what is the value of a here?
}

This comment has been minimized.

@steveklabnik

steveklabnik Jul 19, 2014

Member

Ahh, I like that.

@steveklabnik

steveklabnik Jul 19, 2014

Member

Ahh, I like that.

This comment has been minimized.

@cburgdorf

cburgdorf Jul 21, 2014

Contributor

I like the pseudocode example with the simple int more. I would just go with the C syntax. We don't have to tell anyone "hey, this is C syntax" so if we say "This is pseudocode. Let's pretend this is pass by reference" that should be just fine.

@cburgdorf

cburgdorf Jul 21, 2014

Contributor

I like the pseudocode example with the simple int more. I would just go with the C syntax. We don't have to tell anyone "hey, this is C syntax" so if we say "This is pseudocode. Let's pretend this is pass by reference" that should be just fine.

println!("{}", succ_number);
i = 1
foo(&i)
// what is the value of i here?
}

This comment has been minimized.

@kballard

kballard Jul 18, 2014

Contributor

As above, this pseudocode might be written

function foo(&int x) {
    *x = 5
}

function main() {
    i := 1
    foo(&i)
    // what is the value of i here?
}
@kballard

kballard Jul 18, 2014

Contributor

As above, this pseudocode might be written

function foo(&int x) {
    *x = 5
}

function main() {
    i := 1
    foo(&i)
    // what is the value of i here?
}

This comment has been minimized.

@kballard

kballard Jul 18, 2014

Contributor

All subsequent pseudocode blocks should also then be rewritten for the same syntax, but I won't call out each one individually.

@kballard

kballard Jul 18, 2014

Contributor

All subsequent pseudocode blocks should also then be rewritten for the same syntax, but I won't call out each one individually.

@abernardes

This comment has been minimized.

Show comment
Hide comment
@abernardes

abernardes Jul 18, 2014

👍 on the link with explanations about heaps and stacks. The tutorial lost me when it mentioned heaps and stacks. Wikipedia wasn't very helpful. Thank you for that link @cburgdorf.

abernardes commented Jul 18, 2014

👍 on the link with explanations about heaps and stacks. The tutorial lost me when it mentioned heaps and stacks. Wikipedia wasn't very helpful. Thank you for that link @cburgdorf.

@bachm

This comment has been minimized.

Show comment
Hide comment
@bachm

bachm Jul 19, 2014

It would generally be useful to have a cheat sheet showing pointer types and their typical usage with cell types. Something like:

Name Representation Purpose
Reference &T Allows one or more entities to read T.
Mutable reference &mut T Allows a single entity to read from and write to T.
Reference and Cell &Cell<T> Allows one or more entities to read from and write to T, provided T implements the Copy trait.
Owned pointer (Unique pointer?) Box<T> Allocates T on the heap, with unique ownership, allowing read and write access to T.
Rc pointer Rc<T> Allocates T on the heap, with shared ownership, allowing read access to T.
Rc pointer and RefCell Rc<RefCell<T>> Same as above, plus one-at-a-time write access to T.
Arc pointer Arc<T> Allocates T on the heap, with shared ownership across thread boundaries, allowing read access to T.
Arc pointer and Mutex Arc<Mutex<T>> Same as above, plus one-at-a-time write access to T.
Raw pointer *const T Unrestrained and potentially unsafe read access to T.
Raw mutable pointer *mut T Same as above, plus unrestrained and potentially unsafe write access to T.

The above is pretty basic. The purpose descriptions in particular need some work. The guide also needs to decide what names to use. Should we refer to Arc<T> as Arc pointer or atomically reference counted pointer?

By the way, I'm not sure I like the term owned pointer, because "owned" refers to the pointer itself, whereas the the key concept is the pointer owning the data it points to. At least that's how I interpret the name.

bachm commented Jul 19, 2014

It would generally be useful to have a cheat sheet showing pointer types and their typical usage with cell types. Something like:

Name Representation Purpose
Reference &T Allows one or more entities to read T.
Mutable reference &mut T Allows a single entity to read from and write to T.
Reference and Cell &Cell<T> Allows one or more entities to read from and write to T, provided T implements the Copy trait.
Owned pointer (Unique pointer?) Box<T> Allocates T on the heap, with unique ownership, allowing read and write access to T.
Rc pointer Rc<T> Allocates T on the heap, with shared ownership, allowing read access to T.
Rc pointer and RefCell Rc<RefCell<T>> Same as above, plus one-at-a-time write access to T.
Arc pointer Arc<T> Allocates T on the heap, with shared ownership across thread boundaries, allowing read access to T.
Arc pointer and Mutex Arc<Mutex<T>> Same as above, plus one-at-a-time write access to T.
Raw pointer *const T Unrestrained and potentially unsafe read access to T.
Raw mutable pointer *mut T Same as above, plus unrestrained and potentially unsafe write access to T.

The above is pretty basic. The purpose descriptions in particular need some work. The guide also needs to decide what names to use. Should we refer to Arc<T> as Arc pointer or atomically reference counted pointer?

By the way, I'm not sure I like the term owned pointer, because "owned" refers to the pointer itself, whereas the the key concept is the pointer owning the data it points to. At least that's how I interpret the name.

@steveklabnik

This comment has been minimized.

Show comment
Hide comment
@steveklabnik

steveklabnik Jul 19, 2014

Member

@bachm, I really like this idea.

Member

steveklabnik commented Jul 19, 2014

@bachm, I really like this idea.

@steveklabnik

This comment has been minimized.

Show comment
Hide comment
@steveklabnik

steveklabnik Jul 19, 2014

Member

I added the cheat sheet, and modified it a bit

Member

steveklabnik commented Jul 19, 2014

I added the cheat sheet, and modified it a bit

@steveklabnik

This comment has been minimized.

Show comment
Hide comment
@steveklabnik

steveklabnik Jul 19, 2014

Member

Okay. This now has significant upgrades, and is at least as far along as the current pointer guide. I'd like to stop work here, get this reviewed, and then merge it. The other sections can come later.

Member

steveklabnik commented Jul 19, 2014

Okay. This now has significant upgrades, and is at least as far along as the current pointer guide. I'd like to stop work here, get this reviewed, and then merge it. The other sections can come later.

@steveklabnik

This comment has been minimized.

Show comment
Hide comment
@steveklabnik

steveklabnik Jul 19, 2014

Member

Oh, with the exception of the psudocode issue. That needs sorted before a merge.

Member

steveklabnik commented Jul 19, 2014

Oh, with the exception of the psudocode issue. That needs sorted before a merge.

## Best practices
This part is coming soon.

This comment has been minimized.

@huonw

huonw Jul 20, 2014

Member

This section is easy: "Avoid unless you are interacting with syntax::ast." :P

@huonw

huonw Jul 20, 2014

Member

This section is easy: "Avoid unless you are interacting with syntax::ast." :P

This comment has been minimized.

@steveklabnik

steveklabnik Jul 20, 2014

Member

😄 😅

@steveklabnik

steveklabnik Jul 20, 2014

Member

😄 😅

This comment has been minimized.

@huonw

huonw Jul 20, 2014

Member

(erm, this was meant to go on Gc... haha, failed joke.)

@huonw

huonw Jul 20, 2014

Member

(erm, this was meant to go on Gc... haha, failed joke.)

@bluss

This comment has been minimized.

Show comment
Hide comment
@bluss

bluss Jul 21, 2014

Contributor

I would say that Cell and RefCell are containers, not pointers. (They are not indirections, just encapsulations). Of course they are rather special containers, so they should be treated on their own.

Maybe it is wise to separate basic pointer types and smart pointer types in two categories / headings for the table, just to not have readers freak out about the amount of pointers.

Contributor

bluss commented Jul 21, 2014

I would say that Cell and RefCell are containers, not pointers. (They are not indirections, just encapsulations). Of course they are rather special containers, so they should be treated on their own.

Maybe it is wise to separate basic pointer types and smart pointer types in two categories / headings for the table, just to not have readers freak out about the amount of pointers.

@steveklabnik

This comment has been minimized.

Show comment
Hide comment
@steveklabnik

steveklabnik Jul 21, 2014

Member

The line gets very blurry. I consider anything that implements Deref and DerefMut to be a 'smart pointer.'

Member

steveklabnik commented Jul 21, 2014

The line gets very blurry. I consider anything that implements Deref and DerefMut to be a 'smart pointer.'

@bluss

This comment has been minimized.

Show comment
Hide comment
@bluss

bluss Jul 21, 2014

Contributor

Absolutely, but Cell and RefCell don't implement Deref/Mut at all. Smart pointers are Rc, Arc, Gc, etc.

RefCell has associated handles that are smart pointers -- Ref and RefMut. But so has Mutex<T>, it has MutexGuard which is a smart pointer and a RAII guard at the same time.

Contributor

bluss commented Jul 21, 2014

Absolutely, but Cell and RefCell don't implement Deref/Mut at all. Smart pointers are Rc, Arc, Gc, etc.

RefCell has associated handles that are smart pointers -- Ref and RefMut. But so has Mutex<T>, it has MutexGuard which is a smart pointer and a RAII guard at the same time.

@steveklabnik

This comment has been minimized.

Show comment
Hide comment
@steveklabnik

steveklabnik Jul 21, 2014

Member

Okay, addressed everything else so far.

Member

steveklabnik commented Jul 21, 2014

Okay, addressed everything else so far.

@cmr

This comment has been minimized.

Show comment
Hide comment
@cmr

cmr commented on 377b250 Jul 26, 2014

r+

@bors

This comment has been minimized.

Show comment
Hide comment
@bors

bors Jul 26, 2014

Contributor

saw approval from cmr
at steveklabnik@377b250

Contributor

bors commented on 377b250 Jul 26, 2014

saw approval from cmr
at steveklabnik@377b250

This comment has been minimized.

Show comment
Hide comment
@bors

bors Jul 26, 2014

Contributor

merging steveklabnik/rust/guide_pointers = 377b250 into auto

Contributor

bors replied Jul 26, 2014

merging steveklabnik/rust/guide_pointers = 377b250 into auto

This comment has been minimized.

Show comment
Hide comment
@bors

bors Jul 26, 2014

Contributor

steveklabnik/rust/guide_pointers = 377b250 merged ok, testing candidate = cf1381c

Contributor

bors replied Jul 26, 2014

steveklabnik/rust/guide_pointers = 377b250 merged ok, testing candidate = cf1381c

This comment has been minimized.

Show comment
Hide comment
@bors

bors Jul 26, 2014

Contributor

fast-forwarding master to auto = cf1381c

Contributor

bors replied Jul 26, 2014

fast-forwarding master to auto = cf1381c

bors added a commit that referenced this pull request Jul 26, 2014

auto merge of #15789 : steveklabnik/rust/guide_pointers, r=cmr
This is super, super WIP, but I'm going to go get lunch for a while, and figured I'd toss my work up here in case anyone wants to see my work as I do it.

This contains a new introductory section explaining the basics of pointers, and some pitfalls that Rust attempts to solve. I'd be interested in hearing how my explanation is, as well as if this belongs here. Pointers are such a crucial concept, I don't mind having a beginners' section on them in the main docs, even though our main audience is supposed to understand them already. Reasonable people may disagree, however.

@bors bors closed this Jul 26, 2014

@steveklabnik steveklabnik deleted the steveklabnik:guide_pointers branch Jul 30, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment