Fork me on GitHub
#clojure
<
2022-10-25
>
Joshua Suskalo15:10:25

Is there a workaround for making fn* class names shorter? I'm getting exceptions around class names being too long from relatively small code size just because the macros it's working with expand to quite a few nested function literals.

andy.fingerhut15:10:25

Others can answer more authoritatively, but I know there is a JIRA issue asking about this. I believe the original motivation was for macro-heavy libraries like core.logic

andy.fingerhut15:10:08

I suspect the only workarounds are to use a file system that supports arbitrarily long file names, or to modify the Clojure compiler in how it constructs class names.

andy.fingerhut15:10:14

Some of the comments in that http://ask.clojure.org discussion might include other workarounds.

Alex Miller (Clojure team)16:10:03

I don't think there is any easy workaround. ultimately, this is going to need to be an alternative naming strategy in the compiler

Joshua Suskalo16:10:41

Thanks, that's good to know

Joshua Suskalo16:10:01

Unfortunately I'm in the same boat with a couple features of farolero, most notably the debugger assertions.

andy.fingerhut16:10:12

I'd recommend voting on the http://ask.clojure.org issue, and adding a comment about other Clojure library names that lead to a similar issue, for others searching for the issue in future.

๐Ÿ‘ 1
Noah Bogart16:10:49

I have a function that relies on java.lang.Runtime, and I want to extract that to make the function pure. I've type hinted the arg, but now I'm unsure of how to pass in a fake object that works the same. Any ideas or should I not worry about it?

(defn mem-stats
  "Returns a map of current total, free, and used memory in megabytes."
  [^java.lang.Runtime rt]
  (let [fm (.freeMemory rt)
        tm (.totalMemory rt)]
    {:total (->MB tm) :free (->MB fm) :used (->MB (- tm fm))}))

Noah Bogart16:10:02

But also, in other more complicated situations, how do you create a proxy for a concrete class? I can't seem to get proxy to work correctly in this instance

jjttjj16:10:23

You could use definterface

(definterface MyInter
  (freeMemory []))

(.freeMemory
  (proxy [MyInter] []
    (freeMemory [] 123)))

=> 123

dpsutton16:10:41

(defprotocol RuntimeStats
  (free-memory [_])
  (total-memory [_]))

(extend-protocol RuntimeStats
  java.lang.Runtime
  (free-memory [rt] (.freeMemory rt))
  (total-memory [rt] (.totalMemory rt)))

(let [real (java.lang.Runtime/getRuntime)
      oom (reify RuntimeStats
            (free-memory [_] 0)
            (total-memory [_] (total-memory real)))]
  {:real {:free (free-memory real)
          :total (total-memory real)}
   :oom {:free (free-memory oom)
         :total (total-memory oom)}})

dpsutton16:10:06

{:real {:free 211626544, :total 645922816},
 :oom {:free 0, :total 645922816}}

dpsutton16:10:04

The idea is donโ€™t fake a java.lang.Runtime, just make that know how to satisfy your needs

Noah Bogart16:10:22

Both of these are great, thank you

vemv17:10:46

perhaps worth noting, if java.lang.Runtime was implemented today probably it would implement an interface - it's sort of a modern-day OOP best practice

vemv17:10:42

which Clojure already nudges us to :) by making inheritance difficult (if you wanted to squeeze performance you could subclass Runtime... I'd do it with a plain .java file)

Noah Bogart17:10:31

heh This doesn't need any sort of performance tuning, the function is only used in a single spot. Just decided to use it as an opportunity to learn.

vemv17:10:22

yeah I could imagine one wouldn't be invoking this code 1000 times / second ๐Ÿ˜‡ I was simply nerd-sniped into it

Noah Bogart17:10:47

it's nerd-sniping all the way down

๐ŸŒ€ 1
Jared Langson21:10:30

Is there a variant of time that does not return the value of expr?

colinkahn21:10:52

(time (do (expr...) nil)) should work

๐Ÿ‘ 1