Skip to content

Commit

Permalink
e/partial - better, native implementation
Browse files Browse the repository at this point in the history
The macro impl from v2 seems to have siting issues in v3 that I did not investigate
  • Loading branch information
dustingetz committed Aug 9, 2024
1 parent 8f83641 commit e9634f3
Showing 1 changed file with 35 additions and 12 deletions.
47 changes: 35 additions & 12 deletions src/hyperfiddle/electric_de.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -260,18 +260,41 @@ A mount point can be :

(defmacro apply [& args] `($ Apply ~@args))

(defmacro partial
"Like `cc/partial` for reactive functions. Requires the target function
arity (`argc`) until reactive function supports variadic arguments.
e.g. (new (partial 2 (e/fn [a b] [a b]) :a) :b) ;; => [:a :b]"
[argc F & args]
(if (= 0 argc)
F
(let [rest-args (map #(symbol (str "arg_" %)) (range (- argc (count args))))]
`(let [F# ~F]
(hyperfiddle.electric-de/fn ~@(when (symbol? F) [F]) [~@rest-args]
($ F# ~@args ~@rest-args))))))
(hyperfiddle.electric-de/defn ; ^:hyperfiddle.electric.impl.lang-de2/print-clj-source
Partial
"Takes an Electric function F and fewer than the normal arguments to F, and
returns a e/fn that takes a variable number of additional args. When
called, the returned function calls F with args + additional args."
;; Impl is a mechanical 1 to 1 transaltion of clojure partial.
;; generated code is quite large but redundant, so it gzip to 903 bytes.
;; we could prune this impl to reduce code size (no clear benefit)
;; We keep this impl as a proof that our lambda abstraction is correct
;; We might optimise it later if there are perf issues.
([F] F)
([F arg1]
(hyperfiddle.electric-de/fn
([] ($ F arg1))
([x] ($ F arg1 x))
([x y] ($ F arg1 x y))
([x y z] ($ F arg1 x y z))
([x y z & args] (hyperfiddle.electric-de/apply F arg1 x y z args))))
([F arg1 arg2]
(hyperfiddle.electric-de/fn
([] ($ F arg1 arg2))
([x] ($ F arg1 arg2 x))
([x y] ($ F arg1 arg2 x y))
([x y z] ($ F arg1 arg2 x y z))
([x y z & args] (hyperfiddle.electric-de/apply F arg1 arg2 x y z args))))
([F arg1 arg2 arg3]
(hyperfiddle.electric-de/fn
([] ($ F arg1 arg2 arg3))
([x] ($ F arg1 arg2 arg3 x))
([x y] ($ F arg1 arg2 arg3 x y))
([x y z] ($ F arg1 arg2 arg3 x y z))
([x y z & args] (hyperfiddle.electric-de/apply F arg1 arg2 arg3 x y z args))))
([F arg1 arg2 arg3 & more]
(hyperfiddle.electric-de/fn [& args]
(hyperfiddle.electric-de/apply F arg1 arg2 arg3 (concat more args)))))

(cc/defn on-unmount* [f] (m/observe (cc/fn [!] (! nil) f)))

Expand Down

0 comments on commit e9634f3

Please sign in to comment.