I want to implement a base condition in a recursive function written in Lisp, but I'm not able to do this since there is no return statement in Lisp.
My Lisp code is based on this C code
if (n==0) return;
How do I implement this in Lisp?
A return statement ends the execution of a function, and returns control to the calling function. Execution resumes in the calling function at the point immediately following the call. A return statement can return a value to the calling function. For more information, see Return type.
funcall applies function to args. If function is a symbol, it is coerced to a function as if by finding its functional value in the global environment.
You can use string= to compare symbol names as well as strings.
Common Lisp has the 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))))))
For a Algol programmer (or one of it's many dialects like C, Java, perl, ...) every expression in an LISP works like a "return expression". Example:
{
int x = 10;
if( x == 10 )
return 10 * 5;
else
return 5 * 19;
}
In LISP this can be written like these:
;; 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 might notice LISP if
is more like the ternary operator ( expression ? consequent : alternative )
than a C if
.
EDIT
Now that you have added an example usng return
in C which you want to translate I see that you are not using return
to return a value but as a goto
to exit the function early. Since goto is still considered harmful just using CL return-from
isn't always the right answer even if that would certainly be the best literal translation.
In any LISP you need to provide a value to return even though you are not going to use it (for functions called for their side effects). If you are not going to use the value you can just use nil
:
(if (zerop x)
nil
(something-else x))
If you need more than one statement (for side-effects) you use let
, progn
or switch the whole thing to a 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*))))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With