guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

/list-head/ and /take/


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?

reply via email to

[Prev in Thread] Current Thread [Next in Thread]