This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-03-28
Channels
- # aleph (7)
- # babashka (13)
- # beginners (10)
- # biff (4)
- # calva (75)
- # cljs-dev (22)
- # clojure (55)
- # clojure-berlin (1)
- # clojure-europe (15)
- # clojure-nl (1)
- # clojure-norway (35)
- # clojure-serbia (1)
- # clojure-uk (2)
- # clojurescript (46)
- # community-development (1)
- # core-async (23)
- # data-science (1)
- # datalevin (2)
- # datascript (10)
- # datomic (11)
- # fulcro (28)
- # helix (12)
- # hyperfiddle (26)
- # introduce-yourself (4)
- # malli (16)
- # off-topic (1)
- # pathom (4)
- # pedestal (1)
- # polylith (12)
- # quil (11)
- # releases (3)
- # scittle (24)
- # shadow-cljs (85)
- # specter (1)
- # sql (9)
- # xtdb (5)
@p-himik was recommending pinging this channel about this, as it might relate known bugs. Is this currently not possible?
Like, not even possible in a deftype, reify or specify situation? It might not have to be a defrecord, just be map-like
there are some special properties added to normal fns to make them work, specifically cljs$lang$applyTo
finally, probably this will be a bit ugly and yeah we should probably update the protocol to fill the gap
Okay, this appears to be working:
~@(if-cljs
&env
['cljs.core/IAssociative
`(~'-assoc
[this# k# g#]
(let [new-afn# (~(symbol (str "map->>" afname)) (into (assoc {} k# g#) this#))]
(set! (.-cljs$lang$applyTo new-afn#)
(fn [inner-this#] (apply af.fect/run-af new-afn# inner-this#)))
new-afn#))]
[])
I'm using a clj macro file and a cljc file in that setupFor posterity: not pretty, but it's handling both clj and cljs:
(defn if-cljs
[env then else]
(if (:ns env) then else))
(defmacro daf [afname ctx]
`(do (defrecord ~(symbol (str ">" afname)) []
~@(if-cljs &env ['cljs.core/Fn 'cljs.core/IFn] ['clojure.lang.IFn])
~@(if-cljs &env
(->> (range 22)
(map (fn [n]
(let [args (for [i (range n)] (symbol (str "arg" i)))]
(if (empty? args)
`(~'-invoke
[this#]
(af.fect/run-af this#))
(if-not (< 21 (count args))
`(~'-invoke
[this# ~@args]
(af.fect/run-af this# ~@args))
`(~'-invoke
[this# ~@args]
(apply af.fect/run-af this# ~@args))))))))
(->> (range 22)
(map (fn [n]
(let [args (for [i (range n)] (symbol (str "arg" i)))]
(if (empty? args)
`(~'invoke
[this#]
(af.fect/run-af this#))
`(~'invoke
[this# ~@args]
(af.fect/run-af this# ~@args))))))))
~@(if-cljs
&env
['cljs.core/IAssociative
`(~'-assoc
[this# k# g#]
(let [new-afn# (~(symbol (str "map->>" afname))
(merge (into {} this#)
(assoc {} k# g#)))]
(set! (.-cljs$lang$applyTo new-afn#)
(fn [inner-this#] (apply af.fect/run-af new-afn# inner-this#)))
new-afn#))]
[`(~'applyTo
[this# args#]
(apply af.fect/run-af this# args#))]))
(def ~afname
(~(symbol (str "map->>" afname)) ~ctx))
~@(if-cljs &env
[`(set! (.-cljs$lang$applyTo ~afname)
(fn [this#] (apply af.fect/run-af ~afname this#)))]
[])
~afname))
I realized we probably already did this for defrecord
? I guess you didn’t look there first?
hmm? I presumed records already impl the one and two arity of invoke for map lookup like with maps in the call position
That record has no fields on it when constructed. This is leaning into record's ability to take on new fields after being instantiated. So we're not talking about the arity of the fields vector here in defrecord creation but that of the returned record
What I meant was don’t records have to implement IFn and the apply stuff? I’m not saying it’s the best way rather as reference for doing it
Well I did look at the implementation of defrecord
out of curiosity. I didn't see that it had IFn
Or do you mean just re implement defrecord
and repurpose its variadic field declaration vector to be a parameter vector?
@U050B88UR Here's a repo showing the idea as a deftyped thing in cljs: https://github.com/johnmn3/step-up/blob/main/src/step_up/alpha/user.cljs