This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-02-16
Channels
- # announcements (2)
- # aws (2)
- # babashka (29)
- # beginners (69)
- # calva (6)
- # chlorine-clover (2)
- # cider (1)
- # cljs-dev (4)
- # clojure (44)
- # clojure-israel (1)
- # clojure-spec (3)
- # clojure-uk (31)
- # clojured (2)
- # clojurescript (6)
- # code-reviews (22)
- # core-typed (133)
- # cryogen (6)
- # cursive (7)
- # datomic (25)
- # emacs (19)
- # fulcro (69)
- # graalvm (1)
- # graphql (7)
- # lumo (1)
- # off-topic (92)
- # parinfer (2)
- # pedestal (6)
- # reagent (5)
- # remote-jobs (1)
- # shadow-cljs (11)
- # tools-deps (20)
- # tree-sitter (1)
- # vim (4)
- # vscode (6)
(let [a-promise (promise)]
(something))
;; Now I can suddenly use a-promise?
(println @a-promise)
As far as I know, let
indeed never leaks scope like this - evalulating this code gives me Unable to resolve symbol: a-promise in this context
, which confirms your correct assumption.
If you are currently able to use a-promise
outside the let
like your code shows, the only explanation would be if you already had an a-promise
in your scope outside the let
(could very well happen if you're in a REPL and you have defined it previously)
But in this case, the a-promise
outside the let
would not be the same value as the one defined inside
It’s possible I misread it, but it was in an explanation of promise usage in a book I’m reading
I’ve absolutely misread it... the use was within the let block. Doh. Well at least I understand something
@kamuela Was the example returning the promise as the value of the let
block with code that deliver
ed the value to that promise happening "elsewhere"?
No the example was using the promise within the let block, I just didn’t realize it because of the formatting
Hey! Quick question 🙂. I want to split a vector into [matchingPred] [notMatchingPred] I thought that this
(split-with even? [1 2 3 4 5])
would give me something like [(1 3 5) (2 4)]
but it returns [() (1 2 3 4 5)]
instead. Why is that?group-by
gives me almost the expected result cause it returns {true [2 4], false [1 3 5]}. Should I use that and just get rid of false/true keys by mapping?
Yeah, I went that way, and it worked, I’m not sure if this is the clojure way so please let me know 🙂
Check out the docs for split-with
([pred coll])
Returns a vector of [(take-while pred coll) (drop-while pred coll)
1 is not even so it won't be put in the first collection and the rest won't then either.
Using group-with
sounds good to mesplit-with
according to its doc "returns a vector of [(take-while pred coll) (drop-while pred coll)]".
Note that take-while
does not returns a sequence of items that matches your predicate (all even numbers), but rather (in "plain" words) returns a sequence of items until the first item that does not match your predicate - the first odd number
So take-while even? [1 2 3 4 5]
returns an empty sequence since the first item in your vector [1] is not even.
However, take-while odd? [1 2 3 4 5]
returns a (1)
since odd? 1
returns true, while odd? 2
returns false
Similar logic applies to drop-while
@peb.brzezinski Maybe you want [(filter even? coll) (remove even? coll)]
?
Ahh, thank you, that makes sense. I misunderstood [(take-while pred coll) (drop-while pred coll)]
this part.
Depending on the size of the vector, you could write a reduce fn to return a tuple of [(even-vals) (odd-vals)]
Something like (reduce (fn [[fst snd] n] (if (even? n) [(conj fst n) snd] [fst (conj snd n)])) [[] []] coll)
Risky, as the order of results is unspecified. It might work like you expect, it might not.
Though I'm sure you'd get deterministic results in a benchmark
Order of vals
or order of group-by
, which one's non deterministic? I kind of liked this solution as this is single pass. Otherwise a reduce
is best.
Group by returns a hash map. Order of map entries is unspecified.
Yeah, but there will only ever be two entries. If we know the evens and odds are properly ordered, we are okay.
Like this,
(defn group-with
[pred coll]
(let [grouped (group-by pred coll)]
[(grouped true) (grouped false)]))
(group-with (complement even?) [1 2 3 4 5])
I experimented with this some time ago, you can find the results here: https://gist.github.com/bsless/948319259b542126b57cc1c08b3549f2 Tested for input size of 1e6, found best performance for
(defn splitv [pred coll]
(reduce
(fn [[xs ys] x] (if (pred x) [(cons x xs) ys] [xs (cons x ys)]))
[() ()]
coll))
@mmeix A variant of yours, with deterministic ordering,
(defn group-with
[pred coll]
(let [grouped (group-by pred coll)]
[(grouped true) (grouped false)]))
(group-with even? [1 2 3 4 5]) ;; => [[2 4] [1 3 5]]
is there a consensus around unit testing private functions? looks like it can be done with the #'
macro but it's not clear if that is a hack or considered harmful
seems one school of thought holds that a function should either be unit tested or private, but not both
I belong to this school of thought. Having too many unit tests really pins down the implementation which makes it difficult to change.
I think its an argument that can fall both ways: A benefit to not unit testing your private function is that you keep your implementation flexible. A downside is that testing only your public API may be hard, leading to missed cases.
I mostly don't unit testing private functions, but I also tend not to make functions private in the first place.
There are exceptions to both parts of that, that are driven somewhat by gut feel, based on nine years of doing Clojure (and learning a lot along the way -- I used to use private functions a lot more and I also used to write more tests for private functions!).
I think the goal should be to show that your public API works as advertised ^^ — Not the other way around
Lately I've been doing more generative testing on private functions, to verify their implementations, rather than unit testing them.
generative testing - like haskell's quick check?
Yes, org.clojure/test.check
yes, test.check
in clojure land
usually fueled by clojure.spec
Yeah, what he said!
I was literally just typing a bit about Spec 🙂
Do you have some publicly shareable examples @U04V70XH6? I am interested in seeing generative tests on unit level that don’t just repeat the implementation
I once read this: https://fsharpforfunandprofit.com/posts/property-based-testing-2/, may be relevant ^^!
The other thing is using clojure.spec.test.alpha/check
to generatively exercise an fdef
.
I'm normally in the camp of only test the public interface od your unit. But things are different in Clojure
The unit is at the function level, not the class/namespace. Your private fns should all be pure already, so tests for a pure functions doesn't prevent refactoring the way it does on non pure private class methods
And your IO should either be done by the caller with the data passed in as input, or it should be isolated into private fns that only do the IO, for the latter, mocking those become quite useful
@michael740 I do use it and have seen many people using it when testing private fns. I don't see a harm in it, although I've only done it in very rare cases. Whenever possible I try to either keep fns public but organized in internal namespaces, or test from the API layer only.
Question on file/line metadata attached to forms (not vars) by macros, see thread
I was about to suggest that. There might be a one or two people here who might know, but #clojure channel is better target rich environment for your question, which most people never dig into for Clojure
Hi. I'm using threading (->) and want to divide 1 over the result
(->
10
(/ 1))
Basically I want to get 1/10 but getting 10/1 instead, and I don't want to use (->>) for this case.
I also tried using lambda macro but didn't work (syntax error)
(->
10
#(/ 1 %)) ;Syntax error (ClassCastException) compiling fn*...
Any suggestions?(->> 10
(/ 1))
You can nest ->>
inside ->
(-> x
(stuff)
(->> (/ 1))
(more-stuff))
The reason ->
into #(/ 1 %)
doesn't work is because ->
is a purely syntactic transform, so it it trying to thread the value (`10` here) into the syntactic form for #(/ 1 %)
which is read as (fn [%] (/ 1 %))
so it would produce (fn 10 [%] (/ 1 %))
@baris.aydek Does that help?
oh, now it makes sense. yeah this solves my problem. Thank you!
@baris.aydek Another possibility is this, but I think it's uglier than dropping ->>
into the ->
pipeline:
(-> 10
(#(/ 1 %)))
The extra parentheses mean you get (#(/ 1 %) 10)
after the syntactic transform.i prefer ->>
it's more readable