title: Is there an existing lisp macro for building up a list?
body: <p>In Python, I am able to use <code>yield</code> to build up a list without having to define a temporary variable:</p>
  
  <pre><code>def get_chars_skipping_bar(word):
      while word:
  
          # Imperative logic which can't be
          # replaced with a for loop.
          if word[:3] == 'bar':
             word = word[3:]
          else:
              yield foo[0]
              foo = foo[1:]
  </code></pre>
  
  <p>In elisp, I can't see any way of doing this, either built-in or using any pre-existing libraries. I'm forced to manually build a up a list and call <code>nreverse</code> on it. Since this is a common pattern, I've written my own macro:</p>
  
  <pre><code>(require 'dash)
  (require 'cl)
  
  (defun replace-calls (form x func)
    "Replace all calls to X (a symbol) in FORM,
  calling FUNC to generate the replacement."
    (--map
     (cond
      ((consp it)
       (if (eq (car it) x)
           (funcall func it)
         (replace-calls it x func)))
      (:else it))
     form))
  
  (defmacro with-results (&amp;rest body)
    "Execute BODY, which may contain forms (yield foo).
  Return a list built up from all the values passed to yield."
    (let ((results (gensym "results")))
      `(let ((,results (list)))
         ,@(replace-calls body 'yield
                          (lambda (form) `(push ,(second form) ,results)))
         (nreverse ,results))))
  </code></pre>
  
  <p>Example usage:</p>
  
  <pre><code>(setq foo "barbazbarbarbiz")
  
  (with-results
   (while (not (s-equals? "" foo))
     ;; Imperative logic which can't be replaced with cl-loop's across.
     (if (s-starts-with? "bar" foo)
         (setq foo (substring foo 3))
       (progn
         (yield (substring foo 0 1))
         (setq foo (substring foo 1))))))
  </code></pre>
  
  <p>There must be a better way of doing this, or an existing solution, somewhere in elisp, cl.el, or a library.</p>