Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

collect-cond! a variant of -separate #331

Open
Luis-Henriquez-Perez opened this issue Feb 26, 2020 · 1 comment
Open

collect-cond! a variant of -separate #331

Luis-Henriquez-Perez opened this issue Feb 26, 2020 · 1 comment
Labels
enhancement Suggestion to improve or extend existing behavior

Comments

@Luis-Henriquez-Perez
Copy link

This is similar to separate-multi in #230 but has cleaner syntax.

(defmacro collect-cond! (list &rest clauses)
  (declare (indent 1))
  (let ((lists (--map (make-symbol (concat "list" (number-to-string it)))
                      (number-sequence 1 (length clauses)))))
    `(let (,@lists)
       (--each ,list
         (cond
          ,@(-map (-lambda ((list clause))
                    (when (or (not (listp (car-safe clause)))
                              (atom clause))
                      (setq clause (list clause 'it)))
                    `(,(car clause) (push ,(cadr clause) ,list)))
                  (-zip-with #'list lists clauses))))
       (list ,@(--map `(nreverse ,it) lists)))))

Usage:

(collect-cond! '(1 2 3 4 5 6)
  (= 1 it)
  (= 3 it)
  t)

;; result => ((1) (3) (2 4 5 6))

;; macroexpansion =>
(let
    (list1 list2 list3)
  (--each
      '(1 2 3 4 5 6)
    (cond
     ((= 1 it)
      (push it list1))
     ((= 3 it)
      (push it list2))
     (t
      (push it list3))))
  (list
   (nreverse list1)
   (nreverse list2)
   (nreverse list3)))

(collect-cond! '(1 2 3 4 5 6)
  (= 1 it)
  ((= 3 it) (* 3 (+ 1 it)))
  t)

;; => ((1) (12) (2 4 5 6))

;; macroexpansion =>
(let
    (list1 list2 list3)
  (--each
      '(1 2 3 4 5 6)
    (cond
     ((= 1 it)
      (push it list1))
     ((= 3 it)
      (push
       (* 3
          (+ 1 it))
       list2))
     (t
      (push it list3))))
  (list
   (nreverse list1)
   (nreverse list2)
   (nreverse list3)))
@basil-conto basil-conto added the enhancement Suggestion to improve or extend existing behavior label Jan 18, 2021
@alphapapa
Copy link

This is a pretty nice API. :)

In a similar vein, but for more more complicated use cases, I recently published this: https://github.com/alphapapa/taxy.el

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Suggestion to improve or extend existing behavior
Projects
None yet
Development

No branches or pull requests

3 participants