Fork me on GitHub
#clojurescript
<
2021-02-22
>
jcburley02:02:08

Hi! Does ClojureScript “intentionally” treat a leading dot (.) as potentially the first character in a floating-point literal? Clojure treats “.” as a symbol character, but based on what I’m seeing in lumo, ClojureScript doesn’t (always):

$ lumo
Lumo 1.10.1
ClojureScript 1.10.520
Node.js v11.13.0
 Docs: (doc function-name-here)
       (find-doc "part-of-name-here")
 Source: (source function-name-here)
 Exit: Control+D or :cljs/quit or exit

cljs.user=> .1
0.1
cljs.user=> 

Nazral02:02:58

I am having an issue with advanced compilation and goog.string.format. I think a type hint would solve it but not sure where to put it. I tried (gstring/format "%.2f" ^number v) but it is not working

phronmophobic03:02:35

what's not working? is there an error? is there a stack trace?

Nazral02:02:42

Sorry I'm only replying now, there was a stack trace starting with something like Cc.format is not a function and a whole minified stack trace under

Nazral02:02:52

so not very helpful, and cannot reproduce if the code is not minified

phronmophobic02:02:48

@UGH9KH1DF , what do your requires for that namespace look like? are you requiring goog.string?

phronmophobic02:02:36

oh wait, what namespace are you trying to reference? It doesn't look like goog.string.format exists, https://google.github.io/closure-library/api/goog.string.html

phronmophobic02:02:51

maybe you just want (format "%.2f" v)

Nazral02:02:30

When I tried to use format the compiler was telling me that format is not part of cljs.core though

Nazral02:02:25

(I did fix the problem by using js's .toFixed)

👍 3
phronmophobic02:02:38

you need to require both [goog.string :as gstring] and [goog.string.format]

Nazral02:02:40

Ohhhh ok thank you! Will try, but I don't get why are both requires needed :thinking_face:

phronmophobic02:02:14

the format function is written in a separate module, goog.string.format, but the function is added to goog.string namespace, https://github.com/google/closure-library/blob/4f18d359603b23dd4db402d62d796ea0e40ae48f/closure/goog/string/stringformat.js#L33

Nazral03:02:50

I see, thank you for clarifying

Adrian Imanuel07:02:08

hi, a total newbie here... in lein we use lein new app testing to create a clojure project called testing. but how to create clojurescript project with leinengen?

vanelsas07:02:39

Hi Adrian, you could try one of the templates here: https://clojurescript.org/guides/project-templates

Adrian Imanuel10:02:33

ohhhh, thank you @U01M742UT8F, will try on this :D

Takis_13:02:10

Hello persistent maps and transients maps are expected to be 3x slower than js-objects? i did a simple benchmark that i just added members

Takis_13:02:51

"Elapsed time: 3887.477828 msecs"   (persistent)
"Elapsed time: 3352.944982 msecs"   (transient)
"Elapsed time: 1113.168076 msecs"   (js-object)

Takis_13:02:37

is this expected? we can do something about it?

thheller13:02:53

mutating JS objects is always going to be faster yes.

Takis_13:02:08

I did the same with vectors,but the difference there was small transient was 5sec,js-array was 4sec

Takis_13:02:24

yes but its 3x , its big difference in maps

thheller13:02:47

don't know what you are benchmarking to comment

Takis_13:02:19

(defn p-m [size]
  (loop [i 0
         v {}]
    (if (= i size)
      v
      (recur (inc i) (assoc v (str i) i)))))

(defn t-m [size]
  (loop [i 0
         v (transient {})]
    (if (= i size)
      (persistent! v)
      (recur (inc i) (assoc! v (str i) i)))))

(defn j-m [size]
  (loop [i 0
         v (js/Object)]
    (if (= i size)
      v
      (recur (inc i) (do (aset v (str i) i) v)))))

Takis_13:02:31

simplest benchmark

thheller13:02:45

yeah. things won't look good in such a comparison. still reasonable though.

joelkuiper13:02:24

has anyone had any luck integrating npm dependencies (in this case https://nivo.rocks/) via figwheel-main? I basically took the clj -X:new clj-new/create :template figwheel-main :name example/example :args '["+npm-bundle","--reagent"]' command and added the npm dependency, ran the npm install and tried to import it e.g. (:require ["@nivo/pie" :refer [ResponsivePie]]) and adapt it via reagent [:> ...] however (maybe to be expected) I'm missing something as it yields Uncaught TypeError: example.node$module$_CIRCA_nivo$pie is undefined

joelkuiper14:02:28

funny, react-bootstrap does work with the same mechanism, maybe the "@" symbol?

joelkuiper14:02:02

huh, nevermind got it to work by restarting, I guess the module wasn't picked up dynamically or something

Takis_13:02:54

thank you thheller if someone knows if i can do something about it, to reduce the 3x , tell me if you can

thheller13:02:49

you can't optimize this further

thheller13:02:53

but you are comparing persistent datastructures to a mutable object. that is hardly fair given the different features they provide.

thheller13:02:14

you can after all just use JS objects when that really matters and you don't need all the stuff the maps give you.

Takis_13:02:27

its ok , i know that they work in different way , thank you for helping me

Takis_14:02:19

i noticed that the slow is the HashMap, ArrayMap is fast similar to js-object , from my code the ArrayMap auto becomes HashMap if 9 or more members

andy.fingerhut14:02:35

There is no built-in way without modifying the ClojureScript implementation code itself to do that.

andy.fingerhut14:02:44

Note that ArrayMap always do linear scanning through keys when you do lookups on them. If your maps are being looked up more frequently than they are being constructed, using ArrayMap for larger maps might make your overall performance worse.

Takis_14:02:41

ok thank you , i didnt know that

Takis_14:02:00

is there a way to say keep it ArrayMap for lets say 30 members? (my maps are almost never bigger)

emccue14:02:02

@takis_ If your maps are never more than 30 members, please do yourself a favor and ignore performance

emccue14:02:26

only optimize stuff when it gets to be too slow empirically

emccue14:02:38

not when you think it might be too slow hypothetically

Takis_14:02:33

they can be many of them , like thousands

Takis_14:02:43

i think this is the code

(set! (.-HASHMAP_THRESHOLD ObjMap) 8)
anyway thank you all : )

ghadi17:02:17

I would not modify that 🙂

flowthing17:02:09

I wonder what the wider context of your performance issue is. It might be that there's another way to solve it.

Takis_21:02:55

i checked this https://github.com/mfikes/cljs-bean it looks like it does what i need,easy interop and fast , thank you for information i am new in clojurescript

Yehonathan Sharvit19:02:34

Today I learned that a ClojureScript object could mimic a JavaScript object (Thank you @thheller) via JavasScript proxy. I wrote a small naive piece of code for that

(defn proxy [m]
  (js/Proxy. m #js {:get (fn [target prop]
                           (let [prop' (if (vector? target)
                                        (js/parseInt prop)
                                        (keyword prop))]
                             (let [v (or (get target prop')
                                         (get target prop))]
                               (if (coll? v)
                                 (proxy v)
                                 v))))}))

