[racket] Cond function with test-expr = then-body works but is it wise?

14 views
Skip to first unread message

Don Green

unread,
May 24, 2013, 12:08:16 PM5/24/13
to us...@racket-lang.org

It is possible to create a cond test-expr that also serves as the then-body, however, this means that the expression would be executed twice.

This seems to be ill advised in principle.

Question: If it is ill-advised to create a cond test-expression that also serves as the then body, then what function is recommend?


I am aware of the (cdr (or ... form.

I am aware of the cond ... test-expr => proc-expr] form option.

Thanks

Don Green

Matthias Felleisen

unread,
May 24, 2013, 12:13:27 PM5/24/13
to Don Green, us...@racket-lang.org

Would 

 (cond 
    [testing => values]
    ...)

work for you? That returns the value of the testing expression w/o evaluating it twice. 




____________________
 Racket Users list:
 http://lists.racket-lang.org/users

Eli Barzilay

unread,
May 24, 2013, 12:19:24 PM5/24/13
to Don Green, us...@racket-lang.org
10 minutes ago, Don Green wrote:
> It is possible to create a cond test-expr that also serves as the then-body,
> however, this means that the expression would be executed twice.
>
> This seems to be ill advised in principle.

`cond' can have one-expression clauses that serve both purposes:

-> (cond [(printf "123\n")])
123

It's convenient to use in rare cases, but I usually try to avoid the
temptation since it feels wartish...


> Question: If it is ill-advised to create a cond test-expression that also
> serves as the then body, then what function is recommend?
>
> I am aware of the (cdr (or ... form.

(This looks like some assq use, which should benefit from the above.)

--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!

Laurent

unread,
May 24, 2013, 12:48:29 PM5/24/13
to users
Just for fun, if you have to use the value of the tests in several bodies, you may also define your own macro:

#lang racket

(define-syntax-rule (cond/let id [test body ...] ...)
  (cond [test => (λ(id) body ...)]
        ...))

(let ([x "123a" #;"123"])
  (cond/let y
            [(string->number x) (* y 10)]
            [(regexp-match #px"\\da" x) y]
            [#t y]))

Of course, it's just a proof of concept, it doesn't handle `else' and one-expression clauses, it doesn't verify that id is an identifier, but you should get the idea.

Laurent

Reply all
Reply to author
Forward
0 new messages