<div>[ for those that just want to see what I'm getting at, scroll to the end ]</div><div><br></div>While the docs are clear (enough) on this point, I think it can be quite confusing. See if you spot the bug in this program:<div>
<br></div><div><div>#lang racket</div><div>(define (find-literals e)</div><div> (define literals '())</div><div> (let loop ([e e])</div><div> (match e</div><div> [`(λ (,x) ,e)</div><div> (loop e)]</div>
<div> [`(,e1 ,e2)</div><div> (loop e1)</div><div> (loop e2)]</div><div> [(? symbol?) (void)]</div><div> [else</div><div> (cond</div><div> [(member e literals)</div><div> (void)]</div>
<div> [else </div><div> (set! literals (cons e literals))])]))</div><div> literals)</div><div><br></div><div>(module+ test </div><div> (require rackunit)</div><div> (check-equal? (find-literals '(λ (x) x)) '())</div>
<div> (check-equal? (find-literals '((λ (x) x) 1)) '(1))</div><div> (check-equal? (find-literals '((λ (x) x) #f)) '(#f)))</div></div><div><br></div><div><br></div><div>Hint: the last test case fails. Second hint: if you switch it to use sets, it starts working. Third hint: this isn't about lists. :)</div>
<div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div>
<div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div>
<div><br></div><div><br></div><div><br></div><div>The bug is that 'else' is treated as a variable in match, so it gets bound to #f, which shadows the else in the cond which .... is confusing.</div><div><br></div><div>
So, how about making match treat else specially?</div><div><br></div><div><br></div><div>I don't ask this completely from outer space; there was a bug in Redex's random generation that was caused exactly by this shadowing of else.</div>
<div><br></div><div>Robby</div><div><br></div><div><br></div><div><br></div>