[racket] Problem with case

30 views
Skip to first unread message

Kieron Hardy

unread,
Sep 17, 2012, 6:47:27 PM9/17/12
to users
Hi all,

Can anyone explain why the first function below selects 'x1-case as expected but the second fails to select 'x2-case? Am I expecting something to happen that shouldn't?

Thanks,

Kieron.

****

#lang racket

(case 'a
   ['a 'x1-case]
   ['b 'x1-case]
   [(15 2 3) 'y1-case]
   [(10 11 12) 'z1-case])

(case 'a
   [('a 'b) 'x2-case]
   [(15 2 3) 'y2-case]
   [(10 11 12) 'z2-case])

David Van Horn

unread,
Sep 17, 2012, 7:00:02 PM9/17/12
to Kieron Hardy, users
Be careful with quote in a case clause -- those clauses are already
implicitly quoted. The first is really:

(case 'a
[(quote a) 'x1-case]
[(quote b) 'x1-case]
[(15 2 3) 'y1-case]
[(10 11 12) 'z1-case])

So you'll notice the following surprising behavior:

(case 'quote
['a 'x1-case]
['b 'x1-case]
[(15 2 3) 'y1-case]
[(10 11 12) 'z1-case])

You want:

(case 'quote
[(a) 'x1-case]
[(b) 'x1-case]
[(15 2 3) 'y1-case]
[(10 11 12) 'z1-case])

and:

(case 'a
[(a b) 'x1-case]
[(15 2 3) 'y1-case]
[(10 11 12) 'z1-case])

David





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

Jon Zeppieri

unread,
Sep 17, 2012, 7:11:03 PM9/17/12
to Kieron Hardy, users
The fact that the first one works at all should probably be considered a bug. The syntax of case here:


dictates that the constants in a case clause be parenthesized.

The more important issue, however, is that the constants are implicitly quoted by the case form. So, when you explicitly quote them, they're double quoted. You're trying to match 'a against ''a.

-Jon


J. Ian Johnson

unread,
Sep 17, 2012, 7:14:39 PM9/17/12
to Jon Zeppieri, users
The reader turns the 'a into (quote a), so you'd actually also get the 'x1-case given 'quote.
I don't think this case is a bug so much as a "gotcha."
-Ian

David Van Horn

unread,
Sep 17, 2012, 7:15:44 PM9/17/12
to Jon Zeppieri, users
On 9/17/12 7:11 PM, Jon Zeppieri wrote:
> The fact that the first one works at all should probably be considered a
> bug. The syntax of case here:
>
> http://docs.racket-lang.org/reference/case.html?q=case#(form._((lib._racket/private/more-scheme..rkt)._case))
>
> dictates that the constants in a case clause be parenthesized.

But they *are* parenthesized... after the reader expands '.

That's why you can do weird things like ((lambda 'x ''''''x) add1 0).

David

Jon Zeppieri

unread,
Sep 17, 2012, 7:22:03 PM9/17/12
to David Van Horn, users
On Mon, Sep 17, 2012 at 7:15 PM, David Van Horn <dvan...@ccs.neu.edu> wrote:
On 9/17/12 7:11 PM, Jon Zeppieri wrote:
The fact that the first one works at all should probably be considered a
bug. The syntax of case here:

http://docs.racket-lang.org/reference/case.html?q=case#(form._((lib._racket/private/more-scheme..rkt)._case))

dictates that the constants in a case clause be parenthesized.

But they *are* parenthesized... after the reader expands '.

That's why you can do weird things like ((lambda 'x ''''''x) add1 0).

David


Oh my. Right. That's...  Wow. 
I hadn't considered the possibilities for obfuscating racket code.

Kieron Hardy

unread,
Sep 18, 2012, 10:07:16 AM9/18/12
to users
Thanks for the info guys, now I understand what's going on.

Cheers,

Kieron

Joe Gilray

unread,
Sep 18, 2012, 4:09:52 PM9/18/12
to Kieron Hardy, users
Thanks for the question, Kieron.  It got me to look up case and think a little about its usage.

I'd like to see a discussion of the tradeoffs between cond & case & match and how each is best used.

Thanks,
-joe

Danny Yoo

unread,
Sep 18, 2012, 5:29:08 PM9/18/12
to Joe Gilray, users
>
> I'd like to see a discussion of the tradeoffs between cond & case & match
> and how each is best used.


Hi Joe,

I treat 'cond' as the general, all-purpose conditional branching
thing, and it's my primary tool. I use the other two if the
conditions I'm testing against fit their shapes. If I'm pattern
matching against structures, then I use 'match', and if I'm matching
against single pieces of literal data, like characters or symbols,
then I pick up 'case'.


I think 'case' is supposed to have good performance compared to the
other two, due to work by Jon Zeppieri
(http://lists.racket-lang.org/dev/archive//2012-July/010036.html).

Jon Zeppieri

unread,
Sep 18, 2012, 9:29:04 PM9/18/12
to Joe Gilray, users
On Tue, Sep 18, 2012 at 5:29 PM, Danny Yoo <dy...@hashcollision.org> wrote:
>
> >
> > I'd like to see a discussion of the tradeoffs between cond & case & match
> > and how each is best used.

1. Use 'cond' where you would use 'if...else if...else' in a C-like
language. It's just a multi-way if:

(cond [(string? value)
(write-string value out)]
[(bytes? value)
(write-bytes value out)]
[(input-port? value)
(copy-port value out)]
[else
(error "bad value")])

2. Use 'case' (roughly) where you would use 'switch' in C, namely,
when you're comparing the value of an expression against a set of
constants:

(case escape-char
[(#\n) #\newline]
[(#\r) #\return]
[(#\t) #\tab]
[(#\a) #\u0007]
[(#\v) #\u000b]
[(#\f) #\u000c]
[(#\e) #\u001b]
[else escape-char])

3. Use 'match' (roughly) where you would use 'case' in ML. I agree
with Danny: it's particularly nice for struct matching:

(: add (All (A) ((Braun A) A -> (Braun A))))
(define (add t a)
(match t
[(Braun-Empty)
(Braun-Tree a t t)]
[(Braun-Tree x l r)
(Braun-Tree a (add r x) l)]))

>
>
> I think 'case' is supposed to have good performance compared to the
> other two, due to work by Jon Zeppieri
> (http://lists.racket-lang.org/dev/archive//2012-July/010036.html).
>

The new case implementation isn't in 5.3 or the stable branch on
github. (I assume the nightly builds on racket-lang.org are from the
stable branch?) It's in the master branch.

Eli Barzilay

unread,
Sep 18, 2012, 9:33:09 PM9/18/12
to Jon Zeppieri, users
A few minutes ago, Jon Zeppieri wrote:
> (I assume the nightly builds on racket-lang.org are from the
> stable branch?)

No -- the stable branch corresponds to the released versions, so it's
a convenient way to get to the "most recently released" point.

--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!
Reply all
Reply to author
Forward
0 new messages