www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

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)))