about summary refs log tree commit diff stats
path: root/fnl/curry.fnl
diff options
context:
space:
mode:
authorelioat <hi@eli.li>2023-07-27 15:27:18 -0400
committerelioat <hi@eli.li>2023-07-27 15:27:18 -0400
commitb2e73505a8348b3ac2fd5378866a9f9623f67a26 (patch)
treea4d1e61ddb1162f9c0bf0e7a7fd4ca513be49ce0 /fnl/curry.fnl
parent34ec451e0b27622932cd3991572891de83aaa3da (diff)
downloadtour-b2e73505a8348b3ac2fd5378866a9f9623f67a26.tar.gz
*
Diffstat (limited to 'fnl/curry.fnl')
-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)))))
+