I've been feeling pretty good about my macro-fu recently so I gave it a shot (I havent looked at anyone's solutions yet). This seems to pass all the test cases but I dont think it passes the "linear" requirement yet.<br>
<br><span style="font-family: courier new,monospace;">(define-syntax (cas-cad-e stx)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (syntax-case stx ()</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> [(_ e ((v) exp ...))</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (with-syntax ([break (datum->syntax stx 'break)])</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> #'(call/cc</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (ë (break)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (if (equal? e v)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (begin exp ...)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (void)))))]</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> [(_ e ((v1) exp1 ...) ((v2) exp2 ...) ...)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (with-syntax ([break (datum->syntax stx 'break)])</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> #'(call/cc</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (ë (break)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (if (equal? e v1)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (begin exp1 ... exp2 ... ...)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (cas-cad-e e ((v2) exp2 ...) ...)))))]))</span><br>
<br><br><br><br><br>On Fri, Oct 8, 2010 at 9:04 PM, Shriram Krishnamurthi <<a href="mailto:sk@cs.brown.edu">sk@cs.brown.edu</a>> wrote:<br>> One of my students recently sent me this needless email message:<br>><br>
>> Well, how would you do switch fall-through in Scheme? Could you<br>>> write a version of the case statement that does that?<br>><br>> Since the honor of Racket was at stake (yes, we can have all the same<br>
> stupid features the scripting languages have!), I wrote down the code<br>> for this, and realized it would make a cute little macro exercise.<br>><br>> Spec: define a case construct syntactically just like that of Racket.<br>
> In terms of semantics:<br>><br>> - each branch automatically falls through to the next,<br>><br>> - the last one returns its answer since it has no next clause, and<br>><br>> - any branch can contain (break <expr>), which evaluates <expr> and<br>
> returns its value as that of the entire case.<br>><br>> In honor of its behavor, we'll call this cas-cad-e. Thus,<br>><br>> (define (cas1 v)<br>> (cas-cad-e v<br>> ((1) (display "1"))<br>
> ((2) (display "2") (break 2)<br>> ((3) 3))))<br>><br>> (cas1 1) ==> 2 (and prints "12")<br>> (cas1 2) ==> 2 (and prints "2")<br>> (cas1 3) ==> 3 (and prints nothing)<br>
> (cas1 4) ==> <void> (and prints nothing)<br>><br>> If anyone wants to look at my solution, here it is:<br>><br>> <a href="http://github.com/shriram/cas-cad-e">http://github.com/shriram/cas-cad-e</a><br>
><br>> Of course, those who know how to do this don't need to peek, and those<br>> who don't shouldn't.<br>><br>> Shriram<br>> _________________________________________________<br>> For list-related administrative tasks:<br>
> <a href="http://lists.racket-lang.org/listinfo/users">http://lists.racket-lang.org/listinfo/users</a><br>><br><br>