Fork me on GitHub
#clojurescript
<
2019-09-04
>
dpsutton00:09:36

It depends on what you’re rendering. And I’m assuming reagent is turning your hiccup into react elements

ag00:09:03

I wonder if there’s a work-around

Aklscc02:09:27

Hey, Is there anyone knowing the rationale of the js/{namespace}? How many js things that we can use via it? I have seen the docs http://cljs.github.io/api/syntax/js-namespace, But it doesn't include this.

potetm02:09:11

I’m not sure the question. js/whatever just allows you to access the js global object.

potetm02:09:38

The rational is: without it, you would not be able to access the js global object 😄

potetm02:09:16

I guess to answer your question: You can access anything that you could have accessed in JS directly. (e.g. $ for jquery, ReactDOM.render, _.* for lodash, etc etc etc)

potetm02:09:23

There is no limit.

Aklscc02:09:50

Ok, I know it, thank you.

thheller08:09:11

@ag reagent components themselves can't use hooks but regular JS functions components can. did you maybe turn them into classes via the reagent/adapt-react-class or something?

Aklscc09:09:08

How can we debug the macro in ClojureScript? It doesn't work for repl because of its feauture. And I really confuse with the following code:

(defmacro promise->
  [promise & body]
  `(.catch
    (-> ~promise
        [email protected](map (fn [expr] (list '.then expr)) body))
    (fn [error#]
      (prn "Promise rejected " {:error error#}))))
What's the evalution of the macro expression? Why the exec sequence if promise.then(body-first.then(...))?

Vesa Norilo09:09:20

(macroexpand '(some form, remember the quote)) -> will output the s-expressions after macros have been applied

Vesa Norilo09:09:50

I've never had trouble macroexpanding in cljs repl (mostly use figwheel)

Aklscc10:09:45

Correctly, it' true, because you have inject runtime environment when use figwheel.

Leon11:09:52

how do you guys keep your reagent components code readable? everytime i'm using map to create lists out of data it gets unreadable extremely quickly... any tips? or maybe some helpers i'm missing?

ingesol11:09:29

Well, if you do (map my-comp my-things), that might help?

Leon11:09:18

yea i do, but then if i need to provide some props to my-comp it turns into

(map #(vec [my-comp {:foo "bar} %]) my-things)
and now if these props get bigger, or if my-things isn't that simple and i need to
(map #(vec [my-comp (first %)]) my-things)
or something it gets ugly

ingesol11:09:25

(map (partial my-comp some-param) things)

ingesol11:09:36

I got nothing prettier than that, though.

flowthing11:09:42

(map #(vector my-comp %) things) might be just a tiny bit cleaner than vec.

Leon12:09:57

thanks, i guess ill have to make do with that..

Karol Wójcik13:09:04

U can always use for

danielneal11:09:26

I sometimes find for can be more readable than map

danielneal11:09:34

but then you need a doall so

danielneal11:09:48

swings and roundabouts 😄

ingesol11:09:26

@danieleneal Sure about that? Both for and map are lazy, so the need for doall should be independent of that

danielneal11:09:12

oh yeah 😄

martinklepsch15:09:56

Is there a way to check the type of something without importing/requiring it’s constructor? In my particular case the constructors reside in different modules based on node/browser so requiring it in shared code is more tricky (afaik only possible with Shadow CLJS)

dnolen15:09:15

not as far as I can see

dpsutton15:09:05

a protocol that returns some keyword indicator?

dnolen15:09:13

oh hrm - that reminds me there is a detail thing that's unlikely to change - I wouldn't do it in a lib - but for app maybe ok

dnolen15:09:05

yeah, types need to be printable so that string is on a "static" field of the type - you can see this if you look at the implementation of deftype

Leon17:09:03

hey! im trying to use expound with clojurescript, but setting ` (set! s/explain-out expound/printer)` doesn't seem to do anything.. any ideas?

alexmiller17:09:21

might depend what repl / clojure version you are using

bbrinck17:09:57

@lkowarschick Yes, it may depend on the environment and what you are trying to do with expound https://github.com/bhb/expound/blob/master/doc/compatibility.md

Leon17:09:41

the compatibility chart says it should be compatible. how would that thing: clj -Srepro -Sdeps '{:deps {expound {:mvn/version "0.7.2"} org.clojure/test.check {:mvn/version "0.9.0"} org.clojure/clojurescript {:mvn/version "1.10.520"}}}' -e "(require '[expound.alpha :as expound]) (set! clojure.spec.alpha/*explain-out* expound.alpha/printer)" -m cljs.main -re node be achieved with lein/shadow-cljs?

bbrinck18:09:25

With lein, I wonder if you could use injections? Not sure https://github.com/technomancy/leiningen/blob/301d802eb1c4574c9094780aa6aff845ee14f2f9/sample.project.clj#L182 As for shadow-cljs, I haven’t used it so I can’t say

bbrinck18:09:51

That said, that step should only be necessary if you are trying to get expound errors when using macros.

bbrinck18:09:15

What happens if you instrument a function and call it?

bbrinck18:09:35

Do you see expound messages if you do something like the following?

(set! s/*explain-out* expound/printer)
(s/explain (s/coll-of int?) [1 2 "3"])
(I’m just trying to figure out how you are using spec in this case)

Leon18:09:33

in that case it works..

bbrinck18:09:22

What if you instrument a function and then call it?

Leon18:09:43

then it doesnt

bbrinck18:09:03

Can you share the code you’re using to instrument the function?

Leon18:09:54

just a simple function, and then afterwards stest/instrument

bbrinck18:09:47

hm, what’s the fdef?

bbrinck18:09:08

For instance, this gives me an expound error:

cljs.user=> (require '[clojure.spec.alpha :as s])
nil
cljs.user=> (require '[expound.alpha :as expound])
nil
cljs.user=> (set! s/*explain-out* expound/printer)
#object[expound$alpha$printer]
cljs.user=> (require '[clojure.spec.test.alpha :as st])
nil
cljs.user=> (s/fdef add :args (s/cat :x int? :y int?))
cljs.user/add
cljs.user=> (defn add [x y] (+ x y))
#'cljs.user/add
cljs.user=> (st/instrument)
cljs.user=> (add 1 "2")

bbrinck18:09:27

if you can share your code, I might spot the issue

Leon18:09:01

i just copied yours and it didnt work haha also, your simple example doesn't seem to work outside of the repl (so regularly within the code)

bbrinck18:09:32

Interesting, but you are seeing a spec error when calling your simple function, just not an expound error?

bbrinck18:09:41

(outside of the repl)

Leon18:09:43

yes, i am getting a spec error

bbrinck18:09:21

Interesting. are you getting a formatted message or just the raw spec data?

Leon18:09:48

they are formatted

bbrinck18:09:08

What version of CLJS?

Leon18:09:21

1.10.520

bbrinck18:09:02

Huh, that’s weird, outside of a REPL I thought recent versions of CLJS were not formatting spec errors. In any case, I suspect either

bbrinck18:09:13

a) somehow the printer is not getting set (perhaps this code is not called before the simple function is called) b) the environment (not sure if you’re using lein-cljsbuild or shadow-cljs) is adding some wrapper code that prints specs and that is not using the current value of s/*explain-out*.

Leon18:09:43

i guess it could be related to the thing thats formatting the spec output?

bbrinck18:09:45

If you can push a repo with repros the issue, I can take a look but it’s hard to say over slack since there are a lot of environment-specific variables

Leon18:09:10

ill try to do that, tomorrow ;D thanks for your help anyways ^^

👍 1
bbrinck18:09:14

Yeah, the thing that formats the spec output is environment specific - different for different repls, etc

roman01la18:09:32

(defn primes []
  [2 3 5 7])

(identical? (primes) (primes))
true
Why is it returning true?

bronsa18:09:48

well, in clojure constant collections are created at initialisation time just once rather than at runtime, I imagine clojurescript has a similar optimisation

roman01la18:09:52

mmm, I don't think so, at least not in self hosted cljs

thheller18:09:21

clojurescript does not do this no

unionx18:09:33

so the primes fn returns the same object, kinda like a singleton

Tim18:09:05

Yeah, it seems it just creates a static variable

roman01la18:09:44

Nice. Wonder if ClojureScript should be on par with Clojure here? cc @dnolen

dnolen18:09:32

pretty sure there's a ticket for this, we in fact already do this for keywords/symbols

dnolen18:09:47

note it can't really be the same as Clojure

dnolen18:09:05

but it could be the same for advanced compilation like w/ keywords symbols

Tim18:09:40

just checked in online cljs repl and it behaves differently

thheller18:09:45

I would like to see some performance tests since this may affect startup performance

dnolen18:09:17

right should check that

dnolen18:09:31

and I think the keyword case has the biggest impact runtime wise

metehan19:09:15

hi guys, why we don't have "walk" of clojure in clojurescript http://clojuredocs.org/clojure.walk/walk , or do we have ? how can i change every value of my map

manutter5119:09:17

You can actually require clojure.walk in CLJS, no problem.

metehan19:09:35

I will change an values of an incoming json to keywords like {"id", ":my-id"} to {"id", :my-id}

metehan19:09:15

i see thanks

metehan19:09:14

do you know any library keywordize values

manutter5119:09:29

Hmm, usually people are looking for keywordize keys

manutter5119:09:37

but shouldn’t be too hard…

manutter5120:09:47

Something like this:

(require '[clojure.walk :as walk])
(defn keywordize-values
  [m]
  (let [stringify (fn [[k v]]
                    (let [v (if (string? v)
                              (if (= \: (first v))
                                (keyword (subs v 1))
                                (keyword v))
                              v)]
                      [k v]))]
    (walk/postwalk (fn [x]
                     (if (map? x)
                       (into {} (map stringify x))
                       x))
                   m)))

manutter5120:09:55

(keywordize-values {"id" ":my-id"
                    "sub" {"id" ":my-other-id"}})
=> {"id" :my-id, "sub" {"id" :my-other-id}}

metehan20:09:55

(def sample {:a ":rabbit"
             :b "bird"
             :c ":zebra"
             :d 5})

(defn keyword-str [val]
  (if (string? val)
    (if (= (subs val 0 1) ":") 
      (keyword (replace-first val ":" ""))
      val)
    val))

(defn keywordize-map [m]
  (zipmap
   (keys m)
   (map keyword-str (vals m))))

metehan20:09:56

i made like this do you think this may create some bugs later

metehan20:09:06

yours nicer actually it works for sub maps too

manutter5120:09:11

Yeah, I basically looked up the source code for clojure.walk/keywordize-keys and adapted it to convert the values instead.

metehan20:09:25

thank you very much

alexmiller20:09:11

there' s a ticket out there to genericize some of that stuff to open it up more

Eccentric J23:09:02

> generally for any function that is collection -> collection, the collection should be the first arg. What about map, filter, reduce, etc...?

alexmiller23:09:40

those are sequence -> sequence

alexmiller23:09:49

where the sequence goes last

metehan20:09:24

I just did