[plt-scheme] idiomatic way to split a list into first, middle, last?

From: John Clements (clements at brinckerhoff.org)
Date: Thu Jan 5 19:20:27 EST 2006

Here's what I want:

(match l
   [`(,first ,middle ... ,last)
     `(,(first-proc first) ,@(map middle-proc middle) ,(last-proc  

... but I can't have that, apparently.  Here are two ugly solutions.   
Is there a better one?

a) prioritize readability:

(let* ([first (car l)]
        [middle (reverse (cdr (reverse (cdr l))))]
        [last (car (reverse l))])
   `(,(first-proc first) ,@(map middle-proc middle) ,(last-proc last)))

... This one seems grotesquely inefficient, even though
   1) it's not asymptotically any slower, and
   2) you can get rid of one of the three calls to 'reverse'.

b) write it the naturally recursive way:

(cons (first-proc (car l))
       (let loop ([remaining (cdr l)])
         (if (null? (cdr l))
             (list (last-proc (car remaining)))
             (cons (middle-proc (car remaining))
                   (loop (cdr remaining))))))

I can _write_ this in my sleep, but it's darn hard to _read_.

... or maybe I should go read Olin's paper?



-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 2430 bytes
Desc: not available
URL: <http://lists.racket-lang.org/users/archive/attachments/20060105/37f425a6/attachment.p7s>

Posted on the users mailing list.