I found myself needing this control loop and was very surprised not to find it in the standard library. Does it exist by some other name?
(defmacro until (form &optional guard)
"Runs `while' on FORM until it is non-nil, returning the value.
A guard is provided which may cause the loop to exit early with nil."
(let ((res (gensym "res")))
`(let (,res)
(while (and (not ,guard)
(not (setq ,res ,form))))
,res)))