Shriram Krishnamurthi <xxxxxx@cs.rice.edu> writes:
> Harvey J. Stein wrote:
>
> > This has the obvious implementation:
> >
> > (define (list-length>=? l n)
> > (if (<= n 0)
> > 0
> > (list-length>=? (cdr l) (- n 1))))
>
> 1. The "obvious implementation" doesn't at all seem to correspond with
> the functionality you want. But that's easy enough to fix.
Oops. Sorry. I meant:
(define (list-length>=? l n)
(cond ((<= n 0) #t)
((null? l) #f)
(else (list-length>=? (cdr l) (- n 1)))))
> 2. This seems like exactly the sort of thing exceptions are designed
> to get around. You should be able to write
>
> (let ((name (list-ref argument-list 3)))
> ...)
>
> expecting that there are four values in `argument-list'; if there
> aren't, you can handle the ensuing exception as you deem appropriate
> (eg, locally if you want to provide a default value, or globally if
> you want to signal an error and exit). That's probably what you
> _mean_ to say, anyway.
Yes, exception handling would be an appropriate way to handle such a
thing, if you had exception handling.
> 3. This procedure is anyway "inefficient" in that its client will
> almost certainly traverse the same n elements again. (Dan Friedman
> would say that it "leaks computation".) So it would be better off
> taking a one-argument procedure that takes the remainder of the list
> and uses it appropriately. Better still, then, take two arguments,
> the second being the failure continuation (which would be invoked in
> tail position wrt the original calling context). Or, you could
> generalize this to
>
> list-split: int x list x (list -> beta) x (list -> gamma) x
> (() -> delta) -> (beta + gamma)
>
> This is similar to, but not identical to, `partition'. To be closer
> to the spirit of partition, we could define
>
> list-split: int x list -> [list list]
>
> (for which I don't see an equivalent in the proposal).
I've done this before, but I don't see how a) it prevents getting an
exception when out of range (since you're explicitely calling error
when such occurs), and b) how it prevents walking to element N a 2nd
time.
Maybe better than list-length>= would be (list-ref-with-default l n
default-value), which returns default-vaule if (>= (length l) n). At
least I can see how to use this to get the behavior I wanted without
scanning the list twice. I considered a non exception throwing
list-ref, one which returns something else to indicate not-found, but
there's nothing that can be returned that can't be in the list. At
least if a default value is supplied the programmer can supply
something that's appropriate for the context.
Another possibility is a list-ref which uses values to indicate that
the end of the list was reached.
--
Harvey J. Stein
BFM Financial Research
xxxxxx@bfr.co.il