Make `take' less forceful -- so now (take 0 (error "foo")) returns '()

instead of throwing an error.
This commit is contained in:
Eli Barzilay 2011-01-26 15:51:23 -05:00
parent d2c2112ebc
commit 40610643bf

View File

@ -575,22 +575,20 @@
;; Extra functionality that is useful for lazy list stuff ;; Extra functionality that is useful for lazy list stuff
(define* (take n l) (define* (take n l)
(let ([n0 (! n)] [l (! l)]) (let ([n0 (! n)])
(if (exact-nonnegative-integer? n) (unless (exact-nonnegative-integer? n)
(raise-type-error 'take "non-negative exact integer" 0 n l))
(let loop ([n n0] [l l]) (let loop ([n n0] [l l])
(if (zero? n)
'()
(let ([l (! l)])
(cond [(null? l) (cond [(null? l)
(if (n . > . 0)
;; it would be fine to force the whole list (since we now ;; it would be fine to force the whole list (since we now
;; know it's finite), but doing so means keeping a reference ;; know it's finite), but doing so means keeping a reference
;; to its head, which can lead to memory leaks. ;; to its head, which can lead to memory leaks.
(error 'take "index ~e too large for input list" n0) (error 'take "index ~e too large for input list" n0)]
'())] [(pair? l) (cons (car l) (~ (loop (sub1 n) (cdr l))))]
[(pair? l) [else (error 'take "not a proper list: ~e" l)]))))))
(if (zero? n)
'()
(cons (car l) (~ (loop (sub1 n) (! (cdr l))))))]
[else (error 'take "not a proper list: ~e" l)]))
(raise-type-error 'take "non-negative exact integer" 0 n l))))
;; not like Haskell's `cycle' that consumes a list ;; not like Haskell's `cycle' that consumes a list
(define* (cycle . l) (define* (cycle . l)