This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-05-14
Channels
- # beginners (74)
- # boot (1)
- # cider (6)
- # clj-kondo (8)
- # cljs-dev (30)
- # clojure (195)
- # clojure-ecuador (1)
- # clojure-europe (2)
- # clojure-italy (51)
- # clojure-nl (47)
- # clojure-spec (9)
- # clojure-sweden (27)
- # clojure-uk (63)
- # clojurescript (84)
- # cursive (41)
- # datascript (17)
- # datomic (16)
- # docker (1)
- # emacs (10)
- # events (2)
- # graalvm (2)
- # graphql (37)
- # juxt (2)
- # nrepl (20)
- # nyc (2)
- # off-topic (26)
- # onyx (3)
- # pedestal (4)
- # perun (19)
- # planck (1)
- # reagent (9)
- # reitit (4)
- # shadow-cljs (208)
- # spacemacs (6)
- # tools-deps (4)
@haiyuan.vinurs haven't completely got a question.
@haiyuan.vinurs emacs and install cider that should be enough to get you going https://www.braveclojure.com/basic-emacs/
with cider that i must start a repl, is there a tool like global gtags that can parse the code statically
my normal workflow with cider is: open clojure project, start cider repl with :cider-jack-in
, start to eval my code with :cider-eval-defun-at-point
(mapped to ,ef hehe), finish the cider repl with C-c C-q
@haiyuan.vinurs Clojure really expects to have a live REPL for all your workflows. Check out Stu Halloway's talk on REPL-Driven Development, and another one called Running With Scissors. Without a REPL, you'll struggle to work with Clojure. Like @UC1FADN3T says: start a REPL at the beginning of your work and keep it open until you're done. I tend to keep my REPL running for days and days.
I'm confused, how does (reduce conj () [1 2 3 4])
reverse the sequence? (yes, walking through 4clojure problems!)
conj
has performance guarantees not location guarantees. Vectors are easy to append to. lists are easy to prepend
@dharrigan you can also replace the reduce
with reductions
to get an idea of what is happening at each step of the reduce.
I was confused about that one until I realized that the () was just the initial value for the conj... Realizing that (reduce conj () [1 2 3 4]) is the same as (reduce conj [() 1 2 3 4]) made it clearer for me
often if a reduce is confusing you can s/reduce/reductions/ to get some clarity - (reductions conj () [1 2 3 4])
I spent a nice debugging session with cognitect's AWS library wondering why its profile-credentials-provider cannot find my profile. Heh, a rookie mistake:
:aws-profile local-dynamodb
=> type: symbol (should be string, i.e.:)
:aws-profile "local-dynamodb"
But I got a chance to try Cursive debugger which was actually great and in the debugger I pretty soon figured out that (get (config/parse f) profile-name
was returning nothing and therefore I realized soon that I had a symbol in configuration instead of string.
Regarding my yesterday's question if it is possible to change environment variable value on the fly - I don't need to change it. I found out that Cognitect's AWS library provides a profile-credentials-provider - so, I can have both of my AWS profiles (local Docker DynamoDB profile and real AWS profile) in my confige.edn and using Mount switch the profile in the REPL without restart.
Clojure is great!Yihaa!
And I really love Cursive. I created a "reset" command and a simple hot key for it - I'm able to "stop states, refresh namespaces, start states" with one keystroke, i.e. e.g. switch the data source from my local dynamodb docker container to the real AWS DynamoDB. Yihaa!
... and if you see Stuart Halloway there in Cognitect corridors send him my regards regarding his "Repl Driven Development" - it totally changed how I use REPL.
will do...
Having a scratch file where I write all my REPL stuff nowadays instead of writing them in the actual REPL editor really boosted my Clojure productivity. You guys at Cognitect could list some good beginner "must-to-watch-videos" 🙂
... or someone could write a book titled "50 Clojure coding and REPL tricks" - I surely would buy a copy. 🙂
If I have a vector like
[{:pgid {:S "1"}, :pgname {:S "Books-local-aws"}} {:pgid {:S "2"}, :pgname {:S "Movies-local-aws"}}]
... is there a fancy, Clojure idiomatic way, to turn it to this:
{"1" "Books-local-aws", "2" "Movies-local-aws"}
(I mean using the Clojure standard library without recur or reduce?)
I should start to learn to use the standard library - I understood that the standard library often provides various transformations so that you don't need to loop yourself.why is reduce not idiomatic?
This works:
(reduce
(fn
[mymap item]
(conj mymap {(get-in item [:pgid :S]) (get-in item [:pgname :S])}))
{}
items)
it's the best way to make an associative object out of a seq
... but is there some standard library function that could be used instead?
you can use assoc instead of conj
So, my reduce above is just fine?
(conj foo {bar baz})
is the same as (assoc foo bar baz)
except it creates a hash-map nobody needs
yes, the reduce is fine, but I'd use assoc
Ok. Thanks!
So:
(reduce
(fn
[mymap item]
(assoc mymap (get-in item [:pgid :S]) (get-in item [:pgname :S])))
{}
items)
also, this is open to judgment, but (-> item :pgid :S)
might be more readable than (get-in item [:pgid :S])
for this specific case
a line break might help readability as well
(assoc foo
bar baz)
Ok. Thanks!
So:
(reduce
(fn
[mymap item]
(assoc mymap
(-> item :pgid :S) (-> item :pgname :S)))
{}
items)
Good that I asked. 🙂
So, occasionally if I'm wondering if my small code snippet is idiomatic Clojure or not, you guys don't mind me asking here? I learn a lot with you gurus. 🙂
This is exactly the right place for that sort of question
All right! I'll be a lot more active here in the future! And I'll be learning Clojure 2x than I previously did. Yihaa!
there's also #code-reviews but usually that's usually used for bigger things
@nedcg my only problem with that is that putting an arg to a parent on the same line as a child that had a line-break in the middle feels strange
to me a line break mid form introduces a new level of nesting, so keeping an upper level on the same line has a weird friction to it - but of course that's subjective
@noisesmith the line-break is for visually associate the operations over the same parameter(%2), it feels weird to me decompact with line-breaks such a simple function
right, but {} and items are for reduce, not for #(assoc ...)
so I would remove the line break, or add another for each arg to reduce
but as I said at the start, it's subjective, we don't need to have consensus, but it's informative to hear each others reasons I think
another way to implement this pattern is with (into {} (map (juxt key-fn val-fn) coll))
, where key-fn
and val-fn
are the corresponding “extractions” on each value in coll
clojure doesn't do this collapsing of intermediary values automatically (many other languages do), but we can do it explicitly
Interesting. I need to try that tomorrow (it's midnight here in Finland).
How do I learn to see things like "it avoids creating a lazy-seq nobody needs"?
You just looked at the code and immediately saw it?
Ok. I read it tomorrow. I think I'm not absolute beginner, I have used Clojure a bit but now want to be more fluent and learn more idiomatic Clojure coding...
over time you’ll learn what the code actually does: (map f coll)
creates a lazy sequence, whereas (map f)
does not. so if you’re going to do multiple steps (e.g. map
then filter
then into
), you can avoid creating those intermediate sequence structures and use the more advanced transducer form in order to make it faster