views:

112

answers:

1

what's wrong with this code in Dr.Scheme using Pretty Big? i seem to remember doing similar things in the past with no problem.

(lambda (x y) (set! (Frame-variables res) (append (Frame-variables res) (list (cons x y)))))

which returns the following error:

set!: not an identifier in: (Frame-variables res)

if i omit the (set! (Frame-variables res) ... ) part it works fine except of course that my list doesn't actually change. so it recognizes the second (Frame-varialbes res) but not the first one? or what's the deal with set! in that context?

hopefully you recognize that i have a struct called Frame with a variables field which is a list.

+4  A: 

The problem:

How set! works. What it really does is bind a name to an object that is hanging around in memory somewhere. When you do set!, it changes what that name refers to.

That's the error: (Frame-variables res) isn't an identifier, so it can't make it refer to something else.

The fix:

What you're trying to do is mutate a member of a struct. What you need to do is change that structure member to be mutable, and then use the mutator that will be made.

(define-struct frame (a b ... c [variables #:mutable] e ...))

Then, you can use

(set-frame-variables! res (list "new" "value"))

This will mutate your structure as desired.

The Lecture:

I'm wondering if you're choosing a good design for your program. Mutating and appending to a list are both operations that make me question a design in Scheme.

Also, it looks like what you're doing is trying to maintain an association list of variables, based on what you've called them. This isn't really efficient, and perhaps you should consider something else like a Hash Table

Relevant documentation:

http://docs.plt-scheme.org/reference/define-struct.html#%28form.%5F%28%28lib.%5Fscheme/base..ss%29.%5Fdefine-struct))

McPherrinM
Good answer in general, but see also srfi-17 and swindle, both provide such a "generalized `set!`". While it's true that in general you shouldn't use mutation if it can be avoided, it is sometimes helpful to do so -- and one advantage of generalized setters is that you can write an `inc!` macro that becomes very useful.
Eli Barzilay