(eval-when (:load-toplevel :compile-toplevel :execute)
(defun simple-lambda-list-p (lambda-list)
  (notany (lambda (x)
            (member x '(&optional &rest &key)))
          lambda-list))

(defmacro spicy-lambda ((&rest args) &body body)
  (assert (simple-lambda-list-p args) (args))
  (reduce (lambda (arg form)
            `(lambda (,arg) ,form))
          args :from-end t :initial-value `(progn ,@body)))

(defmacro defspicy (name (&rest args) &body body)
  (if (<= (length args) 1)
      `(defun ,name ,args ,@body)
      `(defun ,name (,(first args))
         (spicy-lambda ,(rest args) ,@body))))
)


(defspicy compose (f g x)
  (funcall f (funcall g x)))

(defspicy const (x y) x)

(defspicy plus (x y) (+ x y))

;; yoba dx = (dx +) . length
(defspicy yoba (dx)
  (funcall (compose (plus dx)) 'length))

(map 'nil (funcall (compose 'print) (yoba 123))
     '(() (1) (3 2 3)))