@seancorfield so i have something to explore to do here regarding testing macros .. my test worked fine in the repl, but not when running lein test
- I fixed that by changing the quote for macroexpand from ' to ` (hard to write in slack)
Hmm, regular ' should work but your tests need to also have the quoted expected form.
dev=> (require '[clojure.test :refer [deftest is]])
nil
dev=> (macroexpand '(when a b))
(if a (do b))
dev=> (deftest when-test
(is (= '(if a (do b))
(macroexpand '(when a b)))))
#'dev/when-test
dev=> (when-test)
nil
dev=>
Yup, just verified that works with lein test
@st3fan
(! 999)-> lein new st3fan
Generating a project called st3fan based on the 'default' template.
The default template is intended for library projects, not applications.
To see other templates (app, plugin, etc), try `lein help new`.
(! 1000)-> cd st3fan/
(! 1001)-> vi test/st3fan/core_test.clj
(! 1002)-> cat test/st3fan/core_test.clj
(ns st3fan.core-test
(:require [clojure.test :refer :all]
[st3fan.core :refer :all]))
(deftest when-test
(is (= '(if a (do b))
(macroexpand '(when a b)))))
(! 1003)-> lein test
lein test st3fan.core-test
Ran 1 tests containing 1 assertions.
0 failures, 0 errors.
How do I deal with Unhandled java.lang.NoClassDefFoundError
when calling a function from a Clojure library that uses a Java library?
It depends how and where and what class it says isn't defined
The message on the exception will say which class, the stack trace will tell you where
org/apache/commons/compress/utils/InputStreamStatistics
Do I need to import it somehow?
You don't need to import it, but it needs to be on the class path, the exact details will depend on the tools you are using
Do you mean lein?
If it is a dependency of the library you using, typical whatever tools you are using will pull in the entire dependency tree and build a class path from it
Yes, lein or boot or clj or maven or even by hand
Could you link me to how I can do this? I've a feeling it might be related to me trying the library by cloning it - am trying https://github.com/zero-one-group/fxl btw
@zackteo if you're using lein, you have to put [zone.one/fxl "0.0.5"]
in your :dependencies
in your project's project.clj
and then run lein deps
in the directory of your project to update your dependencies.
@ricardolopez.zagal I am running the code from within the project. It seems to have to do with cider actually ... am able to run my code within lein repl
and using calva
@zackteo Wait, are you running the code within the project that you cloned?
Yeah
@zackteo You don't need to clone dependencies using git
Lein does it for you from clojars using lein deps
if you you create a project using lein new foo
, and you put [zone.one/fxl "0.0.5"]
inside project.clj, and run lein deps
, you'll be able to use the repl and to make your project using that dependency
It's way more practical than cloning the dependencies from git, specially if you have to use multiple dependencies.
No no I think You got it confused π my bad. Am trying to work on the library itself
Ah!
sorry!
And my mini-test for the function seems to work within a basic lein repl
and from calva. So it appears that cider might be doing something that causes some issues :x
No worries π Now I know about using lein deps
after updating dependencies
Okay got it fixed ... Think it has to do with me not updating cider because I was on emacs native-comp and doom emacs stop supporting the version I was on
Hi
How do I invoke this code blocking?
(go (let [response (<! (http/get "<https://api.github.com/users>"
{:with-credentials? false
:query-params {"since" 135}}))]
(prn (:status response))
(prn (map :login (:body response)))))
is this cljs?
I don't want any async stuff, it's just that the cljs-https requires this
yes
you can't. can't block in javascript
ugh
ok
thanks
Hello, what do you think is the better representation of database structure. Both ways have trade-offs, no?
{:db1
{:tables
{"public.people"
{:columns {"id" {:data_type "int"}
"name" {:data_type "string"}}}}}}
or (more clojure.jdbc native)
{:db1
{:tables [
{:table_name "public.people"
:columns [
{:column_name "id" :data_type "int"}
{:column_name "name" :data_type "string"}]}]}}
Thanksis there a way in clojure.math.combinators
to get all of the permutations by taking one from each list in a list-of-lists? for example:
;; getting from this
[[:a1 :a2] [:b1 :b2]]
;; to these
:a1 :b1
:a1 :b2
:a2 :b1
:a2 :b2
I've considered getting the permutations of the indexes, like (permutations [0 0 1 1])
and then using them as indexes in each inner list, so when theres 3 inner lists each with 2 items it'd be the permutation of [0 0 0 1 1 1]
as indexes
Are you looking for cartesian-product?
π€¦ yes! thanks
literally couldn't be any clearer in the description > ; all the ways to take one item from each passed-in sequence
what is the most idiomatic or preferable way to read a file in Clojure, using slurp
or io/reader
?
Either; slurp loads it in memory and generally is ok with small files; With reader you can stream operations.
slurp is using http://clojure.java.io/reader internally in with-open context so slurp will close reader after consuming all the content. if you are using http://clojure.java.io/reader explicitly do not forget to close the reader after you finish processing otherwise this could lead to memory leaks
Exception in thread "Thread-8" java.io.IOException: Stream closed
at java.io.BufferedReader.ensureOpen(BufferedReader.java:122)
at java.io.BufferedReader.readLine(BufferedReader.java:317)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at clojure.core$line_seq.invokeStatic(core.clj:3091)
at clojure.core$line_seq$fn__5970.invoke(core.clj:3092)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:51)
at clojure.lang.LazySeq.equals(LazySeq.java:121)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:167)
at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:102)
at malachite_mk1.core$concurrent_collision$fn__318.invoke(core.clj:118)
at clojure.lang.AFn.run(AFn.java:22)
at java.lang.Thread.run(Thread.java:748)
#object[java.lang.Thread 0x64864f7e "Thread[Thread-9,5,main]"]
Oh boy, this is going to be fun to debug...
/ssets and maps are better choices for lookup than vectors
usually laziness combined with io
like a with-open that returns a lazy seq
oh, yeah that's literally the thing I'm trying to do
I've seen this movie
Like, I'm trying to read a file line by line This works fine in the non-concurrent version of the function, but it returns this error in the concurrent one π
either return something eager (often with into
) or invert the control and pass the thing you want to do with the lazy seq into the with-open so it's completed in scope
well, if you're doing io and concurrency, you need to think carefully about that
a common pattern is to have one thread that just reads and queues work, then closes when done reading
and "queue" could mean to use future
to spin jobs, or use a Java executor, or put work on a core.async channel
we use core.async channels for this
I'll look into that, thanks for the hint! π
At my current work, the variables we use seem to be max 3 characters, like lid, pid, mv
etc. which I find are uninterpretable. When querying about it, I was told it was because we use the NoSQL document storage and short names like that help save cost.
Can anyone with the relevant experience (Mongo or Azure CosmosDB) comment on that rationale?
I did not consider to use sets for better lookup. Thank you for the idea.
;; I have a question similar to domino's, but i am trying to understand lazy-seqs and not run into OOM issue. ;; Say I read the file in memory. I now need to transform/parse the data and then put this data into multiple sinks (database/streamin platform/search engine ...). IE, all the data needs to end up in all the sinks. ;; So i do this with map/filter and make it lazy. In the end I need to realize the sequence in order to store it into the sink(s). Form what i understand about lazy-seqs, i need to avoid holding onto the head of the lazy-seq. ;; But I am not sure what this really means. ;; In this example, am i holding onto the head of the lazy-seq? -- ;; sinks are partial functions which are configured with database config info
(defn transform-data [file-data]
(->> file-data
(map ransform1)
(map transform2)
(filter filter1)
(map transform4)))
;; I think I am holding onto the head here. When I go an sink the data into the first sink, I am realizing the data
and it cannot get garbage collected because there are still other sinks
remaining to process the data
. Is this correct?
(def sink-all-data [sinks data]
(doseq [sink sinks]
(sink data)))
(sink-all-data partial-sinks (transform-data (data-from-file "/foo/large-file.txt")))
What is the preferred way to handle dates in clojure?
I use <https://github.com/dm3/clojure.java-time>
atm, but if I was to do anything new, I would probably just use the java date time classes directly (if on java 8+) as they are nice to use and interop works really well.
I was looking at that library as it seems nice but thought that maybe I ask first if people use any libraries or directly java8 api
I think using the java8 interop is the preferred way now, especially if you're greenfield
yeah, I would hit the java 8 apis directly now (or java 11, as I'm on that jdk)
I may even spend some time these holidays to do that
Ok, maybe Iβll try that as well, thanks π
you're most welcome
I asked this question in a thread. Sharing it with the channel.
you are not holding onto the head, because each time you consume a new element from "file-data", the previous element can be freed
the head of a lazy seq is the first element, there's nothing in that code that points to the first element of the seq and escapes scope
now file-data itself could be the head of a lazy seq, that means the culprit isn't the code you shared, it's the code that creates a lazy-seq from the input and returns the first element
> Say I read the file in memory. the point is to avoid this - to find a way that the entire file doesn't need to be in memory
Team, (re-matches #"^[a-z\-]+$" "abc--") will give us the result, But if i send 2 hypen it should return nil, How can I achieve this
(re-matches #"^[a-z]+\-$" "abc-")
assuming you want to match on a string with an arbitrary combination of letters plus a single hyphen at the end.
Is it possible to run a public static main method from a generated class from within a repl?
(defn get-user-books
"Retrieves a user's books"
[user consumer token]
(for [i 1
books {}]
(let [response (obtain-books i)
updated-books (conj books response)]
(if (< 50 (count response))
updated-books
(recur updated-books (inc i))))))
This code fails to compile with Can only recur from tail position
but isn't recur the last statement?do you mean for
there?
or did you mean loop
π€¦
Thanks @alexmiller
yes, (ClassName/main (into-array String [arg1 arg2 ...]))
Hi! Itβs possible to use a private git repo with deps.edn
?
Whoa so you have to have a String array even if its empty?
yes
you can provide an empty string array, but varargs are treated as arrays on a byte code level, and unlike java clojure makes no attempt to hide this
I might be misremembering, shouldn't be hard to try both