This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-12-02
Channels
- # adventofcode (286)
- # aws (3)
- # beginners (243)
- # calva (4)
- # cider (51)
- # cljs-dev (8)
- # clojure (74)
- # clojure-conj (1)
- # clojure-france (1)
- # clojure-italy (1)
- # clojure-spec (21)
- # clojure-uk (22)
- # clojurescript (25)
- # clojurex (6)
- # code-reviews (5)
- # core-async (3)
- # cursive (1)
- # defnpodcast (1)
- # fulcro (29)
- # mount (1)
- # off-topic (85)
- # onyx (5)
- # other-languages (7)
- # pathom (6)
- # pedestal (6)
- # re-frame (20)
- # reagent (2)
- # reitit (8)
- # ring-swagger (10)
- # shadow-cljs (53)
- # spacemacs (8)
- # tools-deps (34)
@kwcharllie379 I think the proper answer here is a/merge
(defn wait-for-close!
"Returns a chan that will close after all supplied chs
close.
Any values returned by chs are dropped."
([chs] (merge chs nil))
([chs]
(let [out (chan)]
(go-loop [cs (vec chs)]
(if (pos? (count cs))
(let [[v c] (alts! cs)]
(if (nil? v)
(recur (filterv #(not= c %) cs))
;; drop returned values
(recur cs)))
(close! out)))
out)))
@quieterkali You’ve been at it a while. My first suggestion is a little sleep 😉
so yeah I was thinking smth like this:
(defn get-profile-connection-suggestion
[id]
"Take an id and return list of the connection suggestion"
(let [suggestions (frequencies (get-connections-not-connected-to-profile id))]
(doall (map (fn [[user-id count]]
(get-profile user-id))
(sort-by val > suggestions)))))
I really liked http://www.4clojure.com/ for learning clojure, especially the aspect of functional programming with immutable data structures which was something I'd never done before. I started with the easy exercises and just kept trying different approaches. This motivated me to think differently and I gradually got the hang of it. It's nice because you can go as slowly as you want and look at other people's approaches for comparison.
I personally don’t like the constraints they give — makes it difficult to develop familiarity w/ idiomatic clojure
I think I know what you mean. Learning to solve problems functionally is only one aspect. I have also started picking up the best practices, but you're right that 4clojure didn't help with that. I'm not sure what the best resource would be for that.
Sounds worth trying.
Could anyone point towards a few open source Clojurescript + Reagent projects that make for good studying? I'm trying to wrap my head around the patterns / common structures that I should be using with core.async
Hi, when i post a new comment I want to update the "child comments" entry for the selected parent post...
(swap! posts update-in pid [:comments] conj this-comment-map)
.... makes sens?
do some every day and mastery will be yours
(whether that is clojure or basketball or metta/lovingkindness, that's up to you)
I’m not quite understanding when-let
binding and test. I’ve got:
(def dif (compare val arr))
(when (nil? dif)
...)
In your first block, if dif
is nil
, then presumably you don’t need it bound to any name, right? You know it’s going to be nil.
The second block says, if the result of (compare val arr)
is truthy, bind it to dif
and execute the following code, i.e., return dif
. Meaning your second block can be replaced entirely with (compare val arr)
but I guess this is not the whole picture 🙂
thanks @orendon, I’ve ended up with this:
(loop [val (first arr) values arr]
(if-let [dif (compare val arr)]
dif
(recur (first (rest values)) (rest values))))
I want to compare every value to every other value in an array, stopping when I find some diff.
How do I go about implementing a circular mutable linked list in portable Clojure(script)?
This doesn't work:
user=> (deftype Node [^:volatile-mutable next value])
user.Node
user=> (def a (Node. nil 1))
#'user/a
user=> (def b (Node. a 2))
#'user/b
user=> (set! (.-next a) b)
Execution error (IllegalArgumentException) at user/eval7232 (REPL:1).
No matching field found: next for class user.Node
When deftype makes mutable fields, they are private, to avoid making mutable objects
this also follows from the “opinionated” design of defrecord/deftype: default to immutability, program only to interfaces
if you want to build a mutable type object with deftype, also create an interface or protocol that exposes methods that a user would call to manipulate a mutable field
Thanks a lot!
👋 Hi Everyone! I have a problem and I'm not quite sure what the root of it is. I have a function like this that works in development (i.e., the cache is kept alive across function calls), but when I compile it to javascript, the function never hits the cache (it calls callAPI
even when the input is exactly the same). Is there something obvious that I'm missing here?
Oh wow that’s not beginners material 🙂 If you don’t get a good answer here perhaps try also #clojurescript
Thank you for making me feel better. I feel like a beginner 😄
Also, spooler
supposedly takes one argument, but you are calling it with the three channels?
Yeah, I was wondering how it works in development.
spooler
seems to take an argument and return a function that takes the three channels
Still not quite there:slightly_smiling_face: Shouldn’t it be ((spooler "API call") =I= =O= =E=)
shit, yes
So the purpose of the spooler-returned function is just to kick-off the go block, right? I wonder if the entire thing just gets GC’ed for some reason, since you never hold a reference to the result of the function anywhere. I don’t know much about core.async, sorry.
Hmm... but wouldn't I get the same behavior in development and release?
It never gets garbage collected in development
It may be some javascript stuff, which I'm even more a beginner at
I'm confused why it work until it's in JS land
Got it working!
What do we call the stack-like scope of (binding [dyn-var value...] body)
? It's more than stack, because it applies to lazy sequiences, too. Would you call it a "dynamic scope," or do we have a better term?
@peter.kehl pretty sure that’s dynamic scope (as opposed to lexical scope, which is the norm)
@nikola.kasev use time
?
@nikola.kasev checkout criterium
if you wanna be accurate.
https://github.com/hugoduncan/criterium
Hi, I'm trying to work on my nested comment render-er. so far so good. i can now post a comment and have the atom get updated and re-rendered right away with rum/react
but I am curious now, how can I update the atom to tell the parent element that the new comment is a child? My data looks like
(atom {77
{:id 77,
:contents "Seventy seven is the nicest number below one hundred",
:author "",
:comments [33 53]},
and I'd like to inject a new value into :comments... say :comments [33 53 78]
now. What's the right way to do that with swap!
?Have you tried update-in
with conj
?
i'm confused because i want to use a new way to index each map in the atom (with the ID hanging outside as the key)...
How can I use reduce-kv to get the index of a particular element (:key val) match in my atom? I'm trying to do indexOf to then use assoc-in.
Thanks ^.^
Yeah actually I just had a vector of maps called posts [ {:id X :comments Y :author Z} {:id, :com, :aut} {} {} {} ...]
but under the recommendation of potetm, i'm moving toward making it posts [ 77 { :id 77 .. } 33 {:id 33 ... } 5 {} 9 {} ...]
so that the indexing is fast, but then i'm not sure how to assoc-in ... there's no conj-in is there?
like i'd like to assoc-in posts [post-id :comments] comment-id
but not assoc because that will overwrite, non?
maybe I can use update-in + conj?
Maybe give a very tiny actual data structure and what you want it to become. (It is difficult to piece together from above.) That way anyone can see exactly what you are saying.
I mean, I probably could figure this out, but after looking at the above for 30 seconds, I gave up.
right now i have two atoms and things are getting messy
the basic data structure is a collection of post-map s
But when I want to render a post, I was using filter on the :id ... now I am transitioning it to a map indexed by :id, but updating nested values in the atom is like huh.
Actually, I'm guessing this might be a better structure to talk about
[{:id 1, :x [3]} {:id 2, :x [5 7]}]
If so, is the question, given an id 2
and value 11
, how do I turn this into the following?
[{:id 1, :x [3]} {:id 2, :x [5 7 11]}]
@sova wouldn't this work?
(let [posts [{:id 1 :contents "hoge"}
{:id 4 :contents "fuga"}
{:id 12 :contents "piyo"}]]
(->> posts
(filter #(= (:id %) 4))
first))
; {:id 4, :contents "fuga"}
(let [posts [{:id 1 :contents "hoge" :comments []}
{:id 4 :contents "fuga" :comments [1 2]}
{:id 12 :contents "piyo" :comments [4 5 6]}]
first-hit (->> posts
(keep-indexed #(when (= (:id %2) 4) %1))
first)]
(update-in posts [first-hit :comments] conj 42))
courtesy to https://stackoverflow.com/questions/8641305/find-index-of-an-element-matching-a-predicate-in-clojure
Thank you! tell me more about keep-indexed. I'm tempted to use 2 atoms to hold the state and that's bad.
i just learned about it myself as i was googling about your question so the docs are probably a better guide
so... i can use keep-indexed to get a subset of results...
but why prefer this over filter? /newb
filter has no way to provide the positional index of an item
oh. it gives positional index? nice! so i don't have to use reduce-kv & update-in... i can just use update and the index from keep-indexed?
think about it like this: filter gives you the value, keep-indexed (also) gives you the key
keep-indexed also gives you the value
brain... booting
os loading music plays
tell me more about %2
and %1
It is a shorthand.
#(when (= (:id %2) 4) %1)
could have been written
(fn [idx id] (when (= (:id id) 4) idx))
@sova #()
syntax is a reader macro, and it understands %1
, %2
and so on as the first, second and so on args.
%&
is for variadic args
Ohhhh very nice
seeing examples side-by-side really nails it in
Rock on! This is very goo
(keep-indexed ...)
very nice for updating my parent comments' vectors
for even more flexibility there's also (mapcat f (range) coll)
- with keep you get to accept or reject each item, with mapcat you can accept, reject, or insert new items as needed
uh you can insert with mapcat?
let's get delirious with maps and keywords!
could i trouble you for an exmpl gratia?
+user=> (mapcat (fn [idx el]
(cond (zero? (mod idx 4))
[el el]
(zero? (mod idx 3))
nil
:else [el]))
(range)
[:a :b :c :d :e :f :g :h :i])
(:a :a :b :c :e :e :f :h :i :i)
for every input, mapcat can produce 0 or more outputs
[el el]
?
return a vector of elements
i thought i was adding comment-ids to the parent's :comments
field but apparently i'm adding them to the parents' parent... so comments are being rendered as the same level (not indented) as the parent
so i've got a little insect hanging out somewheres...
nevermind. the code is correct. the rendering is not.
I can implement a very naive function that recurs over the string, but is there a smarter way?
@nikola.kasev (frequencies "ababaa")
is very close
frequencies plus the function that turns \a into :a
(comp keyword str)
user=> (frequencies (map (comp keyword str) "ababaa"))
{:a 4, :b 2}
'frequencies` - I get, but (comp keyword str)
- I still need to wrap my head around it. I know the str function, but what's the purpose of comp?
comp takes functions and returns a function that chains them to an input in reverse order
((comp f g h) x) is the same as (f (g (h x))
notice f, g, h don't move, the parens do
if you check (frequencies "ababaa")
you will probably see the problem he is avoiding
Do you really need a keyword here? The character itself might be just fine as the keys of the map.
@rmprescott yeah, I can live with that
@noisesmith so keyword is turning a character into a key how exactly?
there's no such thing as a key - keyword is a function that takes a string and returns a keyword
or, maybe we could say "in clojure anything is a key" - in (frequencies "ababaa") the chars are keys
the useful things about keywords are that they evaluate to themselves, not some other value, and act as a key lookup when called as a function
I was referring as a key in a map with key/values, so keywords are like atoms in other languages like Erlang, right?
keywords are strings that can be called like functions, and you can't do string operations on them
in most lisps (not clojure) atom means anything that isn't a collection
I'm not sure what an atom is in Erlang
OK - question was edited after I answered so I'm deleting my answer
@noisesmith thanks
@nikola.kasev a search you can use to learn more about comp and how / why it is used is "point free programming"
it's more common in eg. Haskell but Clojure has some facilities for it, and often a point free solution is clearer (once you understand the constructs and how they are used)
right, comp is a prefix version of ∘
@nikola.kasev we have -> which is remarkably similar to that (-> (h x) g f)
is a macro that expands to (f (g (h x)))
reversing the order comp uses, and it's not as refactorable / first class as comp
but also helps to make code much clearer
comp
is important, because it is at the core of what this is really all about
You want to use composable abstractions, and that's one really good aspect of FP. 🙂
quick question, I have many vectors of vectors (rows) and want to turn them into a vector of columns, how can I easily do that? I tried (apply map into rows)
but it fails as into only accepts 2 arguments.. :thinking_face:
you want vec
or (partial into [])
which does the same thing less efficiently
oh - reading the problem description, you actually want vector
not vec or into
user=> (apply map vector [[:a :b :c] [:d :e :f]])
([:a :d] [:b :e] [:c :f])
or (def row->col (partial apply map vector))
plumatic/schema users: how to define a schema that can contain any map?
thanks!
i was looking for something like s/Map, but it looks like it doesnt'have one
s/Any is good enough, anyway