Fork me on GitHub
#clojurescript
<
2016-04-03
>
kingoftheknoll03:04:51

is there a boolean check similar to map? for js objects?

kingoftheknoll04:04:17

(= (type @a) js/Object)

kingoftheknoll04:04:25

I’ll try object?

kingoftheknoll04:04:00

yup object? thanks!

kingoftheknoll04:04:39

do you know of a site that lists all the cljs specific functions? I haven’t found one yet

rauh09:04:40

@tomraithel: clj->js does NOT somehow return the underlying array but copies the elments into a JS array.

rauh09:04:01

So that is done here twice. And in js [0] == [0] is false.

tomraithel09:04:24

@rauh: hmm ok, but i thought that the instances within the copied array are shared and arrays are not "deep-copied"... I wanted to try ClojureScript as a replacement for my reducers in react/redux but as if it really always deep-copies an element on clj->js then I think it would be pretty inperformant

triss14:04:35

how would you guys go about's throttling a mouse move event so only the most recent one got through?

triss14:04:50

I'm using re-frame...

triss14:04:11

but this little job feels like core.async to me?

pauldelany14:04:39

@triss - i'm not experienced in re-frame / reagent (yet ;) ) but your question reminded me of this linked off the docs somewhere - seemed relevant: https://gist.github.com/staltz/868e7e9bc2a7b8c1f754

grav15:04:47

@triss:

(defn throttle [f]
  (let [state (atom nil)]
    (fn [& args]
      (when-let [id @state]
        (js/clearTimeout id))
      (let [id (js/setTimeout #(apply f args) 1000)]
        (reset! state id)))))

grav15:04:50

it takes a function and returns a new, throttled version of that function, that waits a second to see if it’s called again, before returning its output

grav15:04:14

Eg

(def throttled-on-click (throttle (fn [e] (swap! atom assoc :foo 42)))

grav15:04:20

Oh, btw, the above has no dependencies to reframe. I’m using it with reagent, and it could be used with pure react as well.

nberger16:04:51

@triss @grav I'd go the throttle way too, but with React event handlers (as it seems to be your case) your have to be careful with React event pool: the event is recycled unless you call .persiston it, so if you want to access properties from the event (the first element of args there) you have t capture them first, or call persist

amacdougall17:04:58

I'm kind of confused about some doo stuff—maybe someone can steer me right. If I run lein doo chrome <build> once, I pop up a Karma window and run the test (a simple (= 1 1) sanity check right now). I get this output. Not sure if the warning is relevant.

;; ======================================================================
;; Testing with Chrome:

03 04 2016 13:00:30.925:WARN [web-server]: 404: /js/compiled/admin-test/out/cljs_deps.js
LOG: 'Testing raiseyourgame.core-test'
Chromium 44.0.2403 (Ubuntu 0.0.0): Executed 1 of 1 SUCCESS (0.062 secs / 0.046 secs)
But if I run lein doo phantom <build> once, I get this:
;; ======================================================================
;; Testing with Phantom:

ClojureScript could not load :main, did you forget to specify :asset-path?

ERROR: doo was not loaded from the compiled script.

Make sure you start your tests using doo-tests or doo-all-tests
and that you include that file in your build

Subprocess failed

amacdougall17:04:36

Exact same project.clj, same runner, same test file. I also found that the same thing is true of Firefox vs Slimer: Firefox works, Slimer gives the same error as Phantom. The phantomjs binary is installed, and passes the "hello world" example on Phantom's own homepage. lein doo phantom test once is working when I set up a new chestnut project, so I'll compare and contrast... Update: The phantom runner worked after I removed :asset-path and :output-dir from my "admin-test" cljsbuild. I have no idea why, and although I am curious in principle, I think the mental effort involved in figuring it out would be better spent writing a cautionary comment and moving on with my app.

grav17:04:28

@nberger: Interesting, I didn’t know about that, or .persist for that matter!

nberger17:04:17

@grav yeah, I learned it the hard way :)

lwhorton17:04:08

this is a really easy question, but I’m not sure where to start to look for an answer because I’m not sure if my issue is syntax, semantics, or lazy-sequencing:

lwhorton17:04:47

(defn create-something [] (for …)) a for loop that creates a map returns nil (or just nothing) when invoked.

lwhorton17:04:19

however, if I assign the result of the for to a let [val (for …)] and end the fn with (val), it returns the generated values?

amacdougall18:04:05

If you end it with (val) instead of just val, you're attempting to invoke val as a function, with unpredictable results.

lwhorton18:04:27

sorry, not (val) more like … val)))

