;; see for details (fn curry [f n ?args] (let [args (or ?args {:n 0})] (fn [...] (let [inner (table.pack ...) n* (+ args.n inner.n)] (doto inner (table.move 1 inner.n (+ args.n 1)) (tset :n n*)) (table.move args 1 args.n 1 inner) (if (>= n* n) (f ((or _G.unpack table.unpack) inner 1 n*)) (curry f n inner)))))) (macro defcurry [name arglist ...] `(local ,name (curry (fn ,arglist ,...) ,(length (icollect [_ a (ipairs arglist) :until (= (tostring a) "...")] a)))))