On Thu, Nov 11, 2010 at 11:56 AM, Mark Engelberg <mark.engelb...@gmail.com> wrote: > 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)]
This 'if' introduces a stack frame that is not otherwise needed. Jay > [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. > -- Jay McCarthy <j...@cs.byu.edu> Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/users