How to implement redo statement (as in Perl and Ruby) in Lisp

common-lisp, control-structure, lisp, redo

Solution

In Common Lisp:

(tagbody
   start
   (do-something)
   (go start))


(dotimes (i some-list)
  redo
  (when (some-condition-p)
    (go redo))
  (some-more))

Problem

Code that requires `break` statements or `continue` statements in other languages can be done with `block` & `return-from` or `catch` & `throw` in Common Lisp and Emacs Lisp. Then there is code that requires `redo` statements, or at least best written with `redo`. And `redo` statements don't have to be about loops. How can I do `redo` in Lisp? If there was a `redo` equivalent in Lisp, I think it would work like this: special form `with-redo` which takes a symbol and forms, and `redo` which takes a symbol. The form `(with-redo 'foo BODY-FORMS...)` may contain `(redo 'foo)` in its BODY-FORMS, and `(redo 'foo)` transfers control back to the beginning of BODY-FORMS.

Original source