[racket] struct equality?
SOLVED!
Although the struct I was comparing was #:transparent, its parent was
not. Once I added #:transparent to that declaration everything worked.
<sigh>
Thanks for the help for what turned out to be me not being careful
enough with the details.
Todd
On Tue, Jul 6, 2010 at 12:59 PM, Neil Toronto <neil.toronto at gmail.com> wrote:
> Todd O'Bryan wrote:
>>
>> OK, this is harder than I thought. The struct is defined at the top
>> level, so under what conditions might it be re-defined?
>>
>> Also, will an accessor of the form struct-name-field work with any
>> struct of name struct-name, or does it only work with structs that are
>> in the same scope?
>
> The only time I know of that equivalent #:transparent structs don't compare
> equal is when they're defined in different phases. If there's a struct type
> called A that you require both normally and for-syntax, the normal make-A
> will create a struct of a different type than the for-syntax make-A.
>
> It's hard to observe the difference by accident, so seeing it is surprising.
> Here's a demo. In the following, module 'a makes a struct type A and
> provides it. Module 'b requires it normally (phase 0) and for-syntax (phase
> 1), and creates A-type values in both phases. Then an evil macro uses syntax
> quasiquote/unquote to make the phase 1 value visible in phase 0:
>
>> (module a racket
> (define-struct A (value) #:transparent)
> (provide (struct-out A)))
>> (module b racket
> (require 'a (for-syntax 'a)) ; require 'a in phase 0 and phase 1
> (define a1 (make-A 1)) ; ph-0 value, ph-0 constructor
> (define-for-syntax a2 (make-A 1)) ; ph-1 value, ph-1 constructor
> ; get a2 into phase 0 as a quoted struct value
> (define-syntax (get-a2 stx)
> (syntax-case stx ()
> [(_) #`#,a2]))
> (define a2 (get-a2)) ; ph-0 value made by ph-1 constructor
> (provide a1 a2))
>> (require 'a 'b) ; require 'a and 'b in phase 0
>> (equal? a1 a2)
> #f
>> (A-value a1) ; can use phase 0 A-value to get value from a1
> 1
>> (A-value a2) ; CANNOT use phase 0 A-value to get value from a2
> A-value: expects args of type <struct:A>; given instance of a different
> <struct:A>
>
>
> If it helps, you can think of the first three lines in module 'b as
>
> (require (prefix-in phase-0- 'a)
> (prefix-in phase-1- (for-syntax 'a)))
> (define a1 (phase-0-make-A 1))
> (define-for-syntax a2 (phase-1-make-A 1))
>
>
> FWIW, I have no idea why structs are treated specially like this. It works
> fine with primitive types like strings:
>
> #lang racket
> (define a1 "hello")
> (define-for-syntax a2 "hello")
> (define-syntax (get-a2 stx)
> (syntax-case stx ()
> [(_) #`#,a2]))
>
>> (equal? a1 (get-a2))
> #t
>
>
> Seems it would be useful occasionally to not worry about the phase
> distinction. Hope this helps!
>
> Neil T
>
>