The current behavior of list-head is:
*guile> (list-head '(1 2 3 A B C) 10)*
Backtrace:
In standard input:
1: 0* [list-head (1 2 3 A B C) 10]
standard input:1:1: In procedure list-head in expression (list-head
(quote #) 10):
standard input:1:1: Wrong type argument in position 1 (expecting pair): ()
ABORT: (wrong-type-arg)
guile>
The procedure /take/ from SRFI#1 is currently identical to /list-head/.
I would like to see the following change:
1) /list-head/ should treat it's numerical parameter as a maximum but
it should always return at least the head of the list
2) /take/ produces the same result as the current list-head but it
should check it's parameters and produce better error message
Here are two reference implementations and a transcript of an example
session. Beware that they are recursive.
(define (list-head list n)
(if (or (null? list) (<= n 0))
'()
(cons (car list) (list-head (cdr list) (- n 1)))))
(define (take list n)
(if (< n 0)
(error "take: the parameter n has to be an exact natural number
or zero"))
(cond ((and (not (null? list)) (= n 0)) '())
((and (null? list) (not (= n 0)))
(error "take: argument out of range: n was greater than the
length of the list."))
((and (not (null? list)) (> n 0))
(cons (car list)
(take (cdr list) (- n 1)) ))
(else
(error "take: Oh dear, we failed!"))) )
Example Session:
*guile> (define l '(1 2 3 A B C))**
**guile> (take l 10)*
Backtrace:
In standard input:
13: 1 (cond (# #) (# #) (# #) ...)
17: 2 [cons 1 ...
18: 3* [take (2 3 A B C) 9]
13: 4 (cond (# #) (# #) (# #) ...)
17: 5 [cons 2 ...
18: 6* [take (3 A B C) 8]
13: 7 (cond (# #) (# #) (# #) ...)
17: 8 [cons 3 ...
18: 9* [take (A B C) 7]
13: 10 (cond (# #) (# #) (# #) ...)
17: 11 [cons A ...
18: 12* [take (B C) 6]
13: 13 (cond (# #) (# #) (# #) ...)
17: 14 [cons B ...
18: 15* [take (C) 5]
13: 16 (cond (# #) (# #) (# #) ...)
17: 17 [cons C ...
18: 18* [take () 4]
13: 19 (cond (# #) (# #) (# #) ...)
15: 20 [error "take: argument out of range n greater than the
length of the list."]
standard input:15:10: In procedure error in expression (error "take:
argument out of range: n was greater than the length of the list."):
standard input:15:10: take: argument out of range: n was greater than
the length of the list.
ABORT: (misc-error)
*guile> (list-head l 10)*
(1 2 3 A B C)
guile>
BTW Where is the stack-free /cons/ implementation? Is an arbitrary limit
on the stack still useful?