[ for those that just want to see what I'm getting at, scroll to the end ]

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:

#lang racket
(define (find-literals e)
  (define literals '())
  (let loop ([e e])
    (match e
      [`(λ (,x) ,e)
       (loop e)]
      [`(,e1 ,e2)
       (loop e1)
       (loop e2)]
      [(? symbol?) (void)]
      [else
       (cond
         [(member e literals)
          (void)]
         [else
          (set! literals (cons e literals))])]))
  literals)

(module+ test
  (require rackunit)
  (check-equal? (find-literals '(λ (x) x)) '())
  (check-equal? (find-literals '((λ (x) x) 1)) '(1))
  (check-equal? (find-literals '((λ (x) x) #f)) '(#f)))


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. :)

































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.

So, how about making match treat else specially?


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.

Robby
_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev

Reply via email to