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