amacdougall18:04:45

Oh, in that case, I'm not sure why it would be different at all. Sorry.

amacdougall18:04:30

(defn foo []
  1)

(defn foo []
  (let [n 1]
    n))
If I understand you right, you're doing basically that, right?

lwhorton18:04:30

is this because for is lazy? it doesn’t say so in the docs… other mappers seem to explicitly state “returns lazy sequence”.

amacdougall18:04:57

I think for does return a lazy sequence, but just giving it a let binding shouldn't cause it to be realized.

lwhorton18:04:10

i’ll go quadruple check for stupid syntax errors and be right back...

amacdougall18:04:06

What do you mean by "a for loop that creates a map returns nil (or just nothing) when invoked"?

lwhorton18:04:47

s-expression parens strike again… sorry. a misplaced ).

amacdougall18:04:48

I guess you could create a map from a for loop by repeatedly associng stuff on it or whatever? But then it would just be a map.

amacdougall18:04:34

...I can't imagine what that would do, actually. If for gives you a lazy list, I guess you'd get a sequence of the states your map goes through with each iteration?

lwhorton18:04:45

just in case you’re interested, all I’m doing is making derived data without having to store the extra bits in a db by merging two vecs…

(defn create-people [users people]
  (if (empty? people)
    (for [user users] (assoc user :checked false))
    (for [user users person people]
      (if (= (:id user) (:id person))
        (assoc user :checked (:checked person))))))

amacdougall18:04:19

Oh, okay. You're making a list of maps, which is totally legit.

lwhorton18:04:42

i’m sure that’s not the best way to iterate (and it’s O n^squared), but I haven’t read enough of other’s code to find the cool tricks

amacdougall18:04:02

I am pretty sure that this will cycle through all people per user.

amacdougall18:04:42

You may want (for [[user person] (partition 2 (interleave users people))] here. Not sure.

lwhorton18:04:01

yea, I have no guaranteed ordering of the vecs, so I could sort them by id and then get this down to O n log(n) but w/e

lwhorton18:04:23

ooh partition and interleave, two new cool things to check out

amacdougall18:04:44

Yeah, run this in your REPL:

(for [x (range 0 5)
      y (range 100 105)]
  [x y])
Just to verify that your code is doing what you really intended. As written, you're generating one user per unique user-person combination.

lwhorton18:04:44

it works as expected, just checked… really wish boot worked with vim-fireplace and ncider. really tired of copy/pasting

amacdougall18:04:47

I don't know the application, so maybe that's totally right!

juhoteperi18:04:18

@lwhorton: What problem do you have with boot + fireplace? Works fine for me (clj, cljs repl, everything)

amacdougall18:04:25

Would you like a setup where you can execute blocks of code from vim in any terminal application? I use the vim-slime plugin to send arbitrary text to tmux. This means you have to run your terminal in a tmux window, but if you're on OSX, I think vim-slime can also push to iTerm2.

lwhorton18:04:13

1) I have to manually :Connect to my repl each time and point it to the right port 2) it seems to barely be able to eval anything without crashing

amacdougall18:04:27

Then you can send code from vim to Pry, to the Python REPL, to Figwheel's default REPL, to bash itself...

juhoteperi18:04:00

Automatic connections should work just fine

lwhorton18:04:01

well I’m not using figwheel, which is the root of my problem currently @amacdougall. I’m using boot instead.

amacdougall18:04:27

Allow me to continue my sentence, then: "...to the boot REPL..." There, covered.

amacdougall18:04:44

With vim-slime, you can send arbitrary text for execution in any terminal app.

amacdougall18:04:17

If boot doesn't actually support a terminal REPL, then I'm out of ideas.

lwhorton18:04:28

hmm, let me pin that and take a look. great advice, thanks.

lwhorton18:04:35

@juhoteperi: how do you setup to connect automatically? I couldn’t find it anywhere in the docs, and in fact the first-line says Connecting to lein repl happens automatically. If you have a different setup, you can connect by hand.

juhoteperi18:04:16

Both lein repl and boot repl create the same .nrepl-port file on work dir so Fireplace doesn't need to care which one your are using

lwhorton18:04:17

I see, oh that’s great. I dont know what I was doing wrong yesterday but I can cpp from a new shell and it evaluates.