Rusting

The section where I examine what I am learning when compiling Rust code.

21

AUG
2014

Asking Better Questions

I've been playing with some Rust lately and learning a bunch of new concepts.

As part of my experimentation, I built an RPN calculator in the language, just as an exercise that would require a moderate amount of code to be worked out. Honestly, I don't fully understand everything that I had to do to get this code working yet. Maybe 20% of it came about as me following instructions from what seem to be very helpful compiler errors.

I wanted to start attacking these concepts that I didn't understand to increase my knowledge. Of course, I was impatient. I had some working code and I knew what I was missing, so I jumped into IRC, pointed at the code, and asked some not-at-all complete questions. All I got was crickets.

This isn't a failing of the Rust community. It's a lesson I have to relearn every now and then. You have to take the time to present a good enough question that answering it is easy enough and worth it. It's hard work to get your head around 100 lines of code and, even if you do, you'll still be missing plenty of context if the question isn't really well formed. Given that, most people just ignore the question. That's probably for the better too, because any answers provided likely would have missed the points I really needed help with.

What it did do was remind me that I needed to ask better questions. Today I took the time to build a small example that addressed one of my key confusions with Rust so far: Lifetimes (plus Ownership, Borrowing, and References it turns out). Here's the code I whipped up:

// I'm trying to make sure I have my head around "lifetimes"
// after a few readings of the guide:
// http://doc.rust-lang.org/guide-lifetimes.html.  The following is
// a simple example of what I think I now know that I'll try to explain
// in this comment.
//
// Because the letters are "borrowed references," (Do I have my terms right?)
// they could potentially be freed before the Lists struct that contains them.
// Since this possibility exists, Rust requires the explicit lifetime 'a which
// indicates that the lifetime of a created Lists instance is tied to whatever
// references were passed into the letters slot.

#[deriving(Show)]
struct Lists<'a> {
    numbers: Vec<int>,
    letters: Vec<&'a str>
}

fn main() {
    let lists = Lists{numbers: vec![1, 2, 3], letters: vec!["A", "B", "C"]};
    println!("{}", lists);
}

I made a Gist out of that and then went back to IRC to ask people how correct my current understanding was. The effort really paid off. I got some great clarifications:

JEG2
  Can anyone tell me if my understanding of the explicit lifetime
  in this example, as explained by my comment, feels correct?
  https://gist.github.com/JEG2/ae7746544cef14be1606
…
kimundi
  JEG2: That sounds right
…
steveklabnik
  JEG2: oh hey!!!!
  JEG2: good to see you here :)
  <3
Sharp
  JEG2: It's very close to being right (I *think*). Lists and letters
  must have the same lifetime, period. It's not that Lists acquires
  the lifetime of letters when it's created.
kimundi
  JEG2: Not that in this example you are using string literals,
  which have 'static lifetime and thus the references are always valid
JEG2
  steveklabnik: Hey steve. Thanks.
steveklabnik
  JEG2: the lifetime guide is _terrible_ btw, and as soon as my guide
  is wrapped up, which should be this week, it's next on the re-write train
…
kimundi
  Sharp: Eh, that doesn't sound right
…
JEG2
  steveklabnik: Good to know. Thanks.
…
Sharp
  kimundi: Well, actually I think Lists is bound to live at most
  as long as any one of its lifetime parameters. So yeah, you're right.
  I am clearly still confused about lifetimes :P
kimundi
  yeah, that sounds more correct :)
  No, wait
…
kimundi
  Eh, nevermind, its correct. List can not live longer as the 'a lifetime
  because else it would not be able to be created.
…
Dr-Emann
  JEG2: minor thing: everything has a lifetime, whether it
  contains references or not. Rust doesn't just create one
  when there's a possibility of premature frees. It only
  makes you be explicit with them in those cases though.
…
JEG2
  Sharp and Dr-Emann: Good clarifications on lifetimes. Thank you.
Sharp
  You're welcome, glad you could get something out of my confusion :)
…
steveklabnik
  JEG2: i left a comment on your gist too
Dr-Emann
  JEG2: of note is that even though the lifetime of the references
  is defined as the same as the lifetime of the containing struct,
  you can store any reference which lives _at least_ as long as the struct.
steveklabnik
  JEG2: make that two comments
…
JEG2
  Dr-Emann: Ah, I did not know that. So it's legal for my reference
  to outlive the struct?
…
Dr-Emann
  JEG2: they do, in your case, even. You pass literal strings,
  which are references into read only memory in the executable itself.
  They live for the entirety of the program.
…
JEG2
  Dr-Emann: Gotcha.
Dr-Emann
  JEG2: they have the special lifetime 'static. But you can also
  make a string on the stack and include references into it,
  as long as your struct doesn't outlive the String.
JEG2
  steveklabnik: Thanks for the comments. I'm getting a more complete picture.
…
steveklabnik
  JEG2: awesome. I -really really- want to make sure we explain this well,
  but we're not quite there yet.

As Steve Klabnik said, he also posted some very helpful comments on my Gist.

In other words, I got quite a bit of help. That help is also on public IRC logs and Gists, so it might even be of use to others.

It really pays to spend some time developing your question asking skills and then working on remembering to put those skills to use.

In: Rusting | Tags: Community & Rust | 0 Comments
Comments (0)
Leave a Comment (using GitHub Flavored Markdown)

Comments on this blog are moderated. Spam is removed, formatting is fixed, and there's a zero tolerance policy on intolerance.

Ajax loader