This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-02-22
Channels
- # beginners (55)
- # cider (22)
- # cljs-dev (123)
- # cljsrn (75)
- # clojars (1)
- # clojure (92)
- # clojure-europe (2)
- # clojure-italy (16)
- # clojure-nl (6)
- # clojure-spec (17)
- # clojure-uk (77)
- # clojured (2)
- # clojurescript (39)
- # core-async (8)
- # cursive (4)
- # data-science (1)
- # datomic (22)
- # duct (4)
- # editors (21)
- # emacs (10)
- # events (4)
- # fulcro (116)
- # graphql (8)
- # immutant (3)
- # jackdaw (1)
- # juxt (3)
- # kaocha (4)
- # luminus (1)
- # mount (1)
- # nrepl (32)
- # off-topic (34)
- # other-languages (5)
- # pedestal (32)
- # reagent (1)
- # ring (6)
- # ring-swagger (7)
- # shadow-cljs (5)
- # spacemacs (3)
- # specter (1)
- # sql (1)
- # vim (21)
I have an array of art pieces. I want to find the route length and associate it with each art pieces. My code will look like: (defn load-art-routes [art-list ctx] (doall (map-indexed (fn [index art] (let [user-location (select-keys (:coords (sub> ctx :geolocation)) [:latitude :longitude]) art-location (:geoLocation art)] (->> (map-request {:origin (str (:latitude user-location) "," (:longitude user-location)) :destination (str (:lat art-location) "," (:lon art-location)) :mode (name (sub> ctx :transition-mode))}) (p/map (fn [data] (let [route-length (ocall js/Math "round" (/ (get-in data [:routes 0 :legs 0 :distance :value]) (* 0.621371192 1000)) 2) route-duration (ocall js/Math "floor" (/ (get-in data [:routes 0 :legs 0 :duration :value]) 60))] (js/console.log "load-art-routes route-length " route-length") (assoc art :route-length route-length)))) (p/error (fn [error] (util/log (str "GOOGLE DIRECTIONS API ERRORS" params) error) ))))) art-list)) art-list) (defn map-request [params] (when params (let [endpoint google-directions-api-endpoint] (->> (make-get-req (str endpoint "&" (encode-query-params params)) {}) (p/map (fn [data] (util/log "GOOGLE DIRECTIONS API " data) data)) (p/error (fn [error] (util/log (str "GOOGLE DIRECTIONS API ERRORS" params ) error) )))))) The route length calculation is correct but, assoc is not working. It is not actually associating it. I don't know what the issue is. Can anyone help me?
you have a " too many in line (js/console.log "load-art-routes route-length " route-length")
, is that your problem? or a copypaste problem?
that is a copy pase problem. that is not real problem.
I'm trying a write a spec for this map to check its types, but I'm not exactly sure what the best way to spec a nested map is.
by writing another map spec
well, I did that, but I was confusing qualified and unqualified keys so spec/valid?
was returning false
Any issues I should be aware of with saving to multiple databases using pmap? Say we have a map that looks like
(def engines {:mongodb <mongodb connection> :postgres <postgres-db connection> :mariadb <mariadb connection>})
and I do something to the effect of (pmap <function that uses the connection to save to db> engines)
I'm unsure why that would be a problem, if you're using completely separate DB connections
If you were sharing a single DB connection to a single database, that might be a problem if your driver isn't threadsafe
Make sure you're prepared to handle any exceptions thrown by the save-function
What I am unsure is the exception handling. Since pmap uses futures under the hood and Ive come across situations where I wont see the exceptions until I try to deref the future. If an exception occurs in one save function will the process continue to other save functions?
How does semi lazy work? Will it save my data as its mapping or not until I try to consume the results?
It's a good question. I don't know the answer. But it might be worth writing code that behaves in exactly the way you want (and makes it explicit to readers of your code), rather than using pmap
.
I imagine making use of pmap when the function is not side-effecting
I think you have already asked enough specific questions that you will want something more than pmap
it's a good quick and dirty answer for coarse-grained parallel tasks, but lacks all control over how that happens
Java's built-in executors (queue + thread pool) gives you many more options
claypoole is a decent clojure lib that gives you a nicer entry to that and other stuff
Why does comp
work from right to left?
I think because it maps what you would write without comp
, but cleaner
(count (vec '(1 2 3)))
is rewritten ((comp count vec) '(1 2 3))
if I'm not mistaken
It also mirrors how function composition is written in standard mathematical notation
but yeah that sometimes trips me up, too
right - it keeps the order of the functions, and moves / eliminates parens
In the system I've been working on, I have a complex business logic that must run both on server and client side. (due to performance non-functional requirements) I am writing this business logic in Clojure and it is nicely interacting with the rest of the server side controllers and services in Groovy (Grails). I have no experience on Clojurescript. My question is: Will I be able to use the same business logic functions, the same code itself, I wrote in Clojure, as Clojurescript in the client side? And make it interact with the rest of the client side interface in TypeScript/Angular? Is there any gotcha? That would be a major achievement on the project because we will avoid writing 2 codes, in 2 languages for the same (very) complex business logic. It will save us endless hours in both coding and testing. My understanding is that it is true if we keep the core of my business in "pure" Clojure, I mean, away from fancy dependencies that might exist only in Java world or Javascript world. Is that right?
the typical way to do this is use a cljc
file, which allows conditional java side vs. js side code
IMHO using the actual java deps or js deps directly instead of a clojure wrapper is usually the right choice
and your java side or js side functions will be callable easily by java or js, yes
If I remeber correctly, there are certain features you can't use on cljs, but once you know them, you can try to avoid them to have valid clj/cljs code
there are also features you can use in cljs but not clj - cljc makes this work
Look at the difference page
Perfect! Thank you guys!
After my first quick read through, I can say that it will work for me. This will be game changer here.
also I recommend using the transit
lib for communication between client and server - it supports all the most common clojure data types directly, is easy to extend, and avoids a bunch of problems with just using edn directly
a common pattern when I had a mixed clj / cljs codebase was a core library file (cljc) that was shared, plus implementation files that were conditionally included with anything vm specific
I will take a look on that.
and is much faster for clj to cljs
It might not be the case. The client side is written in Angular/TypeScript. Only a specific business logic will be written in ClojureScript. A vanilla TypeScript code will call the ClojureScript logic. The communication with server will be handled by TypeScript/Angular.
there is a transit-js library
This one, correct? https://github.com/cognitect/transit-clj
the reason it's faster is that transit is actually done over the top of json and leverages the super fast json parsers in browsers
and because it also supports caching of repeated map keys and things like that, it can actually be faster than json (even though it's done over json)
which is admittedly counter-intuitive, but easy to show via measurements, which have been done
I will definitely take a good look on that. Thank you! Very helpful! You guys are awesome.
no, you're awesome
This one, correct? https://github.com/cognitect/transit-clj
that's the one for jvm clojure, there's another one for javascript (doesn't even need cljs) https://github.com/cognitect/transit-js
Go it!