Yehonathan Sharvit19:02:05

(def n {:a {:b [{:c {:d 1}}]}})
(def m (proxy n))

Yehonathan Sharvit19:02:36

It is quite similar @mfikes’s bean but in the other direction. Do you guys think it a function like proxy could be useful?

Yehonathan Sharvit19:02:35

Awesome! Thank you pithyless. Another great contribution by @wilkerlucio

Yehonathan Sharvit19:02:57

With https://github.com/mfikes/cljs-bean and https://github.com/wilkerlucio/js-data-interop conversion from ClojureScript to JavaScript back and forth is super efficient. Thank you @mfikes and @wilkerlucio

❤️ 6
wilkerlucio19:02:20

you'r welcome, I just like to add bit on the maturity of this library (js-data-interop), I only used for some experiments, and I don't know anybody that used this in prod, please let me know if you find some issues on the approach

Yehonathan Sharvit20:02:24

Hacking a bit with js-data-interop

Yehonathan Sharvit20:02:46

It doesn’t work with string keys in maps

Yehonathan Sharvit20:02:53

(.-a (jsp {"a" 1})) ;; => nil

p-himik20:02:25

Just out of interest - what would (.-a (jsp {"a" 1, :a 2})) ideally do/return?

Yehonathan Sharvit20:02:57

Same as (.-a (clj->js {"a" 1, :a 2})) 😁

👍 3
p-himik08:02:58

I guess it would also make sense to support symbols then, assuming you want to be as close to clj->js as possible. As a side note, there's also IEncodeJS which IMO makes 100% compatibility with clj->js unfeasible.

Yehonathan Sharvit13:02:39

what’s IEncodeJS?

p-himik13:02:50

It's from the clj->js implementation:

(cond
  ...
  (satisfies? IEncodeJS x) (-clj->js x)
  ...)
No clue whether it's documented anywhere.