I've been studying the BST code in Paul Graham's ANSI Common Lisp.
He provides (my comments):
(defun bst-min (bst) (and bst ;  (or (bst-min (node-l bst)) bst))) ;  (defun bst-max (bst) (and bst ;  (or (bst-max (node-r bst)) bst))) ;  ;;  How do you find min and max of a bst? ;; Recall, the core point is that all items in left subtree are lower, ;; and all items in right subtree are higher, & this holds for the whole ;; tree, -otherwise binary search would miss-, and not just within a ;; single parent child relationship. ;;  Therefore, to find min, we just need to go left until we can go left ;; no more, & that's the min. If the above property didn't hold, you ;; might go left, then right, then left, and that final one there ;; could be as low as you like; but no, it must be greater than its ;; ancestor of which it is a right child. ;;  A null node has no min. The base case. Returns nil if bst is empty. ;;  For a non null node, the min is either the min of its left node, or ;; if that's null, then it's this node, instead. ;;  A null node has no max. The base case. Returns nil if bst is empty. ;;  For a non null node, the max is either the max of its right node, or ;; if that's null, then it's this node, instead.
I find this code more or less fine, but I still find it not easy to read or cognitively process.
I'm wondering whether that subjective fact is a feature of the code itself (i.e., is the code really hard to read), or whether it's something I need to stick with and then it will become very natural; remembering Hickey's advice about lisp that it is simple but not easy.
So, I produced this version by translating from a java implementation. It's easier for me to read (currently).
(defun bst-min (bst) (if (null (node-l bst)) bst (bst-min (node-l bst)))) (defun bst-max (bst) (if (null (node-r bst)) bst (bst-max (node-r bst))))
Is the first version somehow a relic of former days? Would anyone program like that now?
Question I would like to ask helpful peeps here is: which version would you favour and why?