In lecture, I've introduced set-structure-field!, as well as set! Here is the semantics for set-struct-field! (This is the way that Matthias has covered this; I'm told Joe didn't give the explanation in this manner:) ======================= *** make-struct Whenever you call make-struct (or cons or {make-,build-,}vector) what is the return value? We used to say it was the structure (some box containing the various pieces of info). But that was a lie; what actually gets returned is a new type of value, a "reference". References look like placeholders, but actually they are values. We write references as names with a hat. Example: If you evaluate (define ew (make-person 'elizabeth 1926 'brown ...)) here is what really happens: Evaluating the call to make-person returns the reference value ew^, where (define ew^ (make-person 'elizabeth 1926 'brown ...)) And thus the define "really" becomes: (define ew ew^) ;; I grant you, this '(define ew^ ...)' is mis-leading: ;; we're claiming ew^ is a value, yet we are 'define'ing it as if ;; it's a placeholder. Well, it's special in this way. ;; Technically this should be some sort of "define^". If we later evaluate the expression (define qeII ew), Then the rule of define is to evaluate the expression "ew", and associate placeholder qeII with the resulting value. Since the epression "ew" is a placeholder whose value is the reference "ew^", this hand-evaluates to (define qeII ew^) *** selectors If we apply a selector, the selector's argument should be a reference. I imagine the reference as a signpost: when an inquiry is made, it refers the selector off to the correct structure. (person-haircolor ew) ;; ew is placeholder; replace w/ its associated value. = (person-haircolor ew^) ;; To eval this, follow the ref & pull out the field. = 'purple *** set-structure-field! Now, as promised, the rule for set-structure-field!: (set-person-haircolor! ew 'purple) The rule is to evaluate each of the two arguments; the first value will be a reference (ew^ in this case). Then, go back and *rewrite* the call to make-person which is associated with that reference. This explains why qeII is changed: (person-haircolor qeII) = (person-haircolor ew^) = 'purple *** Note on writing references as Placeholders With Hats: In actuality we can't get at drScheme's references directly. But as with all hand-evaluations, what we write as the intermediate expressions can indeed be typed directly into drScheme and evaluate, and drScheme will return the correct answer. So people can type in a hand- eval, and use drScheme to check if they've done it correctly. ======================= Things to note when talking with students: - Use the term "reference", not "reference variable". - Emphasize that set-struct-field! does *not* change any associations: it only modifies the innards of some structure. So really set! and set-struct-field! are entirely distinct: one modifies placeholders' associations, the other doesn't. - References are values. When doing hand-evaluation and you reach a reference, you stop, not replacing the reference with what it refers to.