|
From: | Michael Tiedtke |
Subject: | /list-head/ and /take/ |
Date: | Sun, 21 Jun 2015 07:27:48 +0200 |
User-agent: | Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 |
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? |
[Prev in Thread] | Current Thread | [Next in Thread] |