I used to write nested helper functions (which, btw, ocasionally used parameters of outer functions and are recursive) in Haskell like this (loop
):
sum a b = let
loop s i = if i > b then s else loop (s + i) (i + 1)
in loop 0 a
What is the clearest analog for this in Common Lisp?
I searched around here and found some discussions focused on returning functions from functions (and the problems which may arise when trying to call such “returned” functions) which is not quite the same situation, as far as I can see.
Labels is used to define local functions.
CL-USER> (defun thing (x)
(labels ((helper (y) (loop for i from x to y collect i)))
(helper 5)))
THING
CL-USER> (thing 1)
(1 2 3 4 5)
It is kind of like a let* statement for functions as you can define multiple local functions. So here we have helper and double-it being defined.
(defun thing (x)
(labels ((helper (y) (loop for i from x to y collect i))
(double-it (num) (* 2 num)))
(helper (double-it 10))))
Also you could use lambdas. Which in this instance is fairly tidy, though I still prefer labels for readability in this case.
CL-USER> (defun another-test (x)
(funcall #'(lambda (y) (loop for i from x to y collect i)) 10))
ANOTHER-TEST
CL-USER> (another-test 2)
(2 3 4 5 6 7 8 9 10)
Labels can also be used recursively:
CL-USER> (defun test-recurse (x)
(labels ((rec-list (count)
(when (< count x)
(cons count (rec-list (+ 1 count))))))
(rec-list 0)))
TEST-RECURSE
CL-USER> (TEST-RECURSE 10)
(0 1 2 3 4 5 6 7 8 9)
Hope it helps!