(defmacro with-gensyms (syms &body body)
  `(let ,(loop for s in syms collect `(,s (gensym)))
    ,@body))

(defmacro -> (val f &rest fs)
  (cond ((null fs)
         (cond
           ((listp f) `(funcall ',(car f) ,val ,@(cdr f)))
           (t `(funcall ',f ,val))))
        (t `(-> (-> ,val ,f) ,@fs))))

(defmacro as-> (val sym f &rest fs)
  (cond ((null fs)
         (cond ((listp f) `(funcall ',(car f) ,@(substitute val sym (cdr f))))
               (t `(funcall ',f ,val))))
        (t `(as-> (as-> ,val ,sym ,f) ,sym ,@fs))))

(defmacro <_ (&rest args)
  (with-gensyms (new-args)
    (let ((new-args (nreverse args)))
      `(as-> ,(car new-args) _ ,@(cdr new-args)))))

(print (<_ sin (* 2 _) asin 1))
(print (<_ (- _ 1) (/ _ 2) 4))