[plt-scheme] set! with structs

From: Jon Rafkind (workmin at ccs.neu.edu)
Date: Mon Nov 12 22:32:51 EST 2007

Oh yknow what, you are right. (set-foo-x! ...) expands to (#%app
set-foo-x! ...) and my #%app looks at all the values passed to it, so
yea it wasn't set! after all. I'll look into rebinding define-struct or

Carl Eastlund wrote:
> The set! form is not the atomic unit of mutation, it's the tool for
> mutating lexically bound variables.  A structure field isn't one of
> those, so structure mutators don't use set!.  Since you've rebound
> set! but not structure mutators, I don't know how your tool is
> detecting any mutation in the code below.  If it's only complaining
> about the reference to "a", regardless of mutation, then the mutators
> aren't your problem to begin with.  In any event, if you want to take
> control of structure mutators, you'll have to bind your own
> define-struct.
> --Carl
> On Nov 12, 2007 8:45 PM, Jon Rafkind <workmin at ccs.neu.edu> wrote:
>> Hi,
>>     I wrote a small module language for detecting race conditions by exporting my own versions of %#app and set!, among other things. The language works fine for normal variables but I was surprised to see races reported for different fields of structs. Like
>> (define-struct foo (x y))
>> (define a (make-foo 1 2))
>> (thread (lambda () (set-foo-x! a 1)))
>> (thread (lambda () (set-foo-y! a 1)))
>> Should be ok since different variables are being touched but the tool still complains because 'a' is used in two different threads without any locking. Long story short: how does 'set-foo-x!' eventually convert into 'set!' ? Is it actually dangerous to mutate fields of a structure in separate threads, in which case the tool told me something interesting?
>> Basically my tool keeps track of which threads accessed a given variable by testing the type during #%app and set!, but after looking at the transformation of set-foo-x! in the macro stepper I don't see where set! is being involved at all. It looks like set-foo-x! is bound to a (make-struct-mutator) thing which is a primitive defined in src/struct.c
>> FWIW, this is my set! macro
>>   (define-syntax (shared-set! stx)
>>     (syntax-case stx ()
>>       ((_ id expr)
>>        (if (not (identifier? #'id))
>>          (raise-syntax-error #f "not an identifier" stx #'id)
>>          #'(cond
>>            ((shared? id)
>>             (begin
>>               (do-access id) ;; this will report a race if one exists
>>               (set-shared-expr! id expr)))
>>            (else (set! id expr)))))))
> _________________________________________________
>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme

Posted on the users mailing list.