Fork me on GitHub
#clojurescript
<
2018-03-15
>
benzap01:03:37

So what's the word on clojurescript 1.10*? I found out that i'd been using the preview for a while, and there hasn't been any official release notes yet

benzap01:03:28

so far, nothing seems to be broken since I bumped the version, just minor issues with cljs.devtools not understanding how to format the new MapEntry type

benzap01:03:40

I'm guessing all of the major tooling will follow suit with minor fixes

mfikes02:03:44

@benzap Bugs are being resolved in 1.10.x prior to release

qqq04:03:29

I have a piece of code that looks like this:

(defonce main-atom
  (rc/atom
   [:svg {:width "100%"
          :height "100%"}
    [:text {:x "100" :y "100"} "waiting for data"]]))


(defn main-gui []
  @main-atom)

(defonce ttl-count (atom 0))

(defonce tick-tock-a (atom (fn [])))

(defn update-text []
  (let [ms (last (str (js/Date.now)))
        v (mod @ttl-count 10)]
    (swap! ttl-count inc)
    (reset! main-atom
            [:svg {:width  "100%"
                   :height "100%"}
             [:text {:x 50 :y 50} ms]
             (for [y (range 100)
                   x (range 100)]
               ^{:key [x y]} [:text {:x (+ 100 v (* 10 x))
                                     :y (+ 100 v (* 20 y))}
                              ms])])))

(defn js-reload [& args]
  (update-text))

#?(:cljs
   (set! (.-onload js/window)
         (fn [& args]
           (ca/log "setting up timeout")
           (js/window.setInterval (fn []
                                   (ca/log "update func called")
                                   (update-text))
                                 10)
           (ca/log "done setting up timeout")
           (rc/render [main-gui]
                      (.getElementById js/document "app")))))

where I try to, at 100fps, redraw 100x100 text nodes every frame I'm only getting around 2-3 fps on my 3-year old macbook pro in Chrome. Should I accept this as a fundamental limitation / slowness of SVG ?

qqq06:03:25

@lukewallace1990: try this, copy that function into clj, eval it, then eval (new-board 3) and you should be able to see what it is outputting; the "B" probably stands for "blank" (just guessing)

rauh08:03:58

@qqq A nested for like that will be very slow since it's fully lazy. Also your :key will have to be converted to a string "[x y]" which is slow.

miikka09:03:37

Are infer warnings expected to work?

dnolen10:03:40

they don’t work higher order

dnolen10:03:51

and there’s no plans to make that work

miikka10:03:15

i can't even get warnings for the wrap-baz example here: https://clojurescript.org/guides/externs#externs-inference

dnolen10:03:20

they exist only to catch obvious mistakes

dnolen10:03:41

oh infer externs

dnolen10:03:58

didn’t know you were talking about that

dnolen10:03:03

yes it should work

miikka10:03:01

Oh, I see somebody else is having the same problem: https://dev.clojure.org/jira/browse/CLJS-2491

dnolen10:03:43

hrm I missed that ticket, bumped it to get fixed in the next release

dnolen10:03:04

we have a bunch of tests for this - so probably something subtle

maridonkers12:03:35

Works in Clojure but not in ClojureScript:

