[racket] member et al.

From: Mark Engelberg (mark.engelberg at gmail.com)
Date: Thu Nov 11 00:21:43 EST 2010

On Wed, Nov 10, 2010 at 6:41 PM, Sam Tobin-Hochstadt <samth at ccs.neu.edu> wrote:
> No.  There's no reason that contracts or types need to have any
> trouble with Racket's generalized booleans.  In particular, the Typed
> Racket type system is designed to cope with exactly these sorts of
> idioms.

Consider the following function:
(define (one-two-or-three? n)
  (member n '(1 2 3)))

I'd like the type of this function to be something like Any -> Boolean.

But it's not.  It's contaminated by the type of member into something
I don't really want it to be, namely, Any -> (U False (Listof Any)).

The point is that because Racket doesn't provide true predicates for
some of the built-ins, it becomes more difficult for me to compose
them into true Boolean predicates.  And then, what if I want to write
higher-order predicates, e.g.,

(: this-or-that? ((Any -> Boolean) Any Any -> Boolean))
(define (this-or-that? predicate x y)
  (or (predicate x) (predicate y)))

(this-or-that? one-two-or-three? 1 5)

I could loosen the types of these Booleans to be Any, but then I'm not
really reflecting the "predicate intent" of these functions.
Alternatively, I have to write all my predicates like:
(define (one-two-or-three? n)
  (if (member n '(1 2 3)) true false))
which means I need to be highly aware of all the non-predicate things
I call and explicitly convert them.

So I don't really see how Racket's type system helps with the notion
of Any as Boolean.  It seems like there's no way to pass a non-Boolean
to something that's expecting a Boolean, so the only thing that's
really "coping" here is the user, who is forced to loosen all the
types or explicitly convert to a Boolean.  What am I missing?



Posted on the users mailing list.