Wednesday, February 23, 2011

An easy puzzle

Suppose I have some code like this:
(defun foo (x)
  (wrapper-macro
    (bar 42 x)))
Where wrapper-macro simply prints ‘Normal exit’ or ‘Throw’ as control returns from bar through foo. (If bar returns normally, all the return values are returned from foo after wrapper-macro prints. If bar exits via a throw, then the throw continues after wrapper-macro prints.)

The challenge: Implement wrapper-macro.

(If you wish, imagine that wrapper-macro simply expands to this:
(defun foo (x)
  (wrapper-function
    (lambda ()
      (bar 42 x))))
and the challenge is to implement wrapper-function.)

4 comments:

  1. (defun wrapper-function (thunk)
    (let ((return? nil))
    (unwind-protect
    (multiple-value-prog1
    (funcall thunk)
    (setf return? t))
    (if return?
    (print "Return")
    (print "Non-local exit")))))

    Btw, if possible, please allow the use of PRE tags in comments in order to display code fragments properly

    ReplyDelete
  2. I wish I could turn on PRE tags.

    If you untabify and replace the spaces with  , you get this:

    (defun wrapper-function (thunk)
      (let ((return? nil))
        (unwind-protect
            (multiple-value-prog1
             (funcall thunk)
             (setf return? t))
          (if return?
              (print "Return")
            (print "Non-local exit")))))

    ReplyDelete
  3. I might be wrong, but can't you just do it with call/cc and modifying bar function to use continuations?

    ReplyDelete
  4. ohw0w said...

    Can't you just do it with call/cc and modifying bar function to use continuations?

    Yikes! I don't think you need to haul out the heavy machinery!

    ReplyDelete