This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-05-28
Channels
- # announcements (1)
- # beginners (183)
- # boot (2)
- # clara (4)
- # cljs-dev (20)
- # clojure (59)
- # clojure-dev (7)
- # clojure-nl (1)
- # clojure-serbia (1)
- # clojure-sg (1)
- # clojure-spec (4)
- # clojure-uk (15)
- # clojurescript (77)
- # clr (1)
- # data-science (9)
- # datomic (23)
- # docs (3)
- # duct (15)
- # emacs (8)
- # events (1)
- # fulcro (6)
- # instaparse (3)
- # juxt (1)
- # lumo (9)
- # off-topic (18)
- # perun (2)
- # portkey (13)
- # reagent (2)
- # reitit (11)
- # ring (10)
- # shadow-cljs (158)
- # tools-deps (34)
Is there a built-in function like every?
that instead of returning false when the predicate fails returns the item in the collection ?
so I'm working through 4Clojure at the moment, and am starting to wonder which is the best way as far as readability vs performance vs <insert whatever else here>.... obviously there is a bunch of ways to do the same thing.... but I'm not sure which ways are overall better (used a bit loosely here)?
For instance, on the duplicate a sequence problem.... My solution is
#(reduce (fn [res el] (into res [el el])) [] %)
@lockdown- You could try some
but with the complement predicate.
you can replace (fn [res el] (into res [el el]))
with (fn [res el] (conj res el el))
the mapcat one doesn't work quite like that (that's an uncalled transducer) but is likely the most straightforward solution
@noisesmith I am assuming conj
is better here because I am just adding to the end of the vector? ... would into
be better if I was using a list or a map data structure?
into is a reduce that calls conj
so using conj directly is simpler
and into is better if you are eagerly filling one collection from another (with optional transformation as you consume the items)
here's a version using into properly (won't work on 4clojure's clojure version) (into [] (mapcat (fn [e] [e e])) coll)
or for combining two collections, or altering a collection as you use it to fill a specific collection type
that mapcat doesn't get used on the collection, it's a transducer that into uses instead
+user=> (def m (mapcat (fn [e] [e e])))
#'user/m
+user=> (into [] m [1 2 3 4])
[1 1 2 2 3 3 4 4]
when you don't give mapcat a collection, it returns a transducing function. when you provide an extra arg to into before the last arg, it uses it as a transducing function to transform its input
I'm getting how it is working.. I'm not getting how it is a correct use of into
since I am guessing I am at a point where I am not sure what is correct when/where when it comes to Clojure
I could rephrase that - it's a case where into is better than alternatives
your usage of into inside reduce was just an obfuscated conj
or more simply, don't create a collection just to pass it as the last arg to into, there's always a better alternative
ah.. I see what you're saying... I'll have to think that through a bit when I'm working through problems... but that makes sense
the reasons to use into with a mapcat transducer instead of mapcat directly are in case you know you are using the data eagerly and want better performance, or if it clarifies / simplifies code to be able to describe the transducing function separately from the rest
map the function and map the collection are two different things
we can disambiguate by calling the collection a hashmap
both describe something related to mapping from items of one domain from items to another, and for historical reasons they both get called "map"
into is frequently used with hash-maps because the basic collection operations mostly return lazy-seqs, and into is an easy way to get a hash-map back
that's true in clojure as well
+user=> (instance? java.util.Collection (java.util.HashMap.))
false
+user=> (instance? java.util.Collection {})
false
+user=> (instance? java.util.Map {})
true
but java "Collection" is overly specific, basic cs tells us that hash-maps and queues and trees are all collections
+user=> (coll? {})
true
coll? gets a little closer to our idea of what a "collection" is, but only for clojurey things sadly
+user=> (coll? (java.util.HashMap.))
false
And re: @sundarjβs comment about using repeat
to clarify the intent:
(into [] (mapcat (partial repeat 2)) [1 2 3 4])
or
(into [] (mapcat #(repeat 2 %)) [1 2 3 4])
if you prefer anonymous functions over partial
.(and I agree that expresses the intent better than (fn [e] [e e])
in my opinion)
I don't know which would be considered more idiomatic. My preference is entirely subject. Another option would be #(vector % %)
which some people may prefer.
crazy how many ways there truly are to do something.. still trying to wrap my head around that.... I feel that Haskell had a more clear path to solutions (trying to at least compare functional languages here even though they really are way too different to compare)
If I'm calling a function and would like to conj two values from the result of that function into a map, then return it, what's the best way to do that?
@scott.archer If you're using clj-http
you could have it parse the JSON response automatically, so you'd get back a hash map with keywords as keys -- that would make your code easier.
As it above, you could add a new binding in the let
:
body (parse-string (:body response))
and then you wouldn't be calling parse-string
twice.Instead conj
, I'd probably use assoc
:
(assoc my-site-info :token (body "access_token") :ttl (body "expires_in"))
(assuming the additional let
binding above)
@seancorfield Thanks, I caught the two calls to parse-string. I am using clj-http, so I'll see about having it parse the JSON.
I also find it's easier, with clj-http
, to specify :throw-exceptions false
and check the :status
in the result rather than letting it throw.
Thanks again, i'm new and muddling my way through it. I'm decent at getting stuff working, but I want to learn the right way to do things.
Learning all the idioms takes the longest time. I've been doing Clojure in production for seven years now and I'm learning new stuff all the time!
Hi, I am getting null pointer exception. Can anybody explain why?
(loop [a 0]
((println "*** Sales Menu ***")
(println "------------------")
(inc a))
(if (= a 0)
(recur a)))
First println returns nil and you are trying to use that nil as a function.
Unwrapping println and Inc expressions should help you. But be aware of immutable nature of clojure. (inc a) doesn't change the value of a
loop body executed with implicit do already. No need to add extra do
No. inc returns new value and never change a var. If you the result from it try to use let
.
Describe what you want aa suggested in that channel and community will try to explain how to do that)
@kushalkanungo1991 Also, you are evaluating (inc a)
but essentially throwing the value away. Perhaps if you explain what you're trying to do, maybe we can help guide you to a functional solution?
I am just trying to make an infinite loop and break it on a condition. I saw this example
(loop [accum []
i 1]
(if (= i 10)
accum
(recur (conj accum i)
(inc i))))
;; β [1 2 3 4 5 6 7 8 9]
and was following it.There may be better ways how to do this but it seems you're just trying to learn how loop-recur works. As you see, in your snippet you're anot passing (inc a)
to recur
but just a
which is incorrect. You should use (recur (inc a))
as you see in the snippet you've just posted. This way, the new incremented value of a (original a
is unchanged!) is passed to the loop and symbol a
is rebound to this value.
I am just trying to make an infinite loop and break it on a condition. I saw this example
(loop [accum []
i 1]
(if (= i 10)
accum
(recur (conj accum i)
(inc i))))
;; β [1 2 3 4 5 6 7 8 9]
and was following it.Hi is there a way to destruct the sequence in place sth like (hash-map (desctruct vec1) (destruct vec2))?
what do you expect the input and output to look like here? I doubt that destructure is what you are looking for - it's a helper for making binding forms in macros
@deleter Thanks! π
Hey, I am in a project with Clojure and ClojureScript. I am running lein, Emacs, Cider and Weasel (Browser-connected ClojureScript REPL) on a GNU/Linux system. I am trying to wrap my head around how Cider is working in this environment and how to use the 2 REPLs. When i navigate to the project in Emacs and use M-x cider-jack-in-clojurescript
it starts a new process on the system: clojure.main -m leiningen.core.main update-in :dependencies conj [org.clojure/tools.nrepl "0.2.13" :exclusions [org.clojure/clojure]] -- update-in :plugins conj [cider/cider-nrepl "0.17.0"] -- repl :headless :host ::
and gives me 2 buffers that's connected to REPLs. But i dont know if on or the other is connected to a ClojureScript REPL or a Clojure REPL. How can i know? If I eval a sexp from a file buffer, how can i know to what REPL the sexp is sent?
Are there any examples of component and compjure? Iβm not sure how to structure my app with stateful components. In C# my IOC container would just inject everything automatically.
@grierson Perhaps this section in the component readme helps? https://github.com/stuartsierra/component#web-applications should be pretty close to how it's done in compojure
@curlyfry would the βappβ be a map with keys for database, email, and other stateful components? Then just (:database component) inside my handler?
I actually don't use Component (I prefer Integrant, which has pretty much the same use case but works a bit different) π But the 'app' is called a 'system' in component, and is a map from keywords labeling the components to instances of components https://github.com/stuartsierra/component#systems
@jherrlin Did you try doing cider-repl-set-ns
from the file in question? You can see the prompt change so you will know which repl will do the work. As far as I can tell it's just a simple case of anything from a .cljs file goes to the clojurescript repl and anything from a clj file goes to the clojure repl. I don't know the full details, but in my limited experience it works like that.
hi guys i am trying to simulate movement on google maps of multiple entities in parallel i do this by having this
(defn start-mockup
"travel time has minimal of 30 sec and max of 151 per bus-stop
1 sec = 1000"
[]
(let [root (io/file "resources/routes")
files (rest (file-seq root))
_ (println "Num. files: "(count files))]
(doseq [file files]
(let [data (read-string (slurp file))]
(future
(doseq [c (:coords data)]
(let [travel-time (int (* 100000 (+ 0.03 (rand 0.121))))
_ (println "travel-time:" (int (/ travel-time 1000)) " sec")]
(println "name" (:name data) ", coords: " c)
(Thread/sleep travel-time)
(client/post ""
{:body
(json/generate-string
{:bus-line (:name data)
:current-lat (:lat c)
:current-long (:long c)})}))))))))
right now once the route finishes (there are no more coordinates) future stops and there is no more entity
i'd like to have circular behavior.
Once bus goes from A-B (finishes it's route (no more coords)) to generate now one
or start new future function
i was playing little bit with (while true) with promise
and delivery
but i am not sure if that is right way of thinking?So if I understand your question, you are trying to get the code inside of the future to run more or less forever?
Ok then I see where you are going with the future but it's kind of an odd way of using a future, which mostly exists to compute a future value. Stylistically I'd put the the body of the future in a separate function, so that it's easier to see what is going in an out of the code. To answer your question, you could do the repeat with either a while or a loop/recur. I'd also think about getting rid of the future. Perhaps replace it with a plain old Thread if there aren't too many of them.
i couldnt make it work with while/loop but i will hack my way into it tnx for the feedback about the function there are about 150 futures soo 150 threads and since my laptop has 4 ... it's quite a lot in my mind
Can anyone point me to a "production" example of using clj-http to consume a REST API?
I've got mine working, but I'd like to see what robust error handling looks like in a real implementation.
@scott.archer I tried to look at several projects but didn't find anything fancy. It seems that they mostly rely on exception handling (in upper layer?) * https://github.com/metabase/metabase/blob/c5fdebe219e3882359f0c727c196b0c42d12e8ac/src/metabase/util/stats.clj#L442 * https://github.com/metabase/metabase/blob/248bc22045a6a9458f695e8174f9c1ad7e9fb001/src/metabase/integrations/slack.clj#L80 * https://github.com/instedd/planwise/blob/df24106984aeb1e94a4252401f5f67469700589b/src/planwise/component/resmap.clj#L52 * https://github.com/eponai/sulolive/blob/a8a3d27282ea5691cd8fb67abbc63584659761bc/src/eponai/common/photos.cljc#L45 * https://github.com/eponai/sulolive/blob/a8a3d27282ea5691cd8fb67abbc63584659761bc/src/eponai/server/external/google.clj#L14
Thanks for the response! It looks like most of these check for a 200, then move on. Thanks again!
on line 9 you put a vector in parens
you don't even need parens there, you can use []
then call seq on it
but reduce does that already
I wish examples would stop using '(...) because it's pretty much always worse than using []
ok, what I meant is that the coll passed to reduce is a seq of vectors from a function call
right, but if you need to emulate it being a seq, you can call seq on a vector
but that is pretty much never needed (eg. reduce calls seq on its vector arg anyway)
a list is a kind of seq, but clojure functions that take seqs can turn a lot of things into seqs
so I think I'm getting a list but its a seq and run a test with a list with not quote π
my point is, to test something that takes a sequential collection, use a vector literal
right
it's error prone in a way that [1 2 3] is not
you could forget the ', or try to put forms in that should be evaluated
and the set of places where '(1 2 3) is right and [1 2 3] is wrong are very small, and fixable by a call to seq
reduce hard lesson of the day, make sure the result of the first iteration can be used in subsequent iteraions π
Itβs a good habit to just always supply the initial value
I want to read a string from the user, it has some numbers and some strings, I'd like to use edn reader, any pointers?
i need to pass a java File object to some constructor. everything works fine when i execute my uberjar locally: (io/file (io/resource "mykey.pem"))
where the file is in /resources/mykey.pem
, but when i deploy the uberjar to AWS ECS i get an exception saying mykey.pem is not a file or directory. i get closer if i use io/input-stream
and can slurp the contents once deployed.. but is it possible to convert a buffered input steam to a File object?
@joshkh so you need to include an additional file when packing an uberjar? it has been a long time since i did this ... let me do some research
thanks, sova. the thing is the file is definitely in the jar. i've extracted it and looked. so it's more of a problem with getting a File handle on it.
https://stackoverflow.com/questions/20389255/reading-a-resource-file-from-within-jar
do you need (io/file) ?
maybe you can use just io/resource
i definitely need a File object. (io/input-stream "mykey.pem") returns a valid BufferedInputStream
but the constructor of this java class expects a File. my lack of java skills are showing. π
Well, i just read this: If you need to slurp a file from a JAR file, don't call io/file on the result of calling io/resource, or you will get an exception that says the resource is "not a file". Instead, call slurp directly on the result of io/resource.
Aha, there is also If you need to copy a binary file from a running JAR (or WAR), don't call slurp as it will try and decode the file. Instead, extract similarily to:
(with-open [in (io/input-stream (io/resource "file.dat"))] ;; resources/file.dat
(io/copy in (io/file "/path/to/extract/file.dat"))))
Hi everyone,
Is somebody can help me here with instrumenting
with deftype
.
All detail are here : https://stackoverflow.com/questions/50572207/clojure-how-to-instrument-another-protocol-in-implementation
@sova Re: edn/read-string
-- is the problem there you have a string like "42 \"hello\" \"world\" 13"
and you want to read all those expressions, not just the first one?
You could try (edn/read-string (str "[" user-string "]"))
to get a vector of the expressions...

