dash.el icon indicating copy to clipboard operation
dash.el copied to clipboard

-<< / swiss-arrows?

Open alphapapa opened this issue 8 years ago • 4 comments

(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)

alphapapa avatar Aug 10 '17 02:08 alphapapa

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?

Fuco1 avatar Aug 10 '17 08:08 Fuco1

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.

alphapapa avatar Aug 10 '17 12:08 alphapapa

-tee might also be an appropriate name, since it's like the tee command. Then --tee could be an anaphoric version.

alphapapa avatar Aug 12 '17 05:08 alphapapa

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)))  

alphapapa avatar Dec 09 '18 09:12 alphapapa