Fork me on GitHub

I'm under the impression that let bindings can't infer the primitive type of a var even if it's been type hinted?

(set! *unchecked-math* :warn-on-boxed)
(def ^{:tag 'long} k 100)
(let [i k]
  (+ i 10))
;;=> Boxed math warning, unchecked_add(java.lang.Object,long).
Is that correct, or I'm doing something wrong?


i’m super handwavy in this area, but I think var’s cannot hold primitives. k isn’t a long but a Long. Might be wrong though I’m super wrong. Sorry


You're right in that regard - it will hold boxed Long. But {:tag 'long} will still be used for type inference.

Alex Miller (Clojure team)13:01:05

var hints are resolved so the original code resolves that to the long function, which is not your intent. You can get primitive long or double def vars but you need to hint it with a quoted symbol to avoid the resolution (this is different than return type hints in a defn because those are not resolved)


Oh sorry, that was just wrong when I typed it in slack, the code is hinted properly and it doesn't work:

(set! *unchecked-math* :warn-on-boxed)
(def ^{:tag 'long} k 100)
(let [i k]
  (+ i 10))
;;=> Boxed math warning, unchecked_add(java.lang.Object,long).


There's no warning if you use ^:const

(def ^:const k 100)
(let [i k]
  (+ i 10))


Ya, but that's because const will replace k by the value, so the inference becomes the same as (let [i 100]


DO you ever need primitive var that cannot be ^:const ?


@U064X3EF3 I feel maybe there's a bug somewhere in the compiler? Because if I inspect the binding, the java class is long, but hasJavaClass says false, this seems like a bug:

(defmacro inspect-local []
   (into {}
         (map (fn[[k v]]
                [k {:tag (.-tag v)
                    :class (.getJavaClass v)
                    :primitive? (.isPrimitive (.getJavaClass v))
                    :has-java-class? (.hasJavaClass v)}]))

(let [i k]
  (+ i 10))

;;=> {i {:tag nil, :class long, :primitive? true, :has-java-class? false}}
I'm guessing there must be a check for .hasJavaClass before calling .getJavaClass, and for some reason .hasJavaClass returns false even though there is one? I'm not too sure where in the compiler, but I think this: controls if it needs to emit a primitive or not, and that checks for .hasJavaClass first.

Alex Miller (Clojure team)17:01:04

Not sure, put it on Ask Clojure if you want me to look at it

👍 2

I've asked if we can use bbgum with REPL and currently there is no solution. Does someone know if this is possible? From the discussion and per my understanding this relates to how repl renders and draws the screen (TTY). cc @pez, @bozhidar


Don't think it's related to REPLs, TUI stands for "terminal" user interface. If you don't have a terminal, it's normal it won't work. Repls that run in a terminal should work no?


You could probably start the repl in a terminal and then connect your editor to it. You'd get the tui in the terminal, and you'll be connected to the repl from your editor


thanks, I will try that and see if the bblgum experience is improved


I have a few functions that make RPC calls (and return nothing) which I'd like to make async such that they 'bundle up' similar calls and execute them all at once when the oldest call reaches a certain age. How can I do this in a non-obtrusive manner? If possible I'd like to avoid bringing in core.async as well as explicitly managing a worker thread.


Think I'm gonna go ahead and just use atoms, futures and explicit locking to handle this


I was investigating the contajners library, and got stuck when I tried to retrieve the stats for a docker container, it just hangs, which leads me to believe it is exposing some kind of stream or socket, the issue is that it never returns anything (like a blocked thread), does any one of you guys ever used it? If so, how can I read the status? Thanks


hey, have you tried invoking it with :as :streeam? this should be a similar usecase as

🙌 2
Fabio Francisco22:01:57

Hi, thanks for the reply, I will try just that and get back to you


Just wanted to let you know that it works, thanks for that 🙂


Awesome! Lemme know where the docs could be improved, make this more intuitive or discoverable! PRs welcome too! 😄


What I can tell you right now, is that , at least for docker, it would be good to have an indication of where you should expect a stream or not. The case of stats, is pretty easy to understand, as I told you myself, I was under the impression I needed to do something special to read it, although, if it was already in the documentation, it would be easier to grasp, you could even point to the same example you pointed me to. Besides this, I am loving it so far, I might have some doubts regarding running new containers with specific parameters later, but I will try do it on my own first, and I will let you know how easy (or not) it was. Thanks once again!


Got it! I’ll try to word the documentation more in terms of what class of operations have similar behaviours and examples. The thing with contajners is that by design it’s very simple and tries not to be in your way and the api hence also not knows much about the thing it’s talking to. It’s there pretty much for being an idiomatic and transparent interface. In general the advice I can give is when dealing with the engine specifics, reading it’s api docs first and then applying them here is much faster and iterative.

Fabio Francisco21:01:46

Yes, you’re right as well. Thanks


I remember seeing a web interface to nREPL, mountable as a ring handler but I can't seem to find it anymore. Was that a real thing or am I imagining it?


Yes, that's the one! No idea why I couldn't find it before. Thank you 🙏


I did the same in Google few days ago and all I could find was forum/Slack/etc threads about ring issues during dev time etc


that lib brings me back, it mentions Noir!

😆 2

Yea, I didn’t realize how bad github/google search was for clojure libraries until trying dewey search