First, usually you don't want to print out the return value of a function, since the REPL will print it anyway, which is why you get the output echoed.
Your end condition is wrong since it says "execute the loop while one is greater than y", which is never true for your examples, so the value is never touched and returned as it was. Even if you fix that, it will not be exponentiation, since you are multiplying the modified value of x by itself, not by original.
Avoid using SETF.
LOOP already has a large number of iteration constructs, which allow expressing state mutation in a structured way (I prefer
iterate, code walking issues notwithstanding). Often it is possible to avoid a DO clause altogether.
Code: Select all
(defun xp (x y)
(loop repeat y
for xprime = x then (* xprime x)
finally (return xprime)))