test-pure-safe.rkt (3024B)
1 #lang typed/racket 2 3 (module test typed/racket 4 (require delay-pure 5 typed/rackunit) 6 7 (check-equal? (force (let ([x (vector-immutable 1 2 3)]) 8 (delay/pure/stateless (vector-ref x 0)))) 9 1) 10 11 (check-equal? (force (force (let ([x (vector-immutable 1 2 3)]) 12 (delay/pure/stateless 13 (delay/pure/stateless (vector-ref x 0)))))) 14 1) 15 16 (define f0 17 (let ([x (vector-immutable 'a 'b 'c)]) 18 (let () 19 (define-pure/stateless 20 (: f (→ Integer 21 (Listof Integer) 22 (Rec R (List* Integer Symbol (Promise R))))) 23 (define (f [n : Integer] [big : (Listof Integer)]) 24 : (Rec R (List* Integer Symbol (Promise R))) 25 (cons (length big) 26 (cons (vector-ref x (modulo n 3)) 27 (delay/pure/stateless (f (add1 n) 28 (reverse (cons (length big) 29 big)))))))) 30 (f 0 '())))) 31 32 ;; Check that the first 100 elements are as expected: 33 (check-equal? (let rec : (Listof (List Integer Symbol)) ([i 0] [fi f0]) 34 (if (>= i 100) 35 '() 36 (cons (list (car fi) (cadr fi)) 37 (rec (add1 i) (force (cddr fi)))))) 38 (for/list : (Listof (List Integer Symbol)) 39 ([a (in-list (range 100))] 40 [b (in-cycle (in-list '(a b c)))]) 41 (list a b))) 42 43 (: travel-far (→ Number 44 (Rec R (List* Integer Symbol (Promise R))) 45 (List Integer Symbol))) 46 (define (travel-far i fi) 47 (if (= i 0) 48 (list (car fi) (cadr fi)) 49 (travel-far (sub1 i) (force (cddr fi))))) 50 51 (check-equal? (travel-far 0 f0) '(0 a)) 52 (check-equal? (travel-far 1 f0) '(1 b)) 53 (check-equal? (travel-far 2 f0) '(2 c)) 54 (check-equal? (travel-far 3 f0) '(3 a)) 55 (check-equal? (travel-far 99 f0) '(99 a)) 56 (check-equal? (travel-far 1000 f0) '(1000 b)) 57 58 ;; Test showing that the promise is not cached: we follow a very long sequence 59 ;; of recursive promises, while still holding a reference to the first in f0, 60 ;; if caching occurs we will go out of memory. 61 ;; Since the state of each promise contains a fresh list (reversed from the 62 ;; previous promise's state with an extra element consed in front), the total 63 ;; size would be quadratic in the number of steps if all the intermediate 64 ;; promises were cached. 65 ;; This test runs for about 75 seconds on my machine. It allocates at least 66 ;; (* 50000 50000 1/2) cons cells, which, with 64 bits = 8 bytes per cons cell 67 ;; amounts to (/ (* 50000 50000 1/2 8) (* 1024 1024 1024)) ≅ 9 GiB of RAM, 68 ;; which should be enough to make the travis build fail if caching occurs. 69 (module config info 70 (define timeout 600)) 71 (check-equal? (travel-far 50000 f0) '(50000 c)))