Idiomdrottning’s homepage

Assorted Embarrassment

Here is a pretty bad bug that I left in production for way too long:

(sort new-alist
       (lambda (x y)
         (or (< (second x) (second y))
             (< (first x) (first y)))))

Here is what I meant to write:

 (sort new-alist
       (lambda (x y)
         (or (< (second x) (second y))
             (and (= (second x) (second y))
                  (< (first x) (first y))))))

(I guess those queries can be replaced by temps if you were so inclined. And, “new-alist” is the wrong name for a list of undotted three-element lists; after sorting, it goes through a map (o reverse cdr) but still not dotted. Såattäh…)

Sort by the second field. If they are equal, which they will be often enough, then use the first field as a tie-breaker.

In practice, the second field was equal so often (and/or the input order was already right so often) that the bug went on unnoticed and didn’t do any harm before it was discovered.

Still wrong, though, and illustrative of what a wrong mental model of comparators can look like: thinking of the function as a question of basically proving why X should go first, forgetting that sometimes Y actually has the precedence based on the second field. X is like “Did I win by second field? No? How about by first field?” Hold your jig there, X, sometimes Y wins by second field.