Fork me on GitHub

Hi. Is there a way to circumvent cors policies in my dev-setup. How do you do it? Szenario: I'm writing a clojurescript-app and want to implement a persistence layer. For that I wanted to use opensearch (elasticsearch), so I started a opensearch container. Since the app is served by my dev-environment / figwheel and the container listens to another port I'm hitting the cors-border. My thoughts on it: I could write a little backend, which accessses opensearch, but then I'd lose my figwheel integration, because I would have to serve my javascript also from that backend. Do you have any ideas, how to keep local dev-env and avoid this cors-problem?


doesn't Figwheel work fine with any backend though?


for example in my project I have backend Clojure and frontend with FIgwheel, but maybe I don't understand your situation


So you are serving your javascript app from one endpoint and accessing elasticsearch directly from the client running on another endpoint? If you want that you need to set in your dev environment, e.g.

Access-Control-Allow-Origin: *
Here's something related to figwheel: •

Matthew Downey18:12:04

It's a hack, but when I've hit this issue I just run on localhost, and have the Clojurescript app route requests through localhost. Works fine if you distribute the app as a zip file with HTML and JS inside, and whoever is using it doesn't mind running the local cors proxy.


Thanks for the answers. Had no time so far to test it, but I'm gonna give it a hit these days. Thank you @UP7RM6935 @U06BE1L6T @UEN45M0KV


Hi, can anyone recommend a friendly material to learn clojure. Have being trying to learn this awesome language since last year but no inspiring materials. Thanks


Highly recommend That’s how I learnt clojure :)

practicalli-johnny08:12:42 covers the fundamentals of the language lists of community learning resources, including my own practical books at which also has free books and 100+ hours of Clojure coding videos I learned Clojure by solving challenges has 84 challenges to solve in Clojure, with optional mentor support


The inspiration (?) for the Rings of Power TV series:

Ted Ciafardini17:12:39

Is there a more terse way to remove from a seq of maps based on the non-existence of keys? “All people who are not nice & not kind”

(remove (fn [person] (or (:nice? person) (:kind? person))) people)
I feel like there must be


that’s pretty terse. but there’s (remove (some-fn :nice? :kind?) people)

👍 3
Ted Ciafardini17:12:18

Terse. Never used some-fn before. Thanks!

Matthew Downey18:12:06

There's also (comp (remove :nice?) (remove :kind?)) if you're using transducers / chaining with further computations, e.g.:

    (remove :nice?)
    (remove :kind?)
    (map something-else)
    (comment "etc."))


Note that your code gets significantly shorter if you use

