beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
st3fan 2020-12-21T00:06:13.082900Z

@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)

seancorfield 2020-12-21T00:15:19.083700Z

Hmm, regular ' should work but your tests need to also have the quoted expected form.

seancorfield 2020-12-21T00:16:30.083900Z

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=> 

seancorfield 2020-12-21T00:18:41.084200Z

Yup, just verified that works with lein test @st3fan

seancorfield 2020-12-21T00:20:02.085200Z

(! 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.

zackteo 2020-12-21T01:28:32.086700Z

How do I deal with Unhandled java.lang.NoClassDefFoundError when calling a function from a Clojure library that uses a Java library?

2020-12-21T01:30:42.087300Z

It depends how and where and what class it says isn't defined

2020-12-21T01:31:17.088300Z

The message on the exception will say which class, the stack trace will tell you where

zackteo 2020-12-21T01:35:42.089400Z

org/apache/commons/compress/utils/InputStreamStatistics Do I need to import it somehow?

2020-12-21T01:37:24.091400Z

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

zackteo 2020-12-21T01:38:42.093600Z

Do you mean lein?

2020-12-21T01:38:52.094Z

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

2020-12-21T01:39:45.095200Z

Yes, lein or boot or clj or maven or even by hand

zackteo 2020-12-21T01:41:27.096200Z

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

Domino 2020-12-21T02:10:40.098400Z

@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

Domino 2020-12-21T02:11:20.099500Z

and then run lein deps in the directory of your project to update your dependencies.

zackteo 2020-12-21T02:12:34.101600Z

@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

Domino 2020-12-21T02:13:48.102400Z

@zackteo Wait, are you running the code within the project that you cloned?

zackteo 2020-12-21T02:14:09.102600Z

Yeah

Domino 2020-12-21T02:18:51.107200Z

@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.

zackteo 2020-12-21T02:20:10.108200Z

No no I think You got it confused πŸ˜… my bad. Am trying to work on the library itself

Domino 2020-12-21T02:20:19.108500Z

Ah!

Domino 2020-12-21T02:20:34.109200Z

sorry!

zackteo 2020-12-21T02:21:23.110200Z

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

zackteo 2020-12-21T02:22:15.111400Z

No worries πŸ™‚ Now I know about using lein deps after updating dependencies

zackteo 2020-12-21T02:58:21.113Z

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

dumrat 2020-12-21T05:47:51.113200Z

Hi

dumrat 2020-12-21T05:48:10.113700Z

How do I invoke this code blocking?

dumrat 2020-12-21T05:48:15.113900Z

(go (let [response (&lt;! (http/get "<https://api.github.com/users>"
                                 {:with-credentials? false
                                  :query-params {"since" 135}}))]
      (prn (:status response))
      (prn (map :login (:body response)))))

dpsutton 2020-12-21T05:48:37.114500Z

is this cljs?

dumrat 2020-12-21T05:48:43.114700Z

I don't want any async stuff, it's just that the cljs-https requires this

dumrat 2020-12-21T05:48:44.114900Z

yes

dpsutton 2020-12-21T05:48:53.115100Z

you can't. can't block in javascript

dumrat 2020-12-21T05:49:40.115600Z

ugh

dumrat 2020-12-21T05:49:41.115800Z

ok

dumrat 2020-12-21T05:49:50.116Z

thanks

Jakub Zika 2020-12-21T09:41:07.149900Z

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"}]}]}}
Thanks

holymackerels 2020-12-21T10:49:32.152Z

is 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

holymackerels 2020-12-21T10:51:09.152100Z

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

2020-12-21T11:04:05.152600Z

Are you looking for cartesian-product?

holymackerels 2020-12-21T11:05:57.152800Z

🀦 yes! thanks

πŸ‘ 1
holymackerels 2020-12-21T11:06:32.153100Z

literally couldn't be any clearer in the description > ; all the ways to take one item from each passed-in sequence

yiorgos 2020-12-21T14:38:02.155100Z

what is the most idiomatic or preferable way to read a file in Clojure, using slurp or io/reader?

clyfe 2020-12-21T14:40:34.155400Z

Either; slurp loads it in memory and generally is ok with small files; With reader you can stream operations.

πŸ‘ 2
2020-12-21T14:47:25.155700Z

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

πŸ‘ 3
Domino 2020-12-21T14:59:00.156700Z

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... /s

alexmiller 2020-12-21T14:59:49.156800Z

sets and maps are better choices for lookup than vectors

alexmiller 2020-12-21T15:00:35.157300Z

usually laziness combined with io

alexmiller 2020-12-21T15:00:56.157700Z

like a with-open that returns a lazy seq

Domino 2020-12-21T15:01:37.158100Z

oh, yeah that's literally the thing I'm trying to do

alexmiller 2020-12-21T15:02:16.158700Z

I've seen this movie

Domino 2020-12-21T15:03:05.160600Z

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 πŸ˜•

alexmiller 2020-12-21T15:03:06.160700Z

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

alexmiller 2020-12-21T15:03:53.161100Z

well, if you're doing io and concurrency, you need to think carefully about that

alexmiller 2020-12-21T15:04:40.161800Z

a common pattern is to have one thread that just reads and queues work, then closes when done reading

alexmiller 2020-12-21T15:05:08.162400Z

and "queue" could mean to use future to spin jobs, or use a Java executor, or put work on a core.async channel

valerauko 2020-12-21T15:08:50.164100Z

we use core.async channels for this

Domino 2020-12-21T15:10:54.165800Z

I'll look into that, thanks for the hint! πŸ™‚

0xclj 2020-12-21T15:11:47.166Z

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?

Jakub Zika 2020-12-21T15:17:53.166500Z

I did not consider to use sets for better lookup. Thank you for the idea.

dhd 2020-12-21T16:41:51.167100Z

;; 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]
  (-&gt;&gt; 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")))

hequ 2020-12-21T17:09:00.167800Z

What is the preferred way to handle dates in clojure?

dharrigan 2020-12-21T17:10:32.168700Z

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.

πŸ‘ 2
hequ 2020-12-21T17:12:09.169800Z

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

ryan echternacht 2020-12-21T17:12:32.170300Z

I think using the java8 interop is the preferred way now, especially if you're greenfield

dharrigan 2020-12-21T17:13:03.170800Z

yeah, I would hit the java 8 apis directly now (or java 11, as I'm on that jdk)

dharrigan 2020-12-21T17:13:21.171300Z

I may even spend some time these holidays to do that

hequ 2020-12-21T17:13:31.171600Z

Ok, maybe I’ll try that as well, thanks πŸ™‚

dharrigan 2020-12-21T17:13:36.171800Z

you're most welcome

dhd 2020-12-21T17:25:47.174Z

I asked this question in a thread. Sharing it with the channel.

2020-12-21T18:14:28.174300Z

you are not holding onto the head, because each time you consume a new element from "file-data", the previous element can be freed

2020-12-21T18:15:23.174600Z

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

2020-12-21T18:16:35.174800Z

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

2020-12-21T18:17:09.175Z

> 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

popeye 2020-12-21T19:47:21.177200Z

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

dgb23 2020-12-21T19:50:48.178Z

(re-matches #"^[a-z]+\-$" "abc-")

dgb23 2020-12-21T19:52:26.179Z

assuming you want to match on a string with an arbitrary combination of letters plus a single hyphen at the end.

πŸ™Œ 1
ghosttoaster 2020-12-21T20:16:14.180Z

Is it possible to run a public static main method from a generated class from within a repl?

GGfpc 2020-12-21T20:17:13.180800Z

(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 (&lt; 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?

alexmiller 2020-12-21T20:19:00.181Z

do you mean for there?

alexmiller 2020-12-21T20:19:10.181200Z

or did you mean loop

GGfpc 2020-12-21T20:21:00.181400Z

🀦

GGfpc 2020-12-21T20:21:13.181700Z

Thanks @alexmiller

2020-12-21T20:22:04.181900Z

yes, (ClassName/main (into-array String [arg1 arg2 ...]))

Jean 2020-12-21T20:23:19.182800Z

Hi! It’s possible to use a private git repo with deps.edn?

ghosttoaster 2020-12-21T20:24:30.182900Z

Whoa so you have to have a String array even if its empty?

alexmiller 2020-12-21T20:40:45.183200Z

yes

πŸ™ 1
alexmiller 2020-12-21T20:41:43.183600Z

https://clojure.org/reference/deps_and_cli#_git

πŸ™ 1
2020-12-21T22:32:36.183800Z

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

2020-12-21T22:33:09.184Z

I might be misremembering, shouldn't be hard to try both