Fork me on GitHub
#clojurescript
<
2018-04-13
>
kenny01:04:46

@mfikes Thanks. I'm not sure I understand how the original function is actually being replaced though. It looks like it's just using doto on a newly created function.

kenny01:04:20

Wow, I'm blind. I swear I stared at that function for a solid minute and didn't see that. Thanks 🙂

quoll15:04:57

I’m wondering if the identity of objects returned from sets (when called as a function) is documented. In Clojure, I see:

user=> (def s #{(with-meta [:a] {:n 42})})
#'user/s
user=> (meta (s [:a]))
{:n 42}
In ClojureScript, I see:
figwheel:cljs.user=> (def s #{(with-meta [:a] {:n 42})})
#'cljs.user/s
figwheel:cljs.user=> (meta (s [:a]))
nil

quoll15:04:37

As expected, the set entry still has the metadata:

figwheel:cljs.user=> (meta (first s))
{:n 42}

quoll15:04:30

So I’m curious as to whether this is undefined behavior (and therefore legit), or a bug

john15:04:35

cljs doesn't carry it's meta info around in the same way as clj

dnolen15:04:49

@john that’s not true

dnolen15:04:12

@quoll I would consider it a bug

dnolen15:04:43

@john there’s no difference in the semantics of metadata between Clojure / ClojureScript

quoll15:04:51

OK, thank you David. I’ll put a ticket in for it

dnolen15:04:57

@quoll similar cases have since been resolved

john15:04:49

ah I misread that

john15:04:19

do we still not put runtime metadata on functions though?

quoll16:04:00

Forgot to say… I submitted it here (please let me know if I’ve done something wrong so I can update it): https://dev.clojure.org/jira/browse/CLJS-2736

souenzzo18:04:59

The solution is something like

(let [array (into-array coll)
      k (.indexOf array v)]
  (aget array k))
??? or use reduce? or use loop/recur?

quoll18:04:27

how about…

(-lookup [coll v not-found]
    (if-let [entry (-find hash-map v)
      (key entry)
      not-found))

quoll18:04:25

Heh… it occurred to me that hash-sets aren’t the only set. So I just looked at the implementation of PersistentTreeSet, and this is pretty much what that implementation is already doing https://github.com/clojure/clojurescript/blob/aac49934f41d89c28bbc021a37878e213566decc/src/main/cljs/cljs/core.cljs#L9271

souenzzo19:04:12

(-find #{11 22 33} 11) does not work on lumo repl

quoll16:04:23

Is it worth mentioning that it also occurs when calling get explicitly, or is that sufficiently implied?

souenzzo18:04:59

The solution is something like

(let [array (into-array coll)
      k (.indexOf array v)]
  (aget array k))
??? or use reduce? or use loop/recur?

kenny18:04:52

Is there a way to enabled Spec instrumentation as the very first think that is ran? I am running into an issue where I call st/instrument in my app's entrypoint but because other namespaces have been loaded and have functions calls that occur immediately, they are not replaced with the spec-checking-fn set by instrument. This means all initial calls are not instrument'ed.

nenadalm19:04:47

If you have some namespace which needs to be initialized (contains function calls evaluated when loaded). You can provide init function for such namespaces and then have your entrypoint code:

(instrument)
(app.namespace1/init)
(app.namespace2/init)
(app.namespace3/init)
...

kenny19:04:46

That will still not catch initial function calls. Also that'd need to be done for every namespace because every namespace has functions that need to be instrumented. For a large app with 60+ namespaces, that would be quite annoying to have to do.

nenadalm19:04:06

Yes, that will catch initial function calls if you won't call them immediately but put them into init function inside of the namespace. What these functions you need to call in so many namespaces when they're loaded do?

kenny18:04:24

Perhaps as a :preload?

kenny18:04:08

That's exactly the example :preloads has in the docs: https://clojurescript.org/reference/compiler-options#preloads 🙂

kenny19:04:51

Actually, enabling instrumentation in a preload does not work for my application. None of the symbols are defined when instrument is called in the preload.

kenny19:04:14

Not sure how enabling instrumentation in a preload would ever work for instrumenting your own code.

kenny19:04:51

I have

(defn my-test
  [a b]
  (+ a b))

(s/fdef my-test
        :args (s/cat :a int? :b int?)
        :ret int?)
in a core.cljs and (prn (cljs.spec.test.alpha/instrument)) in a preload. [] is printed out to the console as the result of the instrument call. That doesn't seem like the behavior intended, as described in the preloads compiler option doc.

richiardiandrea19:04:43

I have noticed the same, thanks for bringing it up

thheller19:04:58

@kenny I'm not 100% but I think instrument changes the actual JS var which means it can only work on things that were defined before instrument was called

thheller19:04:34

so if you do that in the preload there probably aren't any

kenny19:04:29

Exactly. That's the problem though.

dnolen19:04:36

instrument in preloads isn’t going to work

dnolen19:04:57

so you’re going to have to try something else

dnolen19:04:46

i.e. call instrument from your entry point

kenny19:04:39

I suggest removing that from the compiler option doc then 🙂 Calling from the entry point is problematic for all function calls that occur before the entrypoint is reached (i.e. global registrations like re-frame's reg-event-* functions).

dnolen19:04:55

removing what from the compiler option doc?

kenny19:04:09

https://clojurescript.org/reference/compiler-options#preloads > Developing ClojureScript commonly requires development time only side effects such as enabling printing, logging, spec instrumentation, and connecting REPLs.

dnolen19:04:25

we’re not going to change that

dnolen19:04:30

since it has nothing to do with instrument

dnolen19:04:49

oh that one line

dnolen19:04:11

@kenny I didn’t realize we’d made that change

dnolen19:04:20

it was never true that this would work for spec

kenny19:04:55

Are you talking about the doc or initial function calls?

dnolen19:04:30

@kenny top level side effects aren’t a good idea anyway - you should really avoid that when possible

dnolen19:04:42

but yes if you have top level calls then you can’t instrument that stuff

dnolen19:04:58

but even this is not really a problem

dnolen19:04:11

use goog-define or whatever for test builds

kenny19:04:18

Gotcha. All of re-frame's API is top level side effects 🙃

dnolen19:04:24

not our problem

kenny19:04:57

I know. Just a difference I did not realize between Clojure's Spec and CLJS spec.

dnolen19:04:29

@kenny I fixed the website, thanks

4