(remove #(or (:nice? %) (:kind? %)) people)

Abhi Saxena20:12:51

Hi All, Give a list of Maps, how can we update the values only if the keys matches certain criteria, do we need to destruct and construct again ({sectionTitle A, dataPresent 1, dateCreated 08/05/2020} {sectionTitle B, dataPresent 0, dateCreated 10/05/2020} {sectionTitle C, dataPresent 2, dateCreated 10/05/2020}) I am looking for updating the dataPresent only when sectionTitle is B and the collection structure should remain the same


can you write a function that takes a single map, checks the section title and if it is equal to B updates dataPresent?

Abhi Saxena20:12:02

Yes, but then I am not sure how to construct the original collection back


if you can make that function and call it f, then (map f collection) would do what you want

Abhi Saxena20:12:35

I did that with map but I have been told since you are just updating a single value inside map why do you even need a map function.......

Abhi Saxena20:12:02

the collection is huge in size


ah, you only want to update a single record. not all of them are candidates for updating?


you don’t have a great data structure for editing in the middle. often you can take a list and turn it into a map by treating one of the keys as an index. so sectionTitle would be your map


or you can use a vector, find the index of the one you want and then update just that index


But if you don’t know where in the collection the map you want to edit is ahead of time and if you’re going to ad-hoc construct a data structure only for this single purpose, you might as well just use map after all, right? You’re going to have to iterate through the collection either way. I think constructing a vector from a list would effectively involve iterating through the whole list, right? And in any case, the big-O complexity to find the right map is going to be linear.


yeah. the best answer is to have a datastructure that matches your access patterns. But for sure it doesn’t make sense to turn a sequence into a vector, update in O(1) time and then still just use it like a sequence. Because the cost to turn it into a vector is the same as just mapping. You really have to use the proper data structure in more places. Turning it into a convenient one in one place at linear cost doesn’t improve over modifying a structure in linear time.

Abhi Saxena20:12:49

Is there a possibility I can filter that map, dissoc it , update it and add it back with conj

Abhi Saxena20:12:19

I am not sure what functions to use for that......


Hm, maybe something like?

(loop [init '()
       [m & tail] ms]
  (if (= (get m "sectionTitle") "B")
    (concat init (conj tail (my-update-fn m)))
    (recur (conj init m) tail)))
I couldn’t think of a way to do it with standard lib fns, so resorted to a loop/recur. But I could be missing something.


I think this does what you want in that it avoids iterating through the rest of the maps after it finds the one you want to update.


Actually, I think there may be a better way to do this using split-with


(let [[init [m & tail]] (split-with #(not= (get % "sectionTitle") "B")
    (concat init (cons (my-update-fn m) tail)))


I think that also avoids processing the rest of the elements after the correct map is found.


Hmm, scratch that, since split-with is implemented as [(take-while pred coll) (drop-while pred coll)] it will process the beginning of the list twice. So in the average case it won’t save you anything unless you think the map of interest will appear near the beginning of list most of the time. I suspect you’ll have to do something like what I did in my first solution (although I think my code can probably be improved) if you want to avoid processing the whole list. But in any case, I guess if it were me I’d be thinking hard about whether the added code complexity is worth the performance optimization. This operation is going to be O(n) regardless.

Abhi Saxena22:12:18

Can't agree more, thanks much for all your help and guidance


zipmap is effectively lazy, isn't it? And some will short-circuit. So we can zipmap a range to the list to discover the index of the matching predicate with some, and use that as the key to update.

(defn update-first [pred transform coll]
  (let [idx (some (fn [[i x]] (when (pred x) i)) (zipmap (range) coll))]
    (if idx
      (update coll idx transform)

(let [m [{"sectionTitle" "A", "dataPresent" 1, "dateCreated" "08/05/2020"}
         {"sectionTitle" "B", "dataPresent" 0, "dateCreated" "10/05/2020"}
         {"sectionTitle" "C", "dataPresent" 2, "dateCreated" "10/05/2020"}]]

   #(= "B" (% "sectionTitle"))
   #(update % "dataPresent" inc)

; =>
[{"dataPresent" 1,
  "dateCreated" "08/05/2020",
  "sectionTitle" "A"}
 {"dataPresent" 1,
  "dateCreated" "10/05/2020",
  "sectionTitle" "B"}
 {"dataPresent" 2,
  "dateCreated" "10/05/2020",
  "sectionTitle" "C"}]

🙌 1

Zip map is not lazy. But it only proceeds for the items in the shortest sequence


Ok. Can we just wrap the zipmap expression in lazy-seq then?


Zip map returns a map. The clojure implementation does not have a lazy behavior. It will have defined keys and associated values


... Well, map is lazy. So I guess replace the zipmap expression with

(map (fn [i x] [i x]) (range) coll)


update only works on associative collections (e.g. maps or vectors). You’d have to convert it to a vector first, right?

🤒 1

I think one of the premises of the question is that the data is in a list.


Aah. So many gotchas on this problem.


@UABEM258C How do you conclude that split-with will process the start of the list twice? Looking at the source, that doesn't make sense to me.

Abhi Saxena06:12:24

thanks @U11BV7MTK @UABEM258C @U90R0EPHA - I was finally able to solve this problem, without your help it wouldn't be possible.


@U90R0EPHA well drop-while and take-while will both iterate across the maps until they find the one that fails the predicate, right? That’s all I meant. There are 2 separate passes. But, on the other hand, an algorithm that only does a single pass but does twice as many cpu operations per step wouldn’t be any better. These things are subtle. Benchmarking is probably a good idea if it is performance critical.


Oh. It just hit me. Yes. The call to drop-while will start from the head and traverse until failed predicate, even though take-while already located the split point.


I’m trying to write a macro to avoid boilerplate about the a db session (using gorillalabs/neo4j-clj).

;; what works
(with-open [session (db/get-session selected-db)]
                          (doall (users session)))

;; what I wrote
(defmacro query
  `(with-open [session (db/get-session selected-db)]
     (doall (~query-name session))))


what happens:

(macroexpand-1 '(query users))
;; => (clojure.core/with-open
;;     [query-macros/session (db/get-session query-macros/selected-db)]
;;     (clojure.core/doall (users query-macros/session)))

(macroexpand '(query users))
;; => Syntax error macroexpanding clojure.core/let at (notebooks/query_macros.clj:29:1).
;;    query-macros/session - failed: simple-symbol? at: [:bindings :form :local-symbol] spec: :clojure.core.specs.alpha/local-name
;;    query-macros/session - failed: vector? at: [:bindings :form :seq-destructure] spec: :clojure.core.specs.alpha/seq-binding-form
;;    query-macros/session - failed: map? at: [:bindings :form :map-destructure] spec: :clojure.core.specs.alpha/map-bindings
;;    query-macros/session - failed: map? at: [:bindings :form :map-destructure] spec: :clojure.core.specs.alpha/map-special-binding


It really looks like the macroexpand-1 is correct to me


but it might not be, I’m new at this


so I can’t quite tell if this is an error in the library I’m using, or if I’m bad at macros


the latter is highly likely

Bob B20:12:40

it looks like the symbol session is being resolved to the current ns, which clojure doesn't like for a local binding - using a gensym might provide some progress... actually, the guide page seems to demo almost your exact use case as a candidate for gensym: <>


i was kind of weirded out by how namespaces and local bindings looked to work…. I don’t know enough to know why, it was just an intuitive, this smells funny


adding that # and I’m up and running, thanks for the find!

👍 1