Fork me on GitHub
#beginners
<
2018-02-25
>
nakiya10:02:37

Very new to clojure/clojurescript and working on my first exercise I have a problem concerning re-com and reagent rendering. I have this view function (using re-frame):

(defn tile-test []
  (let [dim 2]
    [v-box
     :children
     (for [i (range dim)]
       [h-box
        :height "100px" :width "100%"
        :children
        (for [j (range dim)]
          (let [num (+ (* i dim) j)]
            [title :label num :level :level2 :style {:flex "1 1 flex !important"}]))])]))
But when rendered, 1 1 flex !important for :flex value is replaced with 0 0 auto. I can’t figure out what goes wrong here. Trying to debug clojurescript is a pain also - perhaps I’m not doing it right. I’ve been stuck for a while here. Any help is appreciated.

justinlee16:02:44

@duminda I think it is because “1 1 flex” is an invalid flex-basis. you probably want “1 1 auto”. you really shouldn’t need the “!important”

Wilfred10:02:38

I've written a little 'does this map contain another?' function

Wilfred10:02:37

(defn map-contains
  "Does `m` contain at least the keys in `min-keys` with a value of at
  least the value in min-keys?"
  [m min-keys]
  (loop [min-keys min-keys]
    (cond
      ;; Base case: we've exhausted min-keys.
      (empty? min-keys) true
      ;; If the value in m for this key is less, we're not included.
      (let [[c count] (first min-keys)]
        (< (get m c 0) count))
      false
      ;; This key is fine, check the rest.
      :else (recur (rest min-keys)))))

Wilfred10:02:59

Is this good style? Any feedback for a newbie? 🙂

Wilfred11:02:03

I suppose map-contains? is a better name

joelsanchez11:02:17

it's very good but you could use reduce

joelsanchez11:02:17

test cases:

cljs.user=> (map-contains {:a 1 :b 2} {:a 1 :b 2})
true
cljs.user=> (map-contains {:a 1 :b 2} {:a 1 :b 3})
false
cljs.user=> (map-contains {:a 1 :b 3} {:a 1 :b 3 :c 1})
false

joelsanchez11:02:28

that being said, the name is very counterintuitive, since it does a comparison of the vals and assumes they are numbers

Wilfred11:02:02

neat, I've not seen reduced before. Thanks 🙂

Wilfred11:02:31

ooh, actually, reduced reminds me of every?. Therefore this works too:

Wilfred11:02:16

(defn map-contains
  [m min-keys]
  (every? (fn [[k v]] (>= (get m k 0) v)) min-keys))

joelsanchez11:02:11

yep, that version is definitely better than reduce 🙂

Wilfred11:02:59

one more question about maps: is there a nice way of incrementing a single value?

Wilfred11:02:03

(let [some-map {:a 1 :b 2}]
  (assoc some-map :a (inc (some-map :a))))

Wilfred11:02:10

this feels rather repetitive

joelsanchez11:02:08

sure

cljs.user=> (update {:a 1} :a inc)
{:a 2}

joelsanchez11:02:43

also:

cljs.user=> (update-in {:a {:b 1}} [:a :b] inc)
{:a {:b 2}}

Wilfred11:02:34

aha, update is what I want. I found update-in but that seems less useful when you're only interested in a single key.

feihong14:02:35

I need to make a large number of http requests and then merge the results into a large map at the end (order is important). However, to save time I would like downloads to proceed in parallel (say, two simultaneous downloads at a time). Is core.async the right way to go here? If so, is there a good example for this use case?

feihong14:02:05

Hmmm, maybe using with-connection-pool in clj-http would be the right way to go?

gklijs16:02:17

I think do. Most http libraries are async by default. Did some cljs pet project before, where 8 http request needed to be combined, which was quite easy. So I guess with a pool of 2 you get what you want.

noisesmith16:02:53

@feihong.hsu core.async is useful for coordinating asynchronous data, but there are gotchas for using it directly for parallelism - a good rule of thumb is to put your IO or CPU heavy code in core.async/thread and then use the channel returned by thread

noisesmith16:02:53

or if your http library has a switch for async, you can use core.async in the callback to simplify coordinating all the data as it's available

orbjet16:02:58

hi i'm trying to figure out one clojurekoans task: how to evaluate this? (= 25 ( __ (fn [n] (* n n)))) thx 🙂

joelsanchez16:02:15

(= 25 ((fn [f] (f 5)) (fn [n] (* n n))))

noisesmith16:02:29

@shulc_ what you need is a function that accepts a function, and returns 25

mfikes16:02:29

Or, more generally accepts anything an returns 25? 🙂 Perhaps (constantly 25)

orbjet16:02:31

it was a bit puzzling but @joelsanchez @noisesmith got it 😄

mfikes16:02:07

