0

I found this code on stackoverflow (from Rainer Joswig):

 (defun listFormat ()
   (cl-labels ((place-index (idx l)
        (if (null l)
            nil
            (append (list (first l)) (list idx)
                  (place-index (+ idx 1) (rest l))))))
    (place-index 1 l))))

and I changed it by adding a let form and cl-labels:

(defun listFormat ()
   (let ((l '(a b c d)))
   (cl-labels ((place-index (idx l)
                         (if (null l)
                             nil
                           (append (list (first l)) (list idx)
                                   (place-index (+ idx 1) (rest l))))))
     (place-index 1 l))))

Is this a good practice? In the code I'm working on I need to establish variables with let, then do a recursive function, i.e., I don't want the stuff inside the let to be repeated on each recursion. I'm wondering if there is a way to combine this under cl-letf. I try this, but it's not liking it:

(defun listFormat ()
   (cl-letf ((l '(a b c d))
             (place-index (idx l)
                          (if (null l)
                              nil
                            (append (list (first l)) (list idx)
                                    (place-index (+ idx 1) (rest l))))))
     (place-index 1 l)))

complaining of void function idx. So, is there a way to combine let content that shouldn't be resursed with an inner recursion function?

Drew
  • 75,699
  • 9
  • 109
  • 225
147pm
  • 2,907
  • 1
  • 18
  • 39

1 Answers1

3

Recursion as general looping construct is discouraged in Emacs Lisp. Don't. This is not Scheme. Why don't you use one of the following instead?

dash.el:

(defun list-format (list)
  (-flatten (--map-indexed (list it (1+ it-index)) list)))

cl-lib:

(defun list-format (list)
  (cl-mapcan 'list list (number-sequence 1 (length list))))

LOOP:

(defun list-format (list)
  (cl-loop for item in list
           for i from 1
           append (list item i)))

Vanilla:

(defun list-format (list)
  (let ((i 1)
        (list list)
        result)
    (while list
      (push (pop list) result)
      (push i result)
      (setq i (1+ i)))
    (nreverse result)))
wasamasa
  • 21,803
  • 1
  • 65
  • 97
  • I noticed that shadowing of the list variable in the last example is not necessary. Do you know why? If one uses setcdr etc. it will mutate the list passed to the function as well but the pop function does not. Maybe I should post it as a question. – clemera Dec 14 '15 at 18:59
  • I don't know, but I agree, a new question on this would be useful. – wasamasa Dec 14 '15 at 20:24
  • 3
    A lisp without recursion seems a bit tragic. – PythonNut Dec 14 '15 at 22:25
  • 1
    It's not it not having recursion, it's about not using recursion to implement something `dolist` or `mapcar` handle just fine. – wasamasa Dec 15 '15 at 23:04