Fork me on GitHub
#clojure
<
2017-11-03
>
cpmcdaniel01:11:28

so, let’s say I have used reify on an interface and it closes over on of my Clojure functions. At the REPL, I want to be able to redefine my fn and have the reified object call it. I assume a layer of indirection will do the trick, but what is the best way to achieve this? Use resolve first to get the fn and then invoke it?

tbaldridge01:11:45

@cpmcdaniel call the functions like this (#'foo x y) instead of (foo x y)

tbaldridge01:11:08

Although vars work that way already

qqq01:11:00

how do I express the following in clojure: 1. I have a job queue with 1000 items 2. I have 12 worker threads 3. whenever a worker thread finishes a job, it pops off the next job from the queue, and executes it

Alex Miller (Clojure team)02:11:07

Java has an ExecutorService that is a great match for this but you would use interop for it

Alex Miller (Clojure team)02:11:45

Which is a Clojurey wrapper for it

qqq02:11:13

I'm using the ExecutorService. How do I call 'sxubmit' on a clojure function? The problem is that it appears to match both Collable and Runnable ... (fn [] ...)

Alex Miller (Clojure team)02:11:04

Add a type hint to disambiguate

qqq02:11:35

(def #^Runnable r (proxy [Runnable] [] (run [] (rand)))) <-- does your solution avoid the 'proxy' ?

Alex Miller (Clojure team)02:11:28

You don’t need a proxy

qqq02:11:31

(.submit service 
               ^Runnable
               (fn [] 
                ...))
appears to work

Alex Miller (Clojure team)02:11:59

All Clojure functions are Runnable

qqq02:11:50

everything works now; thanks for help

zignd03:11:02

in The Joy of Clojure there's a passage stating: > Clojure functions are highly amenable to interoperability. Their underlying classes implement a number of useful interfaces does it means that the Clojure compiler wraps Clojure functions into Java classes that under the hood implement some interfaces or something like that?

zignd03:11:42

qqq's message reminded me of it

seancorfield03:11:26

@zignd Yes, each function is compiled to a class with a number of methods.

seancorfield03:11:15

@zignd Here's the ancestors of a function type:

boot.user=> (defn foo [x] (inc x))
#'boot.user/foo
boot.user=> (class foo)
boot.user$foo
boot.user=> (ancestors *1)
#{java.util.Comparator clojure.lang.AFunction clojure.lang.IMeta java.io.Serializable clojure.lang.Fn java.lang.Runnable java.util.concurrent.Callable clojure.lang.IFn java.lang.Object clojure.lang.AFn clojure.lang.IObj}
The function compiles to a class called, in this case, boot.user$foo (an inner class foo in the boot.user class which the namespace is compiled to), and it extends/implements all of those listed classes.

zignd03:11:51

@seancorfield Interesting, so the namespace is also compiled into a class, at least that's what it seems from your example. Does it mean that if I was to create a namespace with gen-class its methods would be defined in the boot.user class for example and not in an inner class?

seancorfield03:11:18

The methods would be defined in the class of the namespace yes (and gen-class lets you specify the class name if you want a different one).

seancorfield03:11:04

It's why the default application you often see has a (gen-class) in whatever/core.clj and a -main function -- and that's compiled to a whatever.core class with a main method (the - is the default convention for gen-class).

zignd03:11:25

Woah, I didn't know that, -main makes sense for me now :D

zignd03:11:46

Thanks for your explanations @seancorfield!

seancorfield03:11:05

Also note that anonymous functions get compiled to "unique" class names

boot.user=> (defn quux [n] (fn [m] (* m n)))
#'boot.user/quux
boot.user=> (def times2 (quux 2))
#'boot.user/times2
boot.user=> (type times2)
boot.user$quux$fn__1879

seancorfield03:11:01

In this case quux is compiled to an inner class inside boot.user, and the anonymous function is compiled to an inner class called fn__1879 inside the quux inner class.

zignd03:11:56

Nice, it gets deeper and deeper.

seancorfield03:11:03

Functions, all the way down 🙂

joost-diepenmaat14:11:46

I’m trying to solve an issue we have testing a largish project with lein test; occasionally the test run halts with `Tests failed. Error encountered performing task ‘test’ with profile(s): ‘base,system,user,provided,dev,humane-errors’ Tests failed.`

joost-diepenmaat14:11:26

I just cannot get it to be more verbose than that. We’re running this on CircleCI in a docker container and the last test namespace to run seems to be one that contains some clojure.spec generative tests

joost-diepenmaat14:11:45

other than that no clue. Does anyone have any idea on how I can figure out which test in the test namespace was the last one run or any idea on what the problem might be?

Garrett Hopper18:11:40

Is there any idiomatic way of getting a map from a sequence of keys (with a value associated with each key based on the key)?

Garrett Hopper18:11:00

(into {}
              (map (fn [a]
                     [a (derived-value a)])
                   [:alpha :bravo :charlie :delta :echo]))

taylor18:11:14

I suppose you could replace that fn with (juxt identity derived-value) but that’s not necessarily any better

Garrett Hopper18:11:59

Huh, I hadn't thought about that. Thanks

hiredman18:11:46

into takes a transducer theses days

hiredman18:11:06

(into {} (map (juxt ...)) ...)

Garrett Hopper18:11:24

@hiredman Nice, that is pretty concise. (into {} (map (juxt identity (partial str :test))) [:a :b :c])

Garrett Hopper18:11:24

@hiredman Nice, that is pretty concise. (into {} (map (juxt identity (partial str :test))) [:a :b :c])

Alex Miller (Clojure team)18:11:54

(zipmap a (map derived-value a))

Garrett Hopper18:11:29

@alexmiller That certainly works, though I was looking for something that doesn't repeat a or require binding it.

Alex Miller (Clojure team)18:11:38

(apply zipmap ((juxt identity #(map derived-value %)) a))

Garrett Hopper18:11:04

Which is awful? 😛

Alex Miller (Clojure team)18:11:12

the apply / juxt version

Alex Miller (Clojure team)18:11:35

the simple zipmap one is far and away the clearest of these imo

Garrett Hopper18:11:00

Yeah, I'd agree.

Garrett Hopper18:11:40

@alexmiller Good call; zipmap feels cleaner in my actual use case as well.

Garrett Hopper18:11:52

(Compared to into/map/juxt)

Alex Miller (Clojure team)18:11:21

unfortunately, the implementation of zipmap is not as fast as it could be atm, although in the majority of cases you won’t have enough data for it to make any difference

Garrett Hopper18:11:41

Yeah, there's only 7 keywords.

Garrett Hopper18:11:47

Good to know though.

eriktjacobsen18:11:38

I prefer the zipmap, though I want to give lip-service to medley.core which has map-vals to get rid of the the (into {} (map... nastiness, such as

(map-vals derived-value (zipmap a a))
It's an extra step, but separating the steps of creating a self-keyed map might be a helpful pattern elsewhere

Alex Miller (Clojure team)18:11:08

oh sure, I agree that’s the intent

Alex Miller (Clojure team)18:11:39

I wish we had map-keys / map-vals in core

jeff.terrell18:11:55

Out of curiosity, why don't we?

Alex Miller (Clojure team)19:11:01

b/c we consider new things for core somewhat rarely and I haven’t gathered the evidence to make a compelling case yet :)

jeff.terrell19:11:45

Fair enough. simple_smile Ah, thanks for the link, that was my next question.

Alex Miller (Clojure team)19:11:12

I wrote map-keys into tools.deps.alpha this week :)

karan19:11:27

just seeing this, but my 2c — I happened to write map-keys, map-vals, and, just a couple days ago, map-kv in a utils library @alexmiller

karan19:11:39

where map-kv takes a function of arity-2

Alex Miller (Clojure team)19:11:42

oh sure, there are lots of them out there :)

Alex Miller (Clojure team)20:11:58

they vary widely in quality and generality though which is why it’s not as obvious as you may think on what to add

qqq19:11:04

(ImageIO/write (BufferedImage. 10 10 BufferedImage/TYPE_USHORT_GRAY)
               "jpg"
               (  "test.jpg"))
^-- this returns false . How do I debug this ?

toastbox19:11:39

I'm attempting to call some Clojure code from a Java project. It seems that when I attempt to do an "import clojure.java.api.Clojure;", it succeeds when I'm pulling org.clojure/clojure 1.7.0 (via Maven), but fails when I pull org.clojure/clojure 1.8.0 since the Clojure class apparently no longer exists. Has this Clojure class been deprecated/moved? (or is there a better way to call Clojure code from Java?)

bfabry19:11:43

specter also has MAP-VALS and MAP-KEYS navigators

toastbox19:11:02

I suppose I should clarify that my goal is to call code from a library written in Clojure -- so I may be barking up the wrong tree with my approach.

noisesmith19:11:41

the docs say you should use clojure.java.api.Clojure - I don’t see why it wouldn’t find that with 1.8 so I suspect something else is wrong

noisesmith19:11:56

and I can verify I’ve used clojure 1.8 via clojure.java.api.Clojure in java code

toastbox19:11:25

Those are the docs I worked with initially (and then searched around to find some people with the import statements as well)

toastbox19:11:47

Hmm. Knowing that it's working for you with 1.8 should be helpful -- maybe I'll just have to wipe my .m2 repo

toastbox19:11:05

it is odd that it has only worked for me when I'm pulling 1.7

derpocious19:11:20

hey all, can I ask a very n00b clojure question?

noisesmith19:11:23

@derpocious you don’t have to ask to ask, and there’s a #beginners channel you can use at your discretion

toastbox19:11:02

@noisesmith Hmm. Apparently, Eclipse simply tells me clojure.java.api.Clojure doesn't exist when I'm pulling 1.8.0 (and it results in spurious error indicators everywhere), but it actually works fine. I don't have that problem when I pull 1.7.0.

derpocious19:11:08

But if I ask in the #beginner room then won't it just be all beginner there and no one to help me? 😛

noisesmith19:11:23

@aletts well that’s weird

manutter5119:11:07

@derpocious Oh no, there’s lots of folks that go there looking for people to help

toastbox19:11:11

@noisesmith Actually - I stand corrected. The error indicators disappeared - seems I rebuilt/ran too fast. Cleaning my .m2 org/clojure stuff may have been the solution. Thanks.

yogidevbear20:11:07

Does anyone know if there is a website / post that outlines some of the main Clojure libraries (e.g. Ring, Compojure, Yada, http-kit, Aleph, etc), what each one does and how they similar / differ to each other, which are currently preferred, etc.?

gdeer8120:11:23

if it doesn't exist it would be an interesting project

yogidevbear20:11:13

I know JUXT have the Clojure Radar

gdeer8120:11:01

I tried to write something similar except it took into account the participation in the community of the library author. I got stuck on the calculating library author scores

yogidevbear20:11:54

Actually, that looks like a good overview

phronmophobic20:11:03

not sure how up to date it is

yogidevbear20:11:57

Thanks Adrian 👍 That's a pretty large list of libraries

noisesmith20:11:44

I thought of clojure-toolbox too, but it only categorizes, it doesn’t really compare them