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?

  • Please indent your code properly. Thx. – Drew Dec 15 '15 at 6:25
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)))
  • 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
  • 2
    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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.