In http://www.4clojure.com (a great learning resource), you can see others' solutions, and it is interesting how often the solutions are "cheats" 🙂

noisesmith16:02:35

the cheat solution here could be (constantly 25) for example

noisesmith16:02:02

I'd argue even the cheat would show that understand the thing the lesson is asking for though

orbjet16:02:28

i guess cheat is one thing but to understand why is another

noisesmith16:02:58

user=> (map (constantly 25) [0 nil inc {} "hello"])

noisesmith16:02:58

(25 25 25 25 25)

derpocious20:02:16

hey all, I'm having some trouble using cljs-http

derpocious20:02:30

I add it as a dependency in project.clj

derpocious20:02:46

:dependencies [[org.clojure/clojure       "1.8.0"]
                 [org.clojure/clojurescript "1.8.51"]
                 [org.clojure/core.async    "0.2.395"]
                 [io.nervous/cljs-lambda    "0.3.5"]
                 [cljs-http "0.1.44"]]
  :plugins [[lein-cljsbuild "1.1.4"]
            [lein-npm       "0.6.0"]
            [lein-doo       "0.1.7"]
            [io.nervous/lein-cljs-lambda "0.6.6"]]
  :npm {:dependencies [[source-map-support "0.4.0"]]}

derpocious20:02:01

and run lein deps

derpocious20:02:15

and then I want to call it from a function that I have, but call it from the repl

derpocious20:02:31

so I load it in my file

derpocious20:02:57

(ns jim-stuff.core
  (:require 
            [cljs.core.async :as async]
            [promesa.core :as p])
  (:require-macros [cljs.core.async.macros :refer [go]]))

derpocious20:02:07

and I try to use planck for cljs repl

derpocious20:02:13

with lein dependencies

derpocious20:02:38

planck -c $(lein classpath)

derpocious20:02:44

But it gives me this error

derpocious20:02:53

No such namespace: java.util.concurrent.locks.Lock, could not locate java/util/concurrent/locks/Lock.cljs, java/util/concurrent/locks/Lock.cljc, or JavaScript source providing "java.util.concurrent.locks.Lock" in file cljs/core/async/impl/ioc_macros.clj

derpocious20:02:24

Some strange java.util.concurrent.locks.Lock error

derpocious20:02:38

Why is it even trying to use java stuff for cljs?

gklijs20:02:59

Could be something going wrong with async, as cljs-http is also using it. Maybe because you only refer to go? I would take a look at the cljs-http source and how async is used in there.

derpocious20:02:09

hmm I am getting a warning, "unable to resolve get"

derpocious20:02:18

(go (let [response (<! (http/get ""
                                   {:with-credentials? false
                                    :query-params {"since" 135}}))]
        (prn (:status response))
        (prn (map :login (:body response)))))

derpocious20:02:51

I changed the core.async require to [cljs.core.async :as async :refer [<!]]

derpocious20:02:21

but I shouldn't need to specifically require http/get right?

mfikes20:02:06

@derpocious For self-hosted core.async see this port https://github.com/mfikes/andare

noisesmith20:02:20

@derpocious - to be clear, you need to refer to http at least (which I didn't see in your ns snippet)

mfikes20:02:19

@derpocious Also, if you happen to be targeting Planck, it has a built-in HTTP implementation. http://planck-repl.org/planck-http.html

derpocious20:02:07

@noisesmith sorry, I am requiring that too

derpocious20:02:08

[cljs-http.client :as http]

noisesmith20:02:42

OK - the other thing is that I thought it was called GET but I could be misremembering

derpocious20:02:50

@mfikes so I can use andare instead of cljs-http?

mfikes20:02:11

@derpocious No. Andare is a replacement of core.async for self-hosted

derpocious20:02:22

hmm it says unsable to resolve GET as well

mfikes20:02:38

@derpocious But, if you are using Planck (dunno if you are in the end), Planck has a built-in planck.http namespace you can use instead of cljs-http. And planck.http delegates to libcurl. I doubt cljs-http could work in Planck (I don't see how it would make outbound network requests.)

noisesmith20:02:39

that's very strange - it is actually get (I double checked)

derpocious20:02:55

hmm ok I need to look into this more. thanks guys 🙂

derpocious22:02:30

hey @mfikes, I still don't really understand what the point of planck.http is

derpocious22:02:04

I'm writing a cljs function that will be deployed to aws lambda which uses cljs-http

derpocious22:02:27

And I would like to try it out by calling it from a cljs repl, but you are saying I can't do that?

derpocious22:02:59

Is there a way to tell it to swap cljs-http for planck-http while I'm in the repl without having to change my code to deploy?

mfikes23:02:44

@derpocious If you want to make an outbound HTTP call (say, a get) from Planck, you can use planck.http

mfikes23:02:05

@derpocious Presumably your are not using Planck in your AWS, but some code that deploys onto Node?