3 ms·
I just noticed that although I said you can treat input as a stream, the way you consume the input in the example doesn't reflect that. If you have a primitive
by euccastro 19y ago
I just noticed that although I said you can treat input as a stream, the way you consume the input in the example doesn't reflect that. If you have a primitive (get-input) function like the one I assume above, you can wrap it in a more functional interface like this:
(define (new-input)
(cons 'input (get-input)))
(define (input? x)
(and (pair? x)
(eq (car x) 'input)))
(define (input-val input)
(cdr input))
(define (current-input input)
(if (input? input)
(input-val input)
(car input)))
(define (future-input input)
(if (input? input)
(new-input)
(cdr input)))
...
(define (run-game initial-world input)
(define (run-step world input)
...
(run-step (update-world world (current-input input))
(future-input input)))
(run-step initial-world input))
(run-game (make-initial-world) (new-input))
Now you can just pass a list as the input, to test stuff or to run a demo. Note that current-input behaves much like car; you can call it as many times as you want and you get the same result (this is called referential transparency). You can wrap your random number generator and other stuff in a similar way.
This can be further refactored so you can get out a stream of worlds too, so you can compare it to pre-recorded or hand authored test data. For practical purposes, you'll normally be testing smaller parts of your system; the same principle works for those.