[racket] Confusion with circular structs
I'm running into what I find to be surprising behavior with circular
structures (vertices of a simple graph).
Graphically (see code below to reproduce):
0 --> 1 ;; no problem
2-+ ;; also no problem
^-+
But when I try to add an edge between 0 and 2, I hit an infinite loop at
line 88 of racket/set.rkt (in 5.3.3) or line 447 of
racket/private/set-types.rkt (in the latest 5.90.0.2), both of which are
the hash-proc for set's gen:equal+hash.
Is this the expected behavior (after all, OCaml makes no guarantee of
termination for (=) on circular data)? I'm surprised that the self-edge on
2 doesn't result in the same. I've also tried to reproduce the same using
`shared', but I'm assuming I still misunderstand its functionality because
the result is not quite what I expect it to be.
Any insight would be much appreciated.
Nick
Welcome to Racket v5.90.0.2.
> (struct vertex (value preds succs) #:mutable #:transparent)
> (define v0 (vertex 0 (set) (set)))
> (define v1 (vertex 1 (set) (set)))
> (set-vertex-succs! v0 (set v1))
> (set-vertex-preds! v1 (set v0)) ;; 0 --> 1
> (equal? v0 (set-first (vertex-preds v1)))
#t
> (define v2 (vertex 2 (set) (set)))
> (set-vertex-preds! v2 (set v2)) ;; 2--+
> (set-vertex-succs! v2 (set v2)) ;; ^--+
> v2
#0=(vertex 2 (set #0#) (set #0#))
;; try to add the already existing set
> (set-vertex-succs! v0 (set-add (vertex-succs v0) v2)) ;; loops and loops
C-c C-c^Cuser break
context...:
.../racket/collects/racket/private/set-types.rkt:447:3: hash-proc
.../racket/collects/racket/private/set-types.rkt:447:3: hash-proc
.../racket/collects/racket/private/set-types.rkt:447:3: hash-proc
.../racket/collects/racket/private/set-types.rkt:447:3: hash-proc...
;; try to make a new set instead
> (set-vertex-succs! v0 (set v1 v2))
C-c C-c^Cuser break
context...:
.../racket/collects/racket/private/set-types.rkt:447:3: hash-proc
.../racket/collects/racket/private/set-types.rkt:447:3: hash-proc
.../racket/collects/racket/private/set-types.rkt:447:3: hash-proc
.../racket/collects/racket/private/set-types.rkt:447:3: hash-proc...
> (shared ([v0 (vertex 0 (set) succs0)]
[v1 (vertex 1 preds1 (set))]
[v2 (vertex 2 preds2 succs2)]
[succs0 (set v1 v2)]
[preds1 (set v0)]
[preds2 (set v0 v2)]
[succs2 (set v2)])
(values v0 v1 v2))
(vertex 0 (set) (set #0=(vertex 2 (set #0#) (set #0#))))
(vertex 1 (set (vertex 0 (set) (set #0=(vertex 2 (set #0#) (set #0#)))))
(set))
#0=(vertex 2 (set #0#) (set #0#))
;; I must be using `shared' incorrectly...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130726/b4b06143/attachment.html>