This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-01-17
Channels
- # adventofcode (2)
- # beginners (153)
- # cider (14)
- # clara (9)
- # cljs-dev (8)
- # cljsjs (1)
- # cljsrn (4)
- # clojure (124)
- # clojure-dev (9)
- # clojure-france (18)
- # clojure-greece (22)
- # clojure-italy (11)
- # clojure-nlp (5)
- # clojure-russia (9)
- # clojure-spec (21)
- # clojure-uk (40)
- # clojurescript (82)
- # core-async (12)
- # cursive (3)
- # data-science (2)
- # datomic (225)
- # devcards (8)
- # docs (2)
- # duct (1)
- # emacs (18)
- # figwheel (2)
- # fulcro (117)
- # graphql (13)
- # hoplon (10)
- # jobs (7)
- # jobs-discuss (7)
- # keechma (8)
- # leiningen (4)
- # off-topic (16)
- # om (2)
- # om-next (3)
- # perun (11)
- # precept (4)
- # re-frame (24)
- # reagent (2)
- # remote-jobs (8)
- # ring (2)
- # ring-swagger (9)
- # rum (42)
- # shadow-cljs (8)
- # spacemacs (3)
- # specter (7)
- # uncomplicate (10)
- # unrepl (58)
- # yada (9)
Is there any difference between (sequence (filter query-var?) (iterate/tree form))
and just (filter query-var? (iterate/tree form))
where iterate/tree
returns an IReduceInit
?
the second one should create a lazy-seq from (iterate/tree form) before filtering - I wouldn’t expect the return value to be different though
I see, so sequence
creates a seq directly, and is potentially slightly more efficient then?
yeah - and also - corner case - if it implemented IReduceInit and not ISeq the former would work and the second one would fail
but I expect that to be rare ,most things that implement IReduceInit should also give you something you can seq…
ummm let me double check that
oh it would make sense to implement ISeq too unless you know the only consumer is a transducing context
I was just double checking, thanks for confirming
Well, I’m looking at moving most of Cursive’s internal iteration over to transducers so I’m not worried. Implementing ISeq might be useful too, although I think I’d prefer a fail fast in case I’m accidentally using a seq where I didn’t mean to.
that makes sense too, might call for a cautionary doc string or whatever but yeah
maybe ISeq implements ASeq?
I’m still surprised that seq checks for ASeq and not ISeq, though - I’m not sure what the thinking is there.
in general, I don't implement ISeq or Seqable for things I want to process with reduce, which tend to be about controlling backing resource scope, like a collection representing the lines from a file
Yeah, my plan is to move to reduce for pretty much everything I do internally, seqs don’t actually add much value since I’m operating over an AST which is all in memory anyway.
Actually, sequence
can’t be used as I showed above since it still expects a sequable thing as the coll, which makes sense.
@noisesmith So the correct answer is that they both do the same thing - fail 🙂
oh wow - I would have expected sequence to work
Well, if you think about it, converting an IReduceInit to a seq is impossible without fully reducing - they’re different iteration models (push vs pull, if you like)
oh right, you can use a reduce to get a collection from it, but only eagerly so
(ct/is (thrown? AssertionError (assert false)))
does not work as expected. I want a test that says "this piece of code fails due to an assertion [I don't care which exception in particular]"According to https://clojure.github.io/clojure/clojure.test-api.html
(ct/is (thrown? java.lang.ArithmeticException (/ 1 0)))
is supposed to work.
Instead, I get:
(comment
]
[clojure.lang.AFn applyToHelper "AFn.java" 152]
[clojure.lang.AFn applyTo "AFn.java" 144]
[clojure.core$apply invokeStatic "core.clj" 657]
[clojure.core$with_bindings_STAR_ invokeStatic "core.clj" 1965]
[clojure.core$with_bindings_STAR_ doInvoke "core.clj" 1965]
[clojure.lang.RestFn invoke "RestFn.java" 425]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate invokeStatic "interruptible_eval.clj" 85]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate invoke "interruptible_eval.clj" 55]
[clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__1186$fn__1189 invoke "interruptible_eval.clj" 222]
[clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__1181 invoke "interruptible_eval.clj" 190]
[clojure.lang.AFn run "AFn.java" 22]
[java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1149]
[java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 624]
[java.lang.Thread run "Thread.java" 748]]})
(comment
#error {
:cause "Divide by zero"
:via
[{:type java.lang.ArithmeticException
:message "Divide by zero"
:at [clojure.lang.Numbers divide "Numbers.java" 163]}]
:trace
[[clojure.lang.Numbers divide "Numbers.java" 163]
[clojure.lang.Numbers divide "Numbers.java" 3833]
[aa.abcd$eval8596 invokeStatic "NO_SOURCE_FILE" 31]
[aa.abcd$eval8596 invoke "NO_SOURCE_FILE" 31]
[clojure.lang.Compiler eval "Compiler.java" 7062]
[clojure.lang.Compiler eval "Compiler.java" 7025]
[clojure.core$eval invokeStatic "core.clj" 3206]
[clojure.core$eval invoke "core.clj" 3202]
[clojure.main$repl$read_eval_print__8572$fn__8575 invoke "main.clj" 243]
[clojure.main$repl$read_eval_print__8572 invoke "main.clj" 243]
[clojure.main$repl$fn__8581 invoke "main.clj" 261]
[clojure.main$repl invokeStatic "main.clj" 261]
[clojure.main$repl doInvoke "main.clj" 177]
[clojure.lang.RestFn invoke "RestFn.java" 1523]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__1141 invoke "interruptible_eval.clj" 87)
@qqq - works for me only inside deftest, e.g. this fails:
$ lein repl
nREPL server started on port 62317 on host 127.0.0.1 -
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_112-b16
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e
user=> (require '[clojure.test])
nil
user=> (clojure.test/is (thrown? java.lang.ArithmeticException (/ 1 0)))
#error {
:cause "Divide by zero"
:via
[{:type java.lang.ArithmeticException
:message "Divide by zero"
:at [clojure.lang.Numbers divide "Numbers.java" 158]}]
:trace
[[clojure.lang.Numbers divide "Numbers.java" 158]
[clojure.lang.Numbers divide "Numbers.java" 3808]
[user$eval7323 invokeStatic nil 1]
[user$eval7323 invoke nil 1]
[clojure.lang.Compiler eval "Compiler.java" 6927]
[clojure.lang.Compiler eval "Compiler.java" 6890]
[clojure.core$eval invokeStatic "core.clj" 3105]
[clojure.core$eval invoke "core.clj" 3101]
[clojure.main$repl$read_eval_print__7408$fn__7411 invoke "main.clj" 240]
[clojure.main$repl$read_eval_print__7408 invoke "main.clj" 240]
[clojure.main$repl$fn__7417 invoke "main.clj" 258]
[clojure.main$repl invokeStatic "main.clj" 258]
[clojure.main$repl doInvoke "main.clj" 174]
[clojure.lang.RestFn invoke "RestFn.java" 1523]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__5508 invoke "interruptible_eval.clj" 87]
[clojure.lang.AFn applyToHelper "AFn.java" 152]
[clojure.lang.AFn applyTo "AFn.java" 144]
[clojure.core$apply invokeStatic "core.clj" 646]
[clojure.core$with_bindings_STAR_ invokeStatic "core.clj" 1881]
[clojure.core$with_bindings_STAR_ doInvoke "core.clj" 1881]
[clojure.lang.RestFn invoke "RestFn.java" 425]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate invokeStatic "interruptible_eval.clj" 85]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate invoke "interruptible_eval.clj" 55]
[clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__5553$fn__5556 invoke "interruptible_eval.clj" 224]
[clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__5548 invoke "interruptible_eval.clj" 192]
[clojure.lang.AFn run "AFn.java" 22]
[java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1142]
[java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 617]
[java.lang.Thread run "Thread.java" 745]]}
but this works:
user=> (clojure.test/deftest foo (clojure.test/is (thrown? java.lang.ArithmeticException (/ 1 0))))
user=> (clojure.test/run-tests)
Testing user
Ran 1 tests containing 1 assertions.
0 failures, 0 errors.
{:test 1, :pass 1, :fail 0, :error 0, :type :summary}
… which is all new to me. I’ve never tried to evaluate is
outside a test definition.
@gonewest818: TIL I have been using ct/is wrong this whole time
¯\(ツ)/¯
Hi, how to elegantly remove leading
elements that not satisfies some condition from a sorted
vector in Clojure?
Currently I use for
to do this, but this will run the judging function for every leading elements that does not satisfies this condition in the vector. I think that must be some O(logN) method, like dichotomy.
(drop-while #(not (satisfied? %)) sorted-vector)
there’s split-with
although that actually runs two passes, one with drop-while and one with take-while
no, nothing does bisection in core
but it’s probably just a few lines of code to write it yourself
something along these lines is pretty close
(defn bisect
[v pred]
(loop [low 0, high(count v)]
(if (< low high)
(let [mid (quot (+ low high) 2)]
(if (pred (nth v mid))
(recur low mid)
(recur (inc mid) high)))
(split-at low v))))
depending on the sense of your predicate you may need to not
the pred or flip the inner recurs
what is the standard way/work-around in clojure to propagate exception via a promise? assuming I do not want to use a sentinel in the returned value nor a future for that?
I think you’ve successfully ruled out all the options :)
@alexmiller what was the reason for not implementing this in promise
?
promise conveys a value - how do you convey an exception?
Clojure promises are pretty old and simple and pre-date a lot of what has happened in js and other places
some people use http://funcool.github.io/promesa/latest/ - maybe that would have more stuff to your liking
another option to take a look at is https://github.com/ztellman/manifold
I looked at git blame and Clojure promise
code hasn’t been touched since ’09 :)
actually, that’s not true, was first implemented in ’09 but was updated as recently as ’11
java.util.concurrent.Future supports this so I was surprised that clojure did not have something alike in core.
Hi, whats the clojure equivalent of LongWritable.class
?
For those which work with Kafka or would like to, would you use avro or spec + nippy (https://github.com/ptaoussanis/nippy)?
Depends, avro has good cross language support, nippy is purely clj and not really specified in any way so it can be tricky if you need to later use another lang with your data. Transit could be a contender but I never used it myself.
@pfeodrippe We have used nippy
But we have specifically only done it on those topics were we need high speed, and where the data has a very short lifetime
So if we ever wanted to change language we could rebuild the existing data in some other format realtively quickly
can you delete data permanently in Datomic (for legal reasons) ?
...i.e. European privacy law
Going with Avro because our data is more long-term and it has better Kafka support
I am getting the following response from my frontend server:
:status 0, :success false, :body "", :headers {}, :trace-redirects [" " " "], :error-code :http-error, :error-text " [0]"}
but I see my backend server processing and returning the correct response. I am using composure and [cljs-http.client :as http]
What am I doing wrong?@pfeodrippe I also recommend looking into CBOR
As far as schema-less serializers go, it's very fast and very well supported across a variety of languages
We interact between a couple of languages which took nippy and fressian out of the picture
@cmal if the offending items are guaranteed to all be at the front of a sorted-set, this sounds like a perfect case for subseq which takes a condition and returns the items on the right side of the coll
and if you literally mean “sorted vector” consider using sorted-set which uses a tree (which is what makes that subseq function efficient)
hey folks, what's the lein equivalent of mvn clean install -DskipTests
? Mostly jsut the skipTests part.
I thought that 'lein clean install' without mentioning the word 'test' anywhere should do that.
You're right. That was easy. Thanks!
Almost... 'lein clean' followed by 'lein install' does it, but I've forgotten the syntax for combining multiple lein tasks in a single command.
@pyr Gonna take a look, thanks!!
Where can I go to look at the implementation of structural sharing in clojure? I want to play around with implementing it in rust 😂
there’s no single implementation, each collection type has it’s own version of the cons method
the key is that it can’t work unless you know the collection is immutable
@tjtolton the simplest version is the linked list - it shares structurally if you cons a new item on the front, because it reuses the entirety of the existing list as the tail
this is so trivial in rust it likely exists already 😄
https://www.amazon.com/Purely-Functional-Structures-Chris-Okasaki/dp/0521663504 is good theoretical reading on this topic, @tjtolton
yes, that is THE book on the topic, and Rich used it as a reference
Lots of examples and exercises using ML, but you could adapt the examples to Rust and then do the exercises.
@tjtolton another good intro is the series of blog posts starting here http://hypirion.com/musings/understanding-persistent-vector-pt-1
oh thats perfect. the persistent vector is actually specifically the one I was thinking of when I asked the question
@tjtolton i think this is the paper rich based his implementation on: https://infoscience.epfl.ch/record/64398/files/idealhashtrees.pdf
I don't think Okasaki claims to be as optimized as possible, but it's a great read for how to think about this stuff.
@sundarj yes, but I think it’s useful to start with the clear theoretical premise, then move to the efficient optimization
@noisesmith that's true
the hypirion link I posted above references the Bagwell paper
Per https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/EffectivePrograms.md, Bagwell invented the data structure, Rich made it “persistent”, aka “functional” in the Okasaki sense.
It has been a while since I read the Okasaki book, or parts of it. It seems to restrict itself to implementations that can be done in a purely functional language, including the implementation of the data structures.
The Clojure implementations add something that I haven't seen anywhere else (but could be for lack of looking) - transients. The idea being - it is ok for an implementation of an immutable data structure to use mutation, which can make more efficient implementations possible, and/or easier to write, and you can choose to hide that from the interface/API level, so that above that you only see immutable.
Actually that last message of mine is perhaps conflating two things that can be separated. (1) you can take advantage of mutability in implementation of immutable data structures. That is likely from Bagwell's work. (2) transients are something I haven't seen elsewhere yet, and allow mutability-for-the-sake-of-efficiency to peek its head above the Clojure API/interface level, so programs written purely in Clojure can take advantage of the efficiency in some special cases.
anyone know of any distributed task submission/retry/reporting frameworks that're fun in clojure
yeah, you can still use transients and maintain the referential transparency of the api function, as long as the transient stays in the function's scope
I don't think I've seen any cases yet where transients needed to be directly used in production code though, mostly just indirect usage through into
or similar
Sombody who use yesql, can explain how build project without connection into db?
@fantomofdoom if you're creating a new project (or don't have a ton of yesql anyways), you might consider using https://www.hugsql.org/ which is actively maintained (unlike yesql) and by default requires the connection passed in at runtime to the generated functions
Is there any integration of spec
with web API?
I mean, if we spec
the args of a function (or route), we could expose that spec as an endpoint,
something like graphql
.
@itaied perhaps some of the (in development) v2 stuff in https://github.com/metosin/compojure-api ?