On Thu, Nov 11, 2010 at 9:56 AM, Jay McCarthy <jay.mccar...@gmail.com> wrote: > (define (andmap f l) > (if (empty? l) > #t > (and (f (first l)) (andmap f (rest l))))) > > If and has to return a boolean, then it leaves space on the stack to > check if andmap returns a bool or to convert "truth" to #t. Thus this > program goes from constant stack space to linear stack space.
I don't understand this point. (define (andmap f l) (cond [(empty? l) #t] [(f (first l)) (andmap f (rest l))] [else #f])) definitely returns a Boolean, while working with both "true predicates" and "pseudo predicates", and works in constant stack space. If you really wanted and/or to definitely return booleans, there's no reason they couldn't be implemented similarly, like this for a two arg version: (define-syntax-rule (and x y) (cond [x (if y #t #f)] [else #f])) or more like andmap for the multiarg version. Basically, you end up doing one more test (against the final arg) than you would in the existing scheme. With such an implementation of and, you could implement andmap directly using and, while getting a guaranteed Boolean. So I don't see why there's any connection between making things return Booleans and tail-call behavior. Regardless of this point, I think that at least a case has been made that there would be value to having member? alongside member, because sometimes (especially in Typed Racket) it is useful to express predicate intent. _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/users