[racket] a little macro exercise

From: Neil Van Dyke (neil at neilvandyke.org)
Date: Sat Oct 9 20:57:42 EDT 2010

David Herman wrote at 10/09/2010 07:46 PM:
> I thought about the "am I falling through?" approach you've been taking, but the problem is that it keeps having to recompute the same test. In C-like languages, one of the benefits of `switch' [1] is that fall-through is expected to either be a literal "execute the next instruction in the PC" or at least a jump to a fixed address. So I prefer an approach that sets up a basic-block-like structure, like so:

I like this way of thinking.

Here's an expansion of Shriram's example:

  (define (cas1 v)
    (let ([disc-v v])
         ([break (syntax-rules () [(_ v) (k v)])])
         (define (temp2) (case disc-v [(1) (temp4)] [else (temp3)]))
         (define (temp3) (case disc-v [(2) (temp5)] [else (temp6)]))
         (define (temp4) (display "1") (temp5))
         (define (temp5) (display "2") (break 2) (temp7))
         (define (temp6) (case disc-v [(3) (temp7)]))
         (define (temp7) 3)

That seems a little unfamiliar to me because of the linear search with 
multiple tests.  I instead used a single "case", on the perhaps naive 
assumption that that's easiest for a compiler to optimize:

  (define (cas1 v)
    (let ((temp3 (lambda () 3)))
      (let ((temp2 (lambda () (display "2") 2)))
        (let ((temp1 (lambda () (display "1") (temp2))))
          (case v
            ((1) (temp1))
            ((2) (temp2))
            ((3) (temp3)))))))

Couldn't a compiler could optimize a "case" at least as well as any 
syntax transformer I wrote, unless I had special knowledge about the 
actual runtime inputs that a static optimizer doesn't have (which I 
don't)?  (Examples: binary search, jump tables, branching on tags/types, 
dynamic optimizations.)

I was guessing then that, if I let the compiler do what it wants with a 
single "case" and then went with tail calls to chain fallthrough between 
thunks, it doesn't get much better than that for a compiler.

But I'm just making that up, since I don't know how smart the compiler, 
and modern CPUs and JITs mean that we can't just count instructions in 
disassembly dumps to have an easy idea what'll go on.


Posted on the users mailing list.