hi, I'm going to present clj(s) to my boss and colleagues this week and am currently thinking of the best way to demo how and why a REPL is a great tool to give fast feedback while building production ready code. any good ideas for code snippets?
I'd stick to the usual notepad, but i thought mb you guys come up with something presentable in even less time
@klaus.azesberger For me its always mind blowing how easy it is to implement a search field with re-frame. You could show a table and the have some input that you use to filter the table. Its just a few lines of code and can be live coded, if it is prepared well.
thanks, that certainly fits my time slot π
i could use some of our real ansible configuration data by parsing the yaml files
i want to remove entries from sets in a nested atom.
(swap! lookup-rc update-in [:tags (keyword tag)] (remove entry-id)
is not doing the trick.
for one thing remove doesn't return a set, but also calling remove like that will fail
Hmm, I thought it was like filter
if they are sets, (swap! lookup-rc update-in [:tags (keyword tag)] disj entry-id)
filter also wouldn't work in that context
update-in passes the object as the first arg, (remove entry-id)
doesn't return something that can operate on a set
it returns a transducer which can't do much without a transducing context (update-in doesn't provide one of those)
okay, very cool. beginning to grok.
also, if entry-id is the actual id, that's not how filter and remove work, if it's a function that returns true for that id, it's weirdly named and it won't work with disj
what if i want to remove a keyworded map from an atom completely? can I do something like (swap! lookup-ab update [:entry-ids] disj entry-id)
? in an effort to remove something like the Set associated with 12 from :entry-ids { 12 #{1 2 3 4 5}, 13 #{1 2 3 4 5 6} }
that calls for dissoc, but otherwise yes
disj is for sets, dissoc for hash-maps
aha. thank you. Where does remove come into play? disj did not show up in my elementary searching
remove is when you have a function that returns truthy for items that should be removed, and want a lazy-seq back
for now you can treat (remove f)
as an error that doesn't complain (later you might care about transducers and learn about it)
+user=> (remove even? (range 10))
(1 3 5 7 9)
what you did:
+user=> (remove even?)
#object[clojure.core$filter$fn__5610 0x48e92c5c "clojure.core$filter$fn__5610@48e92c5c"]
+user=> ((remove even?) (range 10))
#object[clojure.core$filter$fn__5610$fn__5611 0x3d1848cc "clojure.core$filter$fn__5610$fn__5611@3d1848cc"]
it returns another transducer (one that would blow up if you ever tried to use it correctly as a transducer)
aha, fn / fn
filter / fn
is cool and groovy but filter / fn / fn
is not.
that's not what is happening here
you called remove with one arg, which returns a transducer
oh, because it doesn't know what dataset to apply this to?
calling a transducer with one arg (in this case your set) returns a broken transducer that doesn't blow up until you try to use it
it creates an invalid transducer, it's just nonsense but nonsense that clojure doesn't proactively check for
I should clarify - you can call a transducer with one arg - that is part of how they are used in transducing contexts, but that's not what's happening correctly here
but you don't need to know any of that- just treat (remove f)
as a garbage in garbage out error until you know you need it
okay, thanks π
@seancorfield how would i access independent elements of a vector by index when I don't know how many there may be in total?
because when a user inputs tags, there may be many or few. i'm wondering if there is an idiom-esque way for how to iterate over strings in a vector of variable length
Ah, maybe just (doseq [x (rest (rest data))] ...) will be just fine π
thanks a lot
i'm catching some errors and printing out to the console when they happen, but i always also end up println'ing a nil
@sova once you have your vector, count
will tell you how many elements are in it.
(a vector is always a finite number of elements and count
is O(1) on it because vectors are Counted
collections, as I recall)