about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--fnl/curry.fnl22
1 files changed, 22 insertions, 0 deletions
diff --git a/fnl/curry.fnl b/fnl/curry.fnl
new file mode 100644
index 0000000..3b5a113
--- /dev/null
+++ b/fnl/curry.fnl
@@ -0,0 +1,22 @@
+;; see <https://wiki.fennel-lang.org/Currying> 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)))))
+