Fork me on GitHub

What is the use case of type function when there is class? When it's useful to put :type on something's metadata?


since you can "type" anything supporting metadata I guess one answer could be that it's useful with multimethods dispatching via (type ... )

๐Ÿ‘ 4

oh, makes sense

Ivan Koz18:05:09

is there any book or written series about clojure compiler?

Alex Miller (Clojure team)18:05:57

wish I had the time to write such a thing :) in a broad sense, the clojure compiler is just translating a relatively small set of possible expressions to java bytecode, and as such is pretty simple as far as compilers go


I would buy this day one ๐Ÿ™‚

Alex Miller (Clojure team)18:05:58

well, don't hold your breath

๐Ÿ‘ 4
Alex Miller (Clojure team)18:05:53

there's essentially no optimization - really Clojure leans on the JIT rather than doing much itself

Alex Miller (Clojure team)18:05:30

fortunately, the jvm is pretty great at it


the defn podcast with the guy working on ClojureCLR was super interesting. he went into differences between JVM and CLR and how one could optimize things for one over the other

๐Ÿ‘‚ 4

This was really good

Ivan Koz18:05:01

yeah i've seen this one few days ago


The nice thing about the clojure compiler is that it's a one pass translator to bytecode


Anyone else have this issue? I'm using the Clojure CLI and have dependency that is a git repo. If I try to update the sha I get this error.

Destination path "my-repo" already exists and is not an empty directory
org.eclipse.jgit.api.errors.JGitInternalException: Destination path "my-repo" already exists and is not an empty directory


I'm also having a hard time finding exactly where the code gets checked out.


I've had that error before and I haven't been able to pinpoint it, but I remember something about auth


All the files go in .gitlibs @ozanzal


Hello guys, i'm writing tests for an async function that uses future But in order to test it, i need to know when the background process have finished, but because it's async i have a return value right when i call it. How can i handle this situation?

Ivan Koz18:05:08

@cybersapiens97 check future-done? function


there's also realized?

Ivan Koz18:05:01

whats the difference?


I think realized? is more general though (but I've heard multiple warnings about using it on lazy things)


realized? works on promises, delays, futures, and lazy-seqs


and from what I hear, using it on lazy-seqs is a bad code smell

Ivan Koz18:05:36

i mean if we have realized why do we have more specific future-done?


principle of least power I guess - also it uses the java Future api, and not the IPending api so it works on java futures, not just clojure's specific implementation of futures


every clojure future isa java.util.concurrent.Future, but not every j.u.c.Future is a clojure future


well, i can use future-done? but still i have to supply a Thread/Sleep ? or i can use something like this await-for ?


@cybersapiens97 what do you want to do if the future takes to long?

Ivan Koz18:05:59

realized is bound to be used for IPending implementors


if you always want to wait for it, just use deref / @


if you want to timeout, that's an optional arg to deref


@noisesmith nothing, the test will fail i guess


in neither case do you actually need to explicitly check if it is realized


@cybersapiens97 then I'd use deref, with the timeout arg (how long is too long? probably more than 0 ms...) then use the timed-out value as your failure condition in the check



(ins)user=> (let [f (future (Thread/sleep 1000) ::OK)] (deref f 500 ::failure))
(ins)user=> (let [f (future (Thread/sleep 1000) ::OK)] (deref f 5000 ::failure))

Ivan Koz18:05:55

was about to write that snippet ๐Ÿ˜„


so, deref waits for the future to be done?

Ivan Koz19:05:06

yes it blocks


yes, by default it blocks, but with the extra arg it has a timeout


there's also future-cancel, if you know your code calls some cancellable method


nice to know, async is something i didn't really used before on clojure or other langs

Ivan Koz19:05:25

try core.async also, it provides a nice way to build concurrent applications


don't think i need that much, it was just a function that needed to be async because it's just a HTTP response 201, Accepted and being processed


(deftest download-musics--return-file-string
  (let [result (deref (core/download-musics test-links) 180000 ::failure)
        _      (shell/sh "unzip" result :dir core/resources-folder)]
    (is (string? result))
    (is (.exists (io/as-file (str core/resources-folder result))))
    (is (= (+ 1 (count test-links)) ;; This is because file-seq add's the own arg folder at the beginning of the seq
           (count (file-seq (io/file (str core/resources-folder (subs result 0 (- (count result) 4))))))))))

Uncaught exception, not in assertion.
expected: nil
  actual: java.lang.ClassCastException: class java.lang.String cannot be cast to class java.util.concurrent.Future (java.lang.String and java.util.concurrent.Future are in module java.base of loader 'bootstrap')
@noisesmith what i'm doing wrong here?

Jimmy Miller20:05:08

Can you post the source of core/download-musics?

Joe Lane19:05:15

Does core/download-musics return a ref or a string?

Joe Lane19:05:10

The error message youโ€™re getting is because youโ€™re trying to treat a string (the result) as a ref (like an atom)


but i can't really change the behavior of this function and it's output, guessing if i could make a wrapper that returns some kind of ref?


you can change download-musics but not the deftest?


i can change deftest but not download-musics


it's output goes directly to a handler that returns an HTTP response based on it, and using a ref as return value would break the response pattern that i'm using for all my functions


why does the deftest try and deref it?


because download-musics is async and i need to wait the background process to finish


deref blocks the main thread until it's done, but i didn't know that it expects a ref, or, i knew it but i forgot ๐Ÿ˜ž


according to the error, you don't


it's returning a string. not a future


yes, because i need an immediate response from this function, in this case, a string


i'm struggling to write a test for it


it sounds like you should remove the deref


I dont' really understand what's going on. are you redefing the download-musics to just return a string or something?


download-musics is an async function, which returns a string. Inside it's body, there is a future, to do the background work (download the musics), but i need an immediate response of where this musics are going to be stored, so it returns the string (the name of the zip file that will be created). all i need is to write a test that waits the completition of the future inside it's body, so i can test it propperly


guess i'll need to write a simple Thread/Sleep for now, just to write the test and refactor it later


no idea. either download-musics returns a string synchronously, or it returns a future that resolves with a string. I donโ€™t understand your test


@cybersapiens97 one pattern for what you are doing is to return a hash-map, eg. {:f the-future :s the-string} so a client can use the parts of the result that matter

๐Ÿ‘ 4

if the consumer needs a string, you can make a thin wrapper that just pulls the string out, but you can use the real return value in your test


you don't really need a unit test for a function that does nothing but a single key lookup


Sorry for silly question, but can you suggest me, what project I can create and share on github, to make any interest to my person as a remote employee (keeping in mind, that I live in Russia). If it is possible, of course ๐Ÿ™‚