This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-02-19
Channels
- # beginners (134)
- # boot (4)
- # cider (23)
- # clara (2)
- # cljs-dev (2)
- # cljsrn (4)
- # clojure (147)
- # clojure-austin (9)
- # clojure-berlin (2)
- # clojure-dusseldorf (2)
- # clojure-france (2)
- # clojure-italy (11)
- # clojure-russia (1)
- # clojure-spec (18)
- # clojure-uk (182)
- # clojurescript (40)
- # community-development (5)
- # cursive (29)
- # datascript (6)
- # datomic (18)
- # duct (6)
- # emacs (4)
- # events (1)
- # fulcro (46)
- # hoplon (5)
- # jobs-discuss (12)
- # keechma (1)
- # luminus (7)
- # lumo (1)
- # off-topic (11)
- # onyx (9)
- # parinfer (5)
- # protorepl (1)
- # re-frame (18)
- # reagent (23)
- # reitit (2)
- # ring (5)
- # ring-swagger (20)
- # schema (1)
- # shadow-cljs (32)
- # spacemacs (1)
- # specter (2)
- # vim (26)
you can configure nginx or apache to forward a request to a specific port - it's called "reverse proxy"
then you can say /foo/ forwards to port 8080, /bar/ forwards to port 8082 etc.
that's totally great. thanks @noisesmith
@mfm We have half a dozen domains served from Apache proxying to half a dozen different Clojure web processes on different ports, like @noisesmith suggests. Happy to answer questions...
Howdy. I just started with clojure and I'm having trouble with the following:
(into [] {"key1" "value1" "key2" "value2"})
@pedrohjordao what do you expect?
oh, the role of into is to empty one contents into another collection
if all you want is to put the collection into the other, just use conj
(conj [] {"key1" "value1" "key2" "value2"})
but really you can also just put the map inside a [] pair, depending on if you have anything else in there
@pedrohjordao if you haven't seen it yet, http://4clojure.com has some good example problems which help with some of the language basics
actually, what I have is something more like:
(loop [remaining-data json-data
processed-data {:open-jobs [] :free-agents [] :pending-requests [] :schedualed-jobs []}]
(if (empty? remaining-data)
processed-data
(let [[head & tail] remaining-data]
(recur tail
(match (first (keys head))
"new_job" (assoc processed-data :open-jobs (conj (:open-jobs processed-data) (get head "new_job")))
"new_agent" (assoc processed-data :free-agents (conj (:free-agents processed-data) (get head "new_agent")))
...
I'm using the match library because i'm used to using matching stuff from other languages. Is there's anything more idiomatic in the core language that I should know about?
Also, how idiomatic is what I'm doing in general?loop/recur to process a collection one item at a time is low level
generally you'd use map (if you output one item per input), mapcat (for 0 or more items per input but still distinct), reduce (to build up some result(s) based on consuming the input in order)
your case looks like reduce to me
yeah, I guess I'm just doing what I'm more familiar with, but I probably should be using reduce
speaking of "case" that match call can be replaced with case, which is built in
and those assoc calls would be much simpler as assoc-in / update-in
actually yeah those look like update-in with conj
user=> (update-in {:c 0 :a {:b ["foo"]}} [:a :b] conj "bar")
{:c 0, :a {:b ["foo" "bar"]}}
in your case it would be more like (update processed-data :open-jobs conj (get head "new_job"))
@pedrohjordao another small thing - if you change (let [[head & tail] remaining-data] ...)
to (let [[mkey mval] & tail] remaining-data] ...)
you can use the key and the value of that map entry directly instead of having to look up by key or look at the first item
so (get head s)
becomes mval
you might have gotten an error, but that kind of destructure does work if done correctly
then call seq on the map
(let [[[mkey mval] & tail] (seq remaining-data)] ...)
:thumbsup:
the only big change there is that the accumulator comes in first, opposite of the order of your bindings (unless there's something tricky you didn't show in your other code)
no problem
(reduce #(match (first (keys %2)
"new_job" (update %1 :open-jobs conj (get %2 "new_job"))
"new_agent" (update %1 :free-agents conj (get %2 "new_agent"))
"job_request" (update %1 :pending-requests conj (get %2 "job_request"))
:else %1))
{:open-jobs [] :free-agents [] :pending-requests [] :schedualed-jobs []}
json-data))
it complains about "ArityException Wrong number of args (9) passed to: core/first--4339 clojure.lang.AFn.throwArity (AFn.java:429)"
the data is something like this:
[ { "new_job" {"key1" "value1", "key2" "value2"}} {"new_agent" {"key1" "value1", "key2" "value2"}} ...}notice where the close paren is that matches the open paren by first on that first line
your next problem will be that with reduce, you only see one key/value pair from json-data at a time
so instead of treating it like a hash-map, you need to treat it like a two element vector, or a map-entry
so (first (keys %2))
becomes either (key %2)
or (first %2)
a few other changes similarly (using second or val on %2 instead of get)
huum, maybe I'm not getting what you are saying. After fixing the closing paren it is working as expected
oh, is json-data a hash-map or a vector full of hash-maps each one having exactly one key?
I might have made an incorrect assumption here
that's weird, but OK 😄
so basically it's a series of tagged events
cool, so that should just work then
so instead of (first (keys %2)) and (get %2 s) you can use a destructure of the seq of %2
#(let [[[k v]] (seq %2)] ...)
- rest of the code can just use k and v instead of using get / first / keys etc.
k and v are idiomatic names for the values in a single map entry, standing for key and value of course
huh, after doing that I get CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/case, compiling:
where are you using case?
sounds like you forgot the opening paren
(let [...] (case ...))
in clojure there are very few ways to invoke something without an open paren
so I think we eliminated half of your lines of code and 3/4 of your parens from your original
@pedrohjordao another thing to consider is that (apply merge-with conj {"new_job" [] "new_agent" [] "job_request" []} json)
does almost everything you need, aside from renaming some keys in a hash-map
haha, but get some sleep and coffee before considering that probably
Just learned about transducers. All of this time I was just using a lot of threaded macros with map, filter, etc. Should I refactor them to comp instead of ->> ?
It depends, the transducer would perform better, but unless you measure and see a problem at that point just go with what's easiest to read
Anybody here that uses mount
for cljs and experiencing an issue where a state starts multiple times?
How can I tell which method will be called when I call a function which is a multimethod on a value?
by calling dispatch-fn
on that value maybe?
It looks like https://clojuredocs.org/clojure.core/get-method pretty much does it. I don't really know what to do with the information I get out of it though.
@U86J7B0VD not much I guess - maybe look at the class name, or perform identity comparison. It's not surprising to me that you can't do much - after all, the whole point of polymorphism is that the caller knows little about the implementation
@U86J7B0VD why do you need to know the implementing function?
I'm really just looking at it for curiosities sake, while trying to understand the language and the problems it solves better.
https://clojure.org/reference/compilation probably does a better job than I can of explaining it
@funyako.funyao156 i’m not sure what you are asking but maybe defonce
will help you?
anyone knows an example or a tutorial or something like that about material-ui? I am thinking about using it because I need to improve ux especially a form. I am using reagent.
Using this piece of code
(->> receiptItems (map #(merge % {:guid (str "12343efidsli3o4203") :receipt_guid guid :user "WILL" :ts "Date"})))
I’m creating a new vector of maps from a vector of maps called receiptItems
. How would I add the index / number the item is in the receiptItems
vector to the new map?You might be looking for map-indexed
What is the right way to use map-indexed? I’ve tried
(->> receiptItems (map-indexed index #(merge % {:guid (str "12343efidsli3o4203") :receipt_guid guid :item_num index :user "WILL" :ts "Date"})))
to no availuser=> (map-indexed #(assoc %2 :index %1) [{:a 1} {:b 2}])
({:a 1, :index 0} {:b 2, :index 1})
How do you split but keep the item you split on in the resulting string? I am using (clojure.string/split item #"[.?!]") and it is splitting, but dropping any .?! I need to keep those in the result. Thanks!
@stevenpkent You'll need to use lookahead in the regex, like this: (clojure.string/split "stuff.nonsense?and!?more" #"(?=[\.\?\!]+)")
That produces ["stuff" ".nonsense" "?and" "!" "?more"]
which might be close enough to what you're looking for?
I tried this:
(map rest (re-seq #"([^.?!]*)([.?!])" "Hi. How are you? I'm great! Cool"))
=> (("Hi" ".") (" How are you" "?") (" I'm great" "!"))
@stevenpkent can also do
user=> (map clojure.string/join (partition-by #{\! \? \.} "foo! bar? baz. qux"))
("foo" "!" " bar" "?" " baz" "." " qux")
(in this particular case)user=> (clojure.string/split "...a" #"\.")
["" "" "" "a"]
user=> (map clojure.string/join (partition-by #{\! \? \.} "...a"))
("..." "a")
doesn't quite work the same as splitthanks all, I will try all these out
if you replace the map
in @manutter51's with mapcat
you get this:
user=> (mapcat rest (re-seq #"([^.?!]*)([.?!])" "Hi. How are you? I'm great! Cool"))
("Hi" "." " How are you" "?" " I'm great" "!")
wonder if there’s a simple way to get the rest of the input
@noisesmith making the last group optional gives you this:
user=> (mapcat rest (re-seq #"([^.?!]*)([.?!])?" "Hi. How are you? I'm great! Cool"))
("Hi" "." " How are you" "?" " I'm great" "!" " Cool" nil "" nil)
I ended up getting this as the intermediate response
[[["this is a file" " this is the second sentence"] ("." ".")] [["i am trying to capitalize the first word of every sentence, using Clojure"] (".")] [["will this work" " will this work"] ("?" "!")] [["i hope i can get this to work"] (".")]]
so if I can associate each punctuation mark with the sentence it goes with, it should be done. I already have trim and capitalize working. i just need to get the the punctuation associated in.
something like (apply map (partial apply map vector) ...)
I was using compojure.api and it was displaying the standard swagger interface, after an unexpected machine restart - it now sends a gzip payload. I have clean every cache I can think of, and even copied just the source of the project to a new directory, same gzip result. I may have upgraded a library prior to machine crash without re-starting the repl - Any ideas on how to debug this and get back to my sweet swagger page?
Do you know what's in the gzip?
I'd also try a different browser. Using DevTools in Chrome, I see a standard request header of Accept-Encoding: gzip, deflate, br
, so it's possible the server thinks your browser wants gzip compression just as an encoding
I got a bit further downloaded ModHeader chrome plugin - changed accept-encoding to empty and now I get the swagger header. My new problem is GET http://localhost:8080/api-docs/config.json 404 (Not Found)
Hmm, not sure what to make of that.
compojure was set to :spec "/swagger.json"
tried changing to :spec "/config.json", no luck
I should mention compojure-api is servicing the api correctly, I just don't have the swagger part of the config working ...
@gmercer did you try to update to latest deps? that 404 sounds like a bug that was fixes in latest ring-swagger.
the swagger-ui changed radically from 2.0 to 3.0, here’s the commit to support them both: https://github.com/metosin/ring-swagger/commit/a9c6efcc77855f303bffbde4beb838baf1ce63df (the conf.js
is not found if the version don’t match)
but I am relying on the empty accept-encoding from ModHeader
I have vague library upgrade memory of bumping buddy-auth and which depends on cheshire 5.8.0, and failed to start until I added explicit dependency for cheshire, downgraded to something in my ~/.m2
I must have kept fighting deps and not re-checked swagger