[racket] member et al.
25 minutes ago, Neil Toronto wrote:
> Eli Barzilay wrote:
> > Four minutes ago, Neil Toronto wrote:
> >> I think we should retire this truthiness business, replace cond's
> >> `=>' with something that lets you easily nest conds (I have a
> >> proposal ready for this, and it is awesome),
> >
> > (a) how is this related? (b) `=>' is not used to nest `cond's.
>
> You use it to have the same computed value available in both the
> test-expr and the then-body, which would otherwise require nested
> `cond's.
(Only if you want to use it multiple times, which is not too
frequent, far less than cases where `=>' are useful for.)
> I got inspired by the #:when form in `for' loops that flattens
> nesting, and wrote a `cond*' macro that allows this instead:
>
> (cond* [... some stuff ...]
> #:with (define m ...)
> [(... something about m ...) (... something using m ...)]
> ... more things referring to m ...)
>
> It's more general, since it doesn't require encoding the condition
> you want to test as a truthiness value. Also, the `define' doesn't
> have to be a `define' - it can be any legal expression.
So, you advocate eliminating `member' etc for predicates (why I
started with saying that this is much stickier than just adding a
`member?'). So we started with
(cdr (assq x alist))
then Scheme upgraded this to
(cond [(assq x alist) => cdr]
[else #f])
and you suggest continuing with
(cond #:with (define p (assq x alist))
[(pair? p) (cdr p)]
[else #f])
or, with more well-behaved proper sub lists
(cond #:with (define p (assq x alist))
[(not (eq? p #f)) (cadr p)]
[else #f])
(Yes, you can still use `pair?' but that would be ugly for the same
reason.)
I also wonder how many newbies (or people that just want to type less)
will fall into traps like
(if (member? x l)
(+ 1 (find x l))
0)
My loud "ugh" should be expected now.
> It's flattened most of my numeric code. Numeric code often computes and
> reacts to easily computable, approximate conditions first. When the easy
> tests are inconclusive, it computes and reacts to progressively more
> precise conditions that are more expensive.
(Sounds like srfi-2.)
> I've never heard this, and I am curious. How does truthiness in `and'
> and `or' preserve proper tail calls?
Two minutes ago, Jay McCarthy 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.
Yeah -- and this is an obvious case. There are more subtle cases
where it's important to preserve tail position. (I think that Joe had
a post once on how nice it is when things work wrt tail calls without
forcing you to think about it or write more code.)
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!