This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-05-02
Channels
- # aws-lambda (5)
- # bangalore-clj (1)
- # beginners (96)
- # boot (66)
- # cider (39)
- # cljsjs (2)
- # cljsrn (5)
- # clojure (265)
- # clojure-android (1)
- # clojure-france (1)
- # clojure-greece (32)
- # clojure-italy (4)
- # clojure-russia (2)
- # clojure-sg (1)
- # clojure-spec (27)
- # clojure-uk (25)
- # clojurescript (88)
- # cursive (4)
- # datomic (31)
- # emacs (96)
- # hoplon (10)
- # immutant (14)
- # jobs (2)
- # luminus (1)
- # lumo (66)
- # off-topic (128)
- # om (8)
- # om-next (2)
- # onyx (9)
- # parinfer (5)
- # re-frame (37)
- # reagent (16)
- # rum (9)
- # schema (3)
- # specter (34)
- # unrepl (8)
- # yada (21)
@souenzzo What about breaking it apart. (namespace :newman/john) ;=> "newman"
and (name :newman/john) ;=> "john")
and then just string them together?
@john right. I can do, but it's really needed to create a new function to generate keys and overwrite the default one from clj->js...
you should use some kind of serializer for your case, something like transit, where you can plug your own writer for keywords.
@souenzzo Haven't tested this, but you could try something like
(defn my-clj->js
[x]
(when-not (nil? x)
(if (satisfies? IEncodeJS x)
(-clj->js x)
(cond
(keyword? x) (str (namespace x) "/" (name x))
(symbol? x) (str x)
(map? x) (let [m (js-obj)]
(doseq [[k v] x]
(aset m (key->js k) (clj->js v)))
m)
(coll? x) (let [arr (array)]
(doseq [x (map clj->js x)]
(.push arr x))
arr)
:else x))))
;modified cljs, Copyright © Rich Hickey ;)
or check to see if the keyword was passed in namespaced and do it then? Not sure if there's a namespaced?
check
@souenzzo sorry, got another repl up to test it. You'll need:
(declare my-clj->js)
(defn my-key->js [k]
(if (satisfies? IEncodeJS k)
(-clj->js k)
(if (or (string? k)
(number? k)
(keyword? k)
(symbol? k))
(my-clj->js k)
(pr-str k))))
(defn my-clj->js
[x]
(when-not (nil? x)
(if (satisfies? IEncodeJS x)
(-clj->js x)
(cond
(keyword? x) (str (namespace x) "/" (name x))
(symbol? x) (str x)
(map? x) (let [m (js-obj)]
(doseq [[k v] x]
(aset m (my-key->js k) (my-clj->js v)))
m)
(coll? x) (let [arr (array)]
(doseq [x (map my-clj->js x)]
(.push arr x))
arr)
:else x))))
All slightly modified cljsThough, if you're round-tripping data with other tools, you may be breaking contracts by changing this behavior.
if I'm writing a mobile ios app in html/cljs, is the best debugging approach to have the ipad run safari, then run safari on the desktop and debug that way? or is there something better [generally, I prefer to debug inside chrome]
I'm seeing a performance problem with clojurescripts defmulti. Specifically, dispatch is slow when there is no match for the dispatch value.
It seems to be proportional to the number of defmethods hooked up.
@olivergeorge it usually is just a map lookup so it shouldn't make a difference?
(defmulti exp1 :type)
(defmethod exp1 :default [x] x)
(dotimes [n 10] (defmethod exp1 n [x] x))
(time (dotimes [n 100] (exp1 {})))
"Elapsed time: 14.655000 msecs"
(dotimes [n 100] (defmethod exp1 n [x] x))
(time (dotimes [n 100] (exp1 {})))
"Elapsed time: 81.760000 msecs"
(time (dotimes [n 100] (exp1 {:type :default})))
"Elapsed time: 0.460000 msecs"
@thheller looks like it has to scan through all possibilities in the method-table and isa? takes a lot of time
Three examples there. The first two show relation to number of dispatch methods. The final one shows that it's specifically a "miss" that shows a performance penalty.
Same between optimisations :none and :advanced
Not repeatable on clj
I wondered if the caching was intentionally not done on "misses" for fear of a memory leak. Not trivial to scan the code and understand.
In my app it's a x8 penalty happening a heap in a tight loop which sucks.
I could see a potential optimization that kicks in if the hierarchy is manually set to (atom nil)
I'll scan JIRA for related tickets since CLJ can handle it better it might be worth fixing.
@rauh tell me if it changes those numbers... a quick win would be awesome.
@thheller do you think this is worth adding a JIRA ticket for?
In case anyone is interested: https://dev.clojure.org/jira/browse/CLJS-2020
@olivergeorge Not battle tested:
(set! cljs.core/find-and-cache-best-method
(fn find-and-cache-best-method
[name dispatch-val hierarchy method-table prefer-table method-cache cached-hierarchy]
(let [hier @hierarchy
use-isa? (not (empty? (:ancestors hier)))
best-entry (if use-isa?
(reduce (fn [be [k _ :as e]]
(if (isa? hier dispatch-val k)
(let [be2 (if (or (nil? be) (dominates k (first be) prefer-table hier))
e
be)]
(when-not (dominates (first be2) k prefer-table hier)
(throw (js/Error.
(str "Multiple methods in multimethod '" name
"' match dispatch value: " dispatch-val " -> " k
" and " (first be2) ", and neither is preferred"))))
be2)
be))
nil @method-table)
(get @method-table dispatch-val))]
(when best-entry
(if (= @cached-hierarchy @hierarchy)
(do
(swap! method-cache assoc dispatch-val (second best-entry))
(second best-entry))
(do
(reset-cache method-cache method-table cached-hierarchy hierarchy)
(find-and-cache-best-method name dispatch-val hierarchy method-table prefer-table
method-cache cached-hierarchy)))))))
@rauh Thanks, I'll try it out.
something of a noob question here: I'm using reagent and ant.design, using their Collapse and Collapse.Panel react components … I'm not sure how to persist the panel's collapsed state into reagent. Right now each figwheel update causes all the panels I've expanded to collapsed again
@hagmonk can you link to the docs/source of the component?
… and github … https://github.com/ant-design/ant-design/tree/master/components/collapse
(I literally knew nothing about react until a few days ago, apologies if this is super obvious)
@hagmonk it looks like it doesn't support persisting the state
there would have to be a prop like collapsed
that gets passed in
I might be looking in the wrong place though
I'm just learning cljs, but know react pretty well. @pesterhazy is right there, there's no state at all in that component https://github.com/ant-design/ant-design/blob/master/components/collapse/index.tsx#L28
so they have activeKey on the Collapse and key on the Panel … but weird things start happening when I try to set those manually
honestly it doesn't speak to the quality of the whole framework if such a basic feature is not supported
I'll take recommendations for other UI frameworks 🙂 My goal is to avoid doing much design work on this prototype, so something like ant was appealing because of how much ground it covered
yeah, not sure what to recommend
I'd look into reactstrap (bootstrap) perhaps
Completely different question: is there a way to specify the initial namespace using figwheel?
another popular one is material-ui (which is material design). and palantir's blueprintjs, but i think that one has fewer components.
I like to have a repl ns around for simple utility functions - and that ns should only be required in figwheel sessions, not prod builds. Ideally figwheel should start in that ns too
@hagmonk I'm also building something with reagent and ant design. Is it similar to the way their Menu/Menu.Item works, where you give each one a key and the parent gets a list of what keys are open?
Here's an example that works for me through figwheel updates:
(defonce which (r/atom "one"))
(defn panel []
[Collapse {:accordion true
:activeKey @which
:onChange #(reset! which %1)}
[Collapse-Panel {:key "one" :header "First"}
"First panel"]
[Collapse-Panel {:key "two" :header "Second"}
"Second panel"]
[Collapse-Panel {:key "three" :header "Third"}
"Third awesome panel"]])
I've had a great time with ant so far!
You'll need to persist the state of which key is active somewhere - either a ratom, or wherever you're storing your app's data.
I'm subscribing to the response of calling auth/login
via a pub/sub system I have set up
And I am calling (done)
when I am done my assertions in the callback for my subscription
My understand is that I want to call done
when all of my assertions have been run, to tell the test runner to move on to the next test
@ksmithbaylor oh that's interesting, thanks for that. I think one difference might be that activeKey is an array for this component
@ksmithbaylor but I'll hack on it some more now and see how it goes
I have a few string parameters that I want to pass from my server (Django templates) to the clojurescript app. In Elm there is a way to pass parameters to initialize an app. I don’t see this pattern in any of the tutorials or docs for cljs (that I’ve found). Is there a standard way to bootstrap a cljs app with parameters after the document has loaded?
@hagmonk I think you can pass either an array or a single string
you could easily do [@which]
instead though
@ksmithbaylor I got it working with the code you provided. Very cool! It didn't occur to me that the onChange handler needed to be implemented … I guess I assumed there was some kind of internal state tracking in the component itself for that
@hagmonk There may be some internal state, but you have to use the onChange
handler to make it "external" so your app can use it
It's pretty common if a component has internal state to expose it via a callback like onChange
, etc
@hagmonk on a related note, I made a macro to help me more easily use antd components from Reagent: https://gist.github.com/ksmithbaylor/86c5459be2a7c84b438975487b3818f1. You may find it useful. I'm fairly new to Clojure myself, so there may be a much better way to do this.
@ksmithbaylor thanks!!
@ksmithbaylor I'll look in more detail later, but I think a better approach might be to create a namespace, then use tools.namespace simply enumerate all the components in js/antd, def'ing them up in your namespace wrapped with adapt-react-class
there's some sample code for that I have floating around that i know for sure works with Java interop stuff I've been working on
See the very bottom of https://github.com/mcohen01/amazonica/blob/master/src/amazonica/core.clj
And also see their aws/* namespaces which are empty apart from a call to set-client that interns all the symbols
Oh one more thing. Reagent has a special hiccup syntax such that you can do: [:< antd.Collapse.Panel {:stuff “this”}]
The downside being it’s a bit of an eyesore if used everywhere. The upside being it calls adapt-react-class
and everything for you.
@hagmonk nice! I didn't know about tools.namespace. And thinking about it now, I definitely did too much work with that macro 😄 I think I was just excited about trying a macro. I'll take a look and see if there's a more idiomatic way to do it.
Oh yeah, it's totally natural to write a bunch of macros then discover they aren't strictly needed … that's part of the journey towards judicious use of macros 🙂
@olivergeorge I can see the same slowdown as you, roughly two orders of magnitude
yeah, it's a killer if you use defmulti as an extension point but rely on default behaviour most of the time.
That seems like a pretty common use case.
@danielcompton thanks for verifying