Is there anything like a returnable C instruction in Lisp?
Common Lisp has a special form RETURN-FROM (and its relative RETURN ) to do what you want.
(defun accumulate-list (list)
(when (null list)
(return-from accumulate-list 0))
(+ (first list)
(accumulate-list (rest list))))
Having said that, I prefer to use COND when writing recursive functions.
(defun accumulate-list (list)
(cond
((null list)
0)
(t
(+ (first list)
(accumulate-list (rest list))))))
source to share
For the Algol programmer (or one of them many dialects such as C, Java, perl, ...) every expression in LISP works like a "return expression". Example:
{
int x = 10;
if( x == 10 )
return 10 * 5;
else
return 5 * 19;
}
In LISP it can be written like this:
;; direct version (let ((x 10)) (if (= x 10) (* 10 x) (* 5 x))) ;; if can be anywhere (let ((x 10)) (* x (if (= x 10) 10 5))))
As you can see, LISP if
is more similar to the ternary operator ( expression ? consequent : alternative )
than the C if
.
EDIT
Now that you've added the example usng return
in C that you want to translate, I see that you are not using return
to return a value, but how goto
to exit the function before. Since goto is still considered harmful , using CL is return-from
not always the right answer, even if it is by far the best literal.
In any LISP, you need to provide a return value even if you don't intend to use it (for functions that cause their side effects). If you are not going to use the value, you can simply use nil
:
(if (zerop x)
nil
(something-else x))
If you need multiple operators (for side effects), you use let
, progn
or switch everything to cond
:
;; using let to bind as well as implicit progn
(if (zerop x)
nil
(let ((tmp (gethash x *h*)))
(setf (gethash x *h*) (+ x 1))
(something-else tmp)))
;; using progn
(if (zerop x)
nil
(progn
(setf (gethash x *h*) (+ (gethash x *h*) 1))
(something-else (gethash x *h*))))
;; using cond
(cond ((zerop x) nil)
(t
(setf (gethash x *h*) (+ (gethash x *h*) 1))
(something-else (gethash x *h*))))
source to share
You just do it if
for the whole body and place nil
, not return
if you really want the return to return "nothing".
Thus, to compile all numbers from 0 to n:
(defun somefunc (n)
(if (zerop n)
0
(+ n (somefunc (- n 1)))))
So if n==0
, the recursive function returns 0. Otherwise, it does the append to append n
to f(n-1)
and returns that result. (Note that this is not a perfect algorithm, just an example of a recursive function).
Remember that Lisp will return the value of whatever expr was last executed as a value in the function. If n==0
, then the above returns 0. If n > 0
, it returns the result of +
expr.
If you need a multi-step test (for example to make sure you are not passed a negative number) cond
this is the way to go (as mentioned earlier). In any case, the value of the last function executed is the value of the function.
source to share