cljs-dev

john 2024-03-28T15:25:16.976449Z

@p-himik was recommending pinging this channel about this, as it might relate known bugs. Is this currently not possible?

p-himik 2024-03-28T15:25:59.524869Z

^ Related to https://clojure.atlassian.net/browse/CLJS-364

john 2024-03-28T15:47:11.530169Z

Like, not even possible in a deftype, reify or specify situation? It might not have to be a defrecord, just be map-like

dnolen 2024-03-30T14:55:57.335969Z

I realized we probably already did this for defrecord? I guess you didn’t look there first?

john 2024-03-30T14:57:47.941899Z

hmm? I presumed records already impl the one and two arity of invoke for map lookup like with maps in the call position

john 2024-03-30T15:34:11.602539Z

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

dnolen 2024-03-30T20:41:30.722439Z

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

john 2024-03-30T21:19:30.625229Z

Well I did look at the implementation of defrecord out of curiosity. I didn't see that it had IFn

john 2024-03-30T21:37:57.125579Z

Yeah I don't think they have IFn

john 2024-03-30T22:25:53.808239Z

variadic-fn is what I want, right?

john 2024-04-09T20:34:51.392999Z

Or do you mean just re implement defrecord and repurpose its variadic field declaration vector to be a parameter vector?

dnolen 2024-03-28T17:08:25.513699Z

there are some special properties added to normal fns to make them work, specifically cljs$lang$applyTo

dnolen 2024-03-28T17:08:58.864269Z

this existed before IFn was a thing - so that suggests a gap.

dnolen 2024-03-28T17:09:13.991289Z

but you can probably make it work by adding this property (and a couple others)

dnolen 2024-03-28T17:09:21.640089Z

I would examine cljs.core/apply for details

dnolen 2024-03-28T17:09:44.152839Z

finally, probably this will be a bit ugly and yeah we should probably update the protocol to fill the gap

dnolen 2024-03-28T17:10:00.173739Z

see if you can make it work, and feel free to open a issue

👍 1
john 2024-03-28T21:12:02.421849Z

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 setup

john 2024-03-28T21:20:44.311389Z

looks like -contains-key? is still impl'ed after the change

john 2024-03-28T21:58:01.517049Z

For 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))

john 2024-04-17T02:32:22.597779Z

@dnolen 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

john 2024-04-17T02:32:51.020469Z

The docs are scant at the moment, but if you're interested, that's the direction the API is going in