dash.el
dash.el copied to clipboard
-<< / swiss-arrows?
(defmacro -<< (expr &rest forms)
(let* ((result (gensym))
(funcalls (cl-loop for form in forms
collect `(funcall #',(car form) ,@(cdr form) ,result))))
`(when-let ((,result ,expr))
(list ,@funcalls))))
e.g.:
(-<< 3
(+ 1)
(format "Number: %s")
(* 10)) ; => (4 "Number: 3" 30)
;; or
(-<< (listify-key-sequence (kbd "C-c m"))
(event-modifiers)
(event-basic-type)) ; => ((control) 99)
We already have this except for functions:
(funcall (-juxt '1+ (lambda (x) (format "Number %s" x)) (lambda (x) (* 10 x))) 3)
is the first example's equivalent. I suppose we could add an anaphoric version /shrug.
Where is your notation coming from?
I stumbled upon this recently:
https://github.com/rplevy/swiss-arrows
Then I had occasion to use a macro like this, so I thought I'd send it in and see what you thought.
-tee might also be an appropriate name, since it's like the tee command. Then --tee could be an anaphoric version.
Here are some implementations that I've found useful:
(defmacro -< (expr &rest forms)
"Return a list of EXPR fed through FORMS, inserting it as the last item in each form.
EXPR is only evaluated once."
(declare (indent defun))
(let ((var (gensym)))
`(let ((,var ,expr))
(list ,@(--map (pcase it
((pred symbolp) (list it var))
((pred listp) (-snoc it var)))
forms)))))
(defmacro -<< (expr &rest forms)
"Return a list of EXPR fed through FORMS, inserting it as the first item in each form.
EXPR is only evaluated once."
(declare (indent defun))
(let ((var (gensym)))
`(let ((,var ,expr))
(list ,@(--map (pcase it
((pred symbolp) (list it var))
(`(,first . ,rest) `(,first ,var ,@rest)))
forms)))))
(defmacro --< (expr &rest forms)
"Return a list of EXPR fed through FORMS.
EXPR is bound to `it' in each form and is only evaluated once."
(declare (indent defun))
`(let ((it ,expr))
(list ,@(cl-loop for form in forms
collect (pcase form
((pred symbolp) (list form 'it))
(otherwise form))))))
For example, testing https://github.com/alphapapa/ts.el:
(-< (ts-now)
ts-Y ts-m ts-d ts-H ts-M ts-S
(list :now))
;;=> (2018 12 9 3 44 14 (:now #s(ts 3 44 14 9 12 2018 nil nil nil nil nil nil nil nil nil nil nil 1544348654.562836)))
(-<< (ts-now)
ts-Y ts-m ts-d ts-H ts-M ts-S (list 0 1))
;;=> (2018 12 9 3 40 49 (#s(ts 3 40 49 9 12 2018 nil nil nil nil nil nil nil nil nil nil nil 1544348449.705473) 0 1))
(--< (ts-now)
ts-Y ts-m ts-d ts-H ts-M ts-S
(list :now it))
;;=> (2018 12 9 3 43 3 (:now #s(ts 3 43 3 9 12 2018 nil nil nil nil nil nil nil nil nil nil nil 1544348583.1479712)))