When compiling a namespace that defines a function named binds a variable to eval
to JavaScript I get this warning:
WARNING - "eval" cannot be redeclared in strict mode
I would have expected that either --compile-opts '{:output-wrapper true}'
or --compile-opts {:rename-prefix "…"}
would resolve this, but it doesn’t seem to. Is there another way, or do I have to rename the Actually, seems like it’s a let
-bound variable named eval
that triggers the warning.
How can I
{:on-click (fn [e] (gc/toggle node "invisible"))}
specify the node that is being clicked upon?(.. e -target -value)
is kinda in the ballpark... not sure if that's the thing
I basically want to create a "flip" effect that hides one div and shows another (sibling) div
naturally when you overwrite an indigenous function name there will be a warning. do you want the warning to not happen?
I would recommend renaming the variable to some other word that isn't a special word, but i'm not an expert.
(. e -target)
did the trick
I notice that the clojurescript version of hash floors and floating point numbers and then just treats them as ints. This is different to the behavior in clojure which is a little annoying. https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core.cljs#L1012
So #?(:cljs (is (= (hash 1.2) (hash 1.3))))
yet #?(:clj (is (not= (hash 1.2) (hash 1.3))))
I get that hashing stuff with floating point numbers in them is probably generally not a great idea but would be nice for my particular case. I am compiling clojure forms to shaders and triggering hot reloads if they change and have been using hash
on the new and comparing it to the stored hash of the old to see if things need replacement. Works great unless I try to change a float ever so slightly.
Any recommendations on how to go about things? It would be nice to use the built in hash. It won’t take that long to write my own special hash but I would prefer to rely on core for this kind of thing.
don't use the hash
to compare stuff 😉
hehe noted. I wouldn’t normally but its dev tooling so I can tolerate the low collision chance. Doing a full new form to old form =
hurts the hot reload speed since right now my relevant def
macro does the comparison and so the general shadow-cljs hot reload does not get finished until all those macros get done. It can be a little too slow if the file I edit is required in a bunch of other places.
I could conceivably push my shader hot reload stuff to a queue and async process that after the shadow-cljs hot reload is done but I’d still like the actual compare to be reasonably performant
don't know how you are doing stuff but if its a macro you could have that compute something based on the form that you store alongside the output
yeah thats how it is currently done with hash as the function computes what I store alongside the output
works great unless I want to change a 1.2 to a 1.3. Though that works fine in the clojure version of my project.
maybe just pr-str
the form and md5 it or so. no clue what you are doing exactly 🙂
oh yeah, good idea. thats a quick alternative.
(my-md5 (pr-str form))
is quite a bit slower that (hash form)
when I just test a bit in the repl. That being said they are both pretty fast in absolute terms so i’ll just have to see how it feels in my workflow.
If the forms are compared within the JVM process, comparing the results of pr-str
might be faster, because md5
consumes the whole string either way.
But then comparing the forms themselves should be even faster, but you say that it's slower.
I’m looking at some code I wrote a good while ago so I am just relying on some notes I wrote at the time that say that comparing the forms was slow though I will double check now.
also I checked my macro magic and I am doing the actual compare in the browser. I am only hot reloading my shaders when I am developing so it is unnecessary to compute and store anything during compilation.
Sorry for the lack of clarity! Trying to explain a little part of of a larger thing without bringing in too many unnecessary details.
> I am doing the actual compare in the browser. Can it be done in the JVM process?
Without sending anything, I mean.
potentially. The macro would probably have to do the computes and store to metadata. Then the runtime bit of things would just compare old and new and call the hot reload “hook” if they are different.
and =
is like 300 times slower in my tests in both clj and cljs. I was testing under the assumption that things are most likely equal which I assume is worst case of the =
function. And that the old and new form don’t “share” anything between them which I don’t know if is true or not.
Any tips on how I can make one 2 divs, one default hide, one default show, and click to switch that?
Do you use any UI library? If so, it's better to ask in the appropriate channel, e.g. #reagent for Reagent.
Thanks. I am using rum. I managed to figure it out! ^_^ keeping a local state and toggling between -1 and 1 via #(* -1 %)
I was about to suggest Element.classList.toggle
🙂
I tried to do toggle but i have 2 elements. so rather than toggle them both i have one local atom and if its value is -1 one class is conditionally set, if it's +1 the other class is conditionally set
obviously doesn't matter in most cases, but changing class attribute on 2 elements is a lighter operation for the browser than adding/removing two elements
wait, I got confused, you are not removing elements, but I don't quite understand, if you are generating your html, how does that work, what is the mechanism that changes the class? is it's react or something?
using +1 and -1 is a bit odd, why not true/false and toggle with not
?
or even better, name the states something meaningful and toggle between them with a map: eg. (swap! state {:dark :light, :light :dark})
, you can do any number of "state transitions" this way
it might be good to have multiple states... i don't understand the line (swap! state {:dark :light, :light :dark})
@ashnur i'm using Rum
[:div.thang {:class (if (= -1 @visibility-atom) "invisible")
:on-click (fn [e] (swap! visibility-atom #(* -1 %)))}
It's like a fake "flip to see the back of this div" but really it's not the back, it's just another div, and i hide one and show one depending on the value of @visibility-atom via the if
statement in the :class
attribute
@qythium maybe you could elaborate on your mini state machine there
say I want to have 3 modes instead of 2
say you have 3 states, using keywords :a :b :c
to denote them
(def *state (atom :a)) ;; initial
(def transitions {:a :b, :b :c, :c :a})
This would cycle between all 3 states
(swap! *state transitions)
well that's cool and pretty mind-blowing
love it
Yup, the "maps/sets/keywords as functions" idiom is quite powerful if you get used to it 🙂
super cool!
note that you might want to guard against invalid states by using #(get transitions % <default>)
, or using case
which throws an error #(case % :a :b, :b :c, :c :a)
Ah that is helpful, to have a fall-back...
I actually use case
most of the time for these things, it's better to catch errors early than have a nil
cause damage down the line
sure. easier to pinpoint the leak
clojure is so awesome. that's maybe the simplest code ever for a working state machine.
the list of states is also a function for advancing states... brilliant and beautiful
thanks for your help everyone, i got a lot done this morning ^.^
Hi, I need some help with tooling. I have a web app with a ring-backend in clojure and a reagent frontend in clojurescript. I am using cursive with leiningen. I can run my frontend through figwheel and develop with code-reloading, and I can use the lein ring plugin to run the backend with code reloading. I have found bits and pieces on the figwheel home page / github wiki, but everything either assumes that I am either using deps.edn instead of leiningen is using outdated APIs.
Edit: What I am trying to do is run them both in tandem: Backend and Frontend, possibly with code reloading/ a REPL on either side
fwiw, before shadow-cljs and deps.edn became a thing, I was unable to adopt clojure because both lein and boot were way outside of what I could reach with respect to my time and other constraints. 7 years I knew about clojure but had no way in. I was limited to using cljs packages compiled to js.
@mail185 shadow-cljs is great and might be just the ticket https://shadow-cljs.github.io/docs/UsersGuide.html
how do people do interop w/ js promises in cljs these days? I see promisea, and the <p! macro w/ core.async... but what's idiomatic?