(defmacro funcallq-or-lambda (f-or-lambda &rest args)
  (if (and (listp f-or-lambda))
      `(funcall ,f-or-lambda ,@args)
      `(funcall ',f-or-lambda ,@args)))

(defmacro -> (val f &rest fs)
  (if (null fs)
      (if (listp f)
          (if (not (eq (car f) 'lambda))
              `(funcallq-or-lambda ,(car f) ,val ,@(cdr f))
              `(funcall ,f ,val))
          `(funcall ',f ,val))
      `(-> (-> ,val ,f) ,@fs)))

(defmacro as-> (val sym f &rest fs)
  (if (null fs)
      (if (listp f)
          (if (not (eq (car f) 'lambda))
              `(funcall ',(car f) ,@(substitute val sym (cdr f)))
              `(funcall ,f ,val))
          `(funcall ',f ,val))
      `(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)))))
; your code goes here
(print
    (<_ (lambda (x) (* 2 x)) (- 3 _) sin pi))