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?

Reply via email to