clojurescript

ClojureScript, a dialect of Clojure that compiles to JavaScript http://clojurescript.org | Currently at 1.10.879
jcburley 2021-02-22T02:36:08.022800Z

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=> 

Nazral 2021-02-22T02:52:58.024400Z

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

Nazral 2021-02-23T02:23:42.058800Z

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

Nazral 2021-02-23T02:23:52.059Z

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

phronmophobic 2021-02-23T02:41:48.059200Z

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

phronmophobic 2021-02-23T02:42:36.059400Z

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

phronmophobic 2021-02-23T02:42:51.059600Z

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

Nazral 2021-02-23T02:44:30.059800Z

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

Nazral 2021-02-23T02:45:25.060Z

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

👍 1
phronmophobic 2021-02-23T02:48:13.060200Z

according to this answer, https://stackoverflow.com/a/34668677

phronmophobic 2021-02-23T02:48:38.060500Z

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

Nazral 2021-02-23T02:50:40.060800Z

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

phronmophobic 2021-02-23T02:56:12.061Z

it look it's just an odd implementation choice by goog.string.format, https://github.com/google/closure-library/blob/4f18d359603b23dd4db402d62d796ea0e40ae48f/closure/goog/string/stringformat.js#L17

phronmophobic 2021-02-23T02:57:14.061300Z

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

Nazral 2021-02-23T03:13:50.061600Z

I see, thank you for clarifying

phronmophobic 2021-02-22T03:39:35.024500Z

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

Yehonathan Sharvit 2021-02-22T05:13:24.024900Z

I tried and it seems to work even for deeply nested maps! https://gist.github.com/viebel/6086821294611d4be3f45ccc28060f2e

2021-02-22T07:19:08.026400Z

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?

2021-02-22T10:34:33.026900Z

ohhhh, thank you @alexander.vanelsas, will try on this :D

vanelsas 2021-02-22T07:36:39.026500Z

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

takis_ 2021-02-22T13:37:10.028600Z

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_ 2021-02-22T13:37:51.029500Z

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

takis_ 2021-02-22T13:38:37.029800Z

is this expected? we can do something about it?

thheller 2021-02-22T13:40:53.031Z

mutating JS objects is always going to be faster yes.

takis_ 2021-02-22T13:41:08.031200Z

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

takis_ 2021-02-22T13:41:24.031600Z

yes but its 3x , its big difference in maps

thheller 2021-02-22T13:41:47.032Z

don't know what you are benchmarking to comment

takis_ 2021-02-22T13:42:19.032300Z

(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_ 2021-02-22T13:42:31.032600Z

simplest benchmark

thheller 2021-02-22T13:46:45.034900Z

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

joelkuiper 2021-02-22T13:48:24.036300Z

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

takis_ 2021-02-22T13:48:54.037600Z

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

thheller 2021-02-22T13:51:49.038500Z

you can't optimize this further

thheller 2021-02-22T13:52:53.038700Z

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

thheller 2021-02-22T13:53:14.038900Z

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_ 2021-02-22T13:55:27.039100Z

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

takis_ 2021-02-22T14:19:19.040500Z

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

joelkuiper 2021-02-22T14:19:28.040800Z

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

takis_ 2021-02-22T14:20:00.041500Z

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

2021-02-22T14:23:35.041600Z

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

2021-02-22T14:24:44.041800Z

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_ 2021-02-22T14:25:41.042Z

ok thank you , i didnt know that

emccue 2021-02-22T14:37:02.042700Z

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

emccue 2021-02-22T14:37:26.043200Z

only optimize stuff when it gets to be too slow empirically

emccue 2021-02-22T14:37:38.043500Z

not when you think it might be too slow hypothetically

takis_ 2021-02-22T14:41:33.044200Z

they can be many of them , like thousands

takis_ 2021-02-22T14:47:43.045700Z

i think this is the code

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

joelkuiper 2021-02-22T14:48:02.045800Z

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

ghadi 2021-02-22T17:36:17.047200Z

I would not modify that 🙂

flowthing 2021-02-22T17:52:09.047700Z

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

Yehonathan Sharvit 2021-02-22T19:12:34.049400Z

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 Sharvit 2021-02-22T19:12:43.049600Z

Example of usage:

Yehonathan Sharvit 2021-02-22T19:13:05.049800Z

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

Yehonathan Sharvit 2021-02-22T19:14:20.050100Z

And in JavaScript

Yehonathan Sharvit 2021-02-22T19:14:50.050700Z

m.a.b[0].c.d // 1

Yehonathan Sharvit 2021-02-22T19:19:36.051300Z

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

pithyless 2021-02-22T19:33:15.052800Z

@viebel prior art? :] https://github.com/wilkerlucio/js-data-interop

Yehonathan Sharvit 2021-02-22T19:36:35.053600Z

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

Yehonathan Sharvit 2021-02-22T19:39:57.055100Z

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

❤️ 2
p-himik 2021-02-23T08:25:58.062200Z

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 Sharvit 2021-02-23T13:35:39.062800Z

what’s IEncodeJS?

p-himik 2021-02-23T13:41:50.063Z

It's from the clj->js implementation:

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

wilkerlucio 2021-02-22T19:42:20.055400Z

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 Sharvit 2021-02-22T20:00:24.055700Z

Hacking a bit with js-data-interop

Yehonathan Sharvit 2021-02-22T20:00:46.055900Z

It doesn’t work with string keys in maps

Yehonathan Sharvit 2021-02-22T20:00:53.056100Z

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

p-himik 2021-02-22T20:03:25.056400Z

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

Yehonathan Sharvit 2021-02-22T20:33:57.057100Z

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

👍 1
takis_ 2021-02-22T21:45:55.058400Z

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