Throw an error if the number input for `take' is too big.
Note that this is usually delayed so it's not too useful. Note that it *doesn't* force the list -- see the explanation in the comment. (Related to PR 11458.)
This commit is contained in:
parent
fd53321823
commit
698b3a6c90
|
@ -575,10 +575,16 @@
|
|||
;; Extra functionality that is useful for lazy list stuff
|
||||
|
||||
(define* (take n l)
|
||||
(let ([n (! n)] [l (! l)])
|
||||
(let ([n0 (! n)] [l (! l)])
|
||||
(if (exact-nonnegative-integer? n)
|
||||
(let loop ([n n] [l l])
|
||||
(cond [(or (<= n 0) (null? l)) '()]
|
||||
(let loop ([n n0] [l l])
|
||||
(cond [(null? l)
|
||||
(if (n . > . 0)
|
||||
;; it would be fine to force the whole list (since we now
|
||||
;; know it's finite), but doing so means keeping a reference
|
||||
;; to its head, which can lead to memory leaks.
|
||||
(error 'take "index ~e too large for input list" n0)
|
||||
'())]
|
||||
[(pair? l) (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))))
|
||||
|
|
Loading…
Reference in New Issue
Block a user