Fork me on GitHub

Hi everyone. I am looking for some advice on an interop problem I have stumbled into. I am working with a Java API that requires me to extend an existing abstract base-class, add some fields and an annotation. What would be the best way to accomplish this with Clojure? Is gen-class the way to go?

Alex Miller (Clojure team)01:02:48

@mss given "will then be passed to a method that expects a java.lang.Class”, then you need to use something that creates a (presumably known) class - options are deftype, defrecord, and gen-class

Alex Miller (Clojure team)01:02:24

if your only constraint is to implement an interface, then deftype might be the easiest:

Alex Miller (Clojure team)01:02:48

(deftype Foo []
  (interface-method [this] (my-func)))

Alex Miller (Clojure team)01:02:57

then the class is just Foo

Alex Miller (Clojure team)02:02:14

(qualified by your current namespace if you need the fully-qualified class)


thanks for the response, that makes sense. how does deftype work under the hood? worried about leaking memory from successive calls to e.g. make-an-instance above (except deftype instead of defrecord) to make the body of the interface method dynamic

Alex Miller (Clojure team)02:02:39

if you’re just calling it dynamically (not AOTing code that uses it), it should just be creating classes and registering them in the classloader


and over time none of those class declarations would be deallocated, correct? sorry my understanding of jvm memory lifecycle is a little fuzzy

Alex Miller (Clojure team)02:02:31

class unloading is tricky. seems easy to test.


great, glad that class unloading is a thing. will look into it more. thanks so much for the help

Alex Miller (Clojure team)02:02:07

it has evolved a lot in the JVM over the years and Clojure has its own DynamicClassLoader with its own class cache, but it should let that happen

Drew Verlee02:02:49

I’m reading through Clojure Applied (which is awesome) and i was hoping someone could help me wrap around why the author suggests using a protocols for the core functions of an API. They state.... > Most APIs have this pattern—a handful of key base functions and a larger set of functions provided for ease of use. Protocols are a good way to capture the core set of functions so that multiple implementations can extend that protocol. The derived functions should be provided in the API namespace and layered over the protocol. TheAPI functions then work for any entity that extends the protocol. Is the benfiet of using a protocol that we make the functions needed to implement the API explicit in the protocol. So if a differently shaped set of data wants to implement the API we have documented the core function signatures and some docs. This also seems to imply we should keep our core set of data for the api inside a record, as protocols work on different classes.


Yes, protocols are often used to present an abstract interface. For example, ClojureScript uses protocols to represent the interfaces of data:

Drew Verlee02:02:30

So it seems the general wisdom is to have abstract interfaces (protocals, records) at your core, but to accept more general data (maps) at your edges.


I'm confused by this (right at the start of clojure koans) - "What could be equivalent to nothing?" (= nil)


my first thought/instinct is false


(= false nil)


but that is incorrect


any place I should be looking (without spoiling the answer)?


obviously this passes (= nil nil) but I'm assuming that isn't 'correct'


i think you can use everything what returns nil, like (first []) ?


but staying in basics like (= nil nil) should be good at start


hmm - hadn't considered that - thanks for the tip


(defn sleep-print-update
  [sleep-time thread-name update-fn]
  (fn [state]
    (Thread/sleep sleep-time)
    (println (str thread-name ": " state))
    (update-fn state)))
(def counter (ref 0))
(future (dosync (commute counter (sleep-print-update 100 "Thread A" inc))))
(future (dosync (commute counter (sleep-print-update 150 "Thread B" inc))))
Here’s a timeline of what prints:
Thread A: 0 | 100ms
Thread B: 0 | 150ms
Thread A: 0 | 200ms
Thread B: 1 | 300ms
from Chapter 10 of Clojure for the Brave and True I'm confused why println is called twice (per thread) ... commute shouldn't be retrying the "transaction"


commute, on the other hand, behaves like this at commit time:

Reach outside the transaction and read the ref’s current state.
Run the commute function again using the current state.
Commit the result.


the commute fn runs in future, the thread sleeps and at the end when state is changing it derefs the state and runs commute fn again


it sleeps again and println second time


=> 2


I guess I'm just not clear how each future ends up calling sleep-print-update twice


I thought commute does not retry


at commit time commute runs again with current value of state


it's not a retry because nothing is compared


from it sounds like commute is actually running twice (similar to your explanation above)


ok well that's confusing 🙂


Why am I getting two different results when I eval and debug the same function in cider? 😅


Stdout vs return value?


I get an exception with eval, everything runs fine with debug...


I don't use cider much, paste the code and the results, maybe somebody will help.


What do you use instead of cider?


@not-raspberry the code is a little messy, I'll find the solution on my own 😕 Thanks! 🙂


@lepistane fireplace, mostly 🙂