(defn ^{:doc (:doc (meta #'defn))} doc-string-copy [a b c])
. Is there a way to accomplish this in ClojureScript?

john12:03:45

You might have to use meta-fn... ClojureScript's vars are a little thinner than Clojure's. (at runtime)

john12:03:00

meta-fn can slow things down a bit though.

john13:03:27

If you're not getting bit by the runtime var thing, it might be something else. But that's a hunch.

dnolen13:03:18

var stuff should be avoided in ClojureScript except for a very small number of documented cases

dnolen13:03:28

the dynamic stuff from Clojure will never be supported

dnolen13:03:02

there’s in fact only one real valid supported use of vars at the moment

dnolen13:03:10

invoking across module boundaries when code splitting

maridonkers13:03:22

@john @dnolen Was thinking about defining a wrapper function around another function and automatically copying the wrapped function's docstring. This also doesn't work:

(def ^{:doc (str "A docstring.")} doc-string-copy (fn []))
with the same exception:
clojure.lang.PersistentList cannot be cast to java.lang.CharSequence
But it's not a problem not having it (only wondered if there was a workaround).

dnolen13:03:42

none of those things are going to work

dnolen13:03:53

you cannot have runtime stuff in the var meta at all

dnolen13:03:00

only static values, no fn calls, no macros etc.

maridonkers13:03:09

No problem, I'll copy the docstring manually. Thanks for the feedback.

Ryan Radomski13:03:03

I believe you can do the function wrapping at macroexpansion time

Ryan Radomski13:03:24

don't quote me on that, may be worth looking into

maridonkers14:03:37

Unquoting 🙂 Thanks, will check it out.

borkdude13:03:48

In cljs, if you use the call to goog.string.format like this: (gstring/format "%05d" 123) do you still need to include both:

(ns example.core
  (:require
    [goog.string :as gstring]
    goog.string.format))

dnolen14:03:35

if goog.string.format is in a different file, then yes

pesterhazy14:03:44

Are there docs for reify, specify, specify! as they apply to ClojureScript? I'm wondering if there's a more elegant way to extend React.Component than https://gist.github.com/pesterhazy/39c84224972890665b6bec3addafdf5a

rauh14:03:30

@pesterhazy Why not goog/inherits ?

pesterhazy14:03:03

@rauh, did not know that existed

pesterhazy14:03:46

I was confused because it's not in the goog.object namespace. If anyone is reading along, it's defined here: https://github.com/google/closure-library/blob/master/closure/goog/base.js#L1877

pesterhazy14:03:09

I'll give that a try, thanks @rauh

bhauman15:03:04

I stole it from sablono

rauh15:03:51

@pesterhazy Yeah there are many ways to do it. You can even do js*:

(let [klass (if async? js/React.unstable_AsyncComponent js/React.Component)]
    (js*
      "class extends ~{} {
         constructor(props, context) {
           super(props, context);
           ~{}(this, props, context, ~{});
         }
      }" klass init-class init-fns))

bhauman15:03:14

It would be nice to have a tiny library that helps folks assemble JS classes, and by extension react classes

bhauman15:03:30

@rauh what's the ~{} refer to above?

bhauman15:03:08

oh interpolation

rauh15:03:09

@bhauman Those get replaced with the arguments: (js* "foo ~{} bar", 34) => "foo 34 bar"

bhauman15:03:25

that's a new one on me

rauh15:03:27

And will probably work with Strings, symbols, functions etc etc. Bascially any CLJS

pesterhazy15:03:56

Relying on js* sounds dangerous

mfikes15:03:12

@bhauman FWIW

cljs.user=> (macroexpand '(+ 1 2))
(js* "(~{} + ~{})" 1 2)

bhauman15:03:25

good to know

bhauman15:03:33

very good to know

mfikes15:03:26

@pesterhazy I agree. FWIW, David has indicated that he sees no reason to, for example, add warnings for code in the wild that uses js*. But yeah, it makes you wonder what might happen if js* actually ever changed in behavior.

mfikes15:03:44

It seems pretty stable now. 🙂

pesterhazy15:03:52

@mfikes it also changes the output version from ES5 to ES6... not sure if that's an issue anymore these days though

mfikes15:03:37

@pesterhazy What changes the output version?

pesterhazy15:03:52

@mfikes using class via js*

mfikes15:03:24

Oh, you mean the code above is emitting ES6 code.

pesterhazy15:03:44

yes, that's a 100% more elegant way of putting it 🙂

mfikes15:03:24

Yes. You probably have to set :language-out if you do that

dnolen15:03:38

all that stuff is just sugar over stuff that Google Closure can do

dnolen15:03:56

ES6 classes desugar into old stuff that works everywhere

dnolen15:03:04

so I don’t really see the point

dnolen15:03:32

and if you want to write JavaScript just write write JavaScript

dnolen15:03:39

and require it

pesterhazy15:03:06

@dnolen would you suggest using goog/inherit to extend React.Component?

dnolen15:03:07

if we change js* to only work from cljs.core and it breaks your stuff, don’t come complaining

dnolen15:03:24

many FP compile JS don’t have a sensible way to include JS in the build

dnolen15:03:27

we do not have the problem

dnolen15:03:38

use the stuff you have

dnolen15:03:22

om.next just uses goog/inherit

dnolen15:03:25

works fine

dnolen15:03:59

the one place I used js* was to hack in Closure @nocollapse

dnolen15:03:09

but that just something that needs to be supported directly

dnolen15:03:17

if you use js* you deserve what you get

dnolen15:03:24

you have been warned 🙂

mfikes15:03:41

js* is to ClojureScript as asm is to C, but with non-guaranteed semantics, or even existence 🙂

sh4z17:03:23

is there a more idiomatic way to do this?

john19:03:50

Has anyone noticed chrome opening external debug windows for service workers (I think coming from youtube), when the browser reloads after a watched recompile?

john19:03:43

Probably only happens when you have a youtube embed on the page

Steve C21:03:12

Hey all. I know clojure well and nothing about javascript - hoping someone can help me solve a problem I ran into. I wrote a library in clojurescript and compiled it into javascript. I'm trying to incorporate it into an existing react app using es6 modules. I'm having problems importing the google closure file that I generated.

bhauman22:03:58

@steve476 you probably want to compile using :optimizations :simple or :whitespace and make sure you tag the defn names with ^:export so you can access them from javascript.