This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-04-17
Channels
- # ai (115)
- # announcements (8)
- # babashka (26)
- # beginners (7)
- # biff (8)
- # calva (1)
- # cider (10)
- # clerk (2)
- # clj-together (11)
- # clojure (26)
- # clojure-boston (1)
- # clojure-denmark (3)
- # clojure-europe (23)
- # clojure-nl (1)
- # clojure-norway (33)
- # clojure-uk (3)
- # clojurescript (14)
- # conjure (3)
- # cursive (65)
- # emacs (10)
- # events (18)
- # exercism (6)
- # honeysql (14)
- # hyperfiddle (11)
- # kaocha (6)
- # nbb (17)
- # off-topic (58)
- # pathom (5)
- # reagent (28)
- # reitit (1)
- # releases (1)
- # sci (3)
- # shadow-cljs (22)
- # xtdb (29)
SOLVED
(apologies if this should be in #beginners
)
Hello — Looks like a Clojure int
is a java.lang.Long
for positive numbers, but not quite for negative ones. The smallest java.lang.Long
is 0x8000000000000000
, according to https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/lang/Long.java#L79, suggesting ordinary 64-bit twos complement:
jdk.internal.ValueBased
public final class Long extends Number
implements Comparable<Long>, Constable, ConstantDesc {
/** ... */
@Native public static final long MIN_VALUE = 0x8000000000000000L;
/** ... */
@Native public static final long MAX_VALUE = 0x7fffffffffffffffL;
But Clojure seems to promote the hex literal for the smallest int to BigInt
:
(format "0x%X" -9223372036854775808)
;; => "0x8000000000000000"
(class -9223372036854775808)
;; => java.lang.Long
(class 0x8000000000000000)
;; => clojure.lang.BigInt
How about the LARGEST negative number? Clojure format
prints -1
as 0xFFFFFFFFFFFFFFFF
, with 16 F
’s, as expected for twos-complement:
(class -1)
;; => java.lang.Long
;; (format "0x%X" -1)
;; => "0xFFFFFFFFFFFFFFFF"
But Clojure seems to promote 0xFFFFFFFFFFFFFFFF
to BigInt
:
(class 0xFFFFFFFFFFFFFFFF)
;; => clojure.lang.BigInt
(= -1 0xFFFFFFFFFFFFFFFF)
;; => false
Something funny is going on. It’s not the top bit, either (as with many Lisps). With just the top bit off, Clojure (reasonably), thinks it’s got a positive Long
:
0x4000000000000000
;; => 4611686018427387904
(format "0x%X" 4611686018427387904)
;; => "0x4000000000000000"
(class 0x4000000000000000)
;; => java.lang.Long
Is this just a reader issue with hex literals?So 0x8... is not a negative number, and it doesn't fit in a positive long, so it is a bigint
You can wrap it in (unchecked-long ...) If you want to force interpreting the bit pattern as a long
one other Java thing to be aware of is that there is a special case where Long/MIN_VALUE * -1 = Long/MIN_VALUE (due to overflow). "normal" Clojure multiplication with -
checks and throws, but you can see this with unchecked-multiply
:
user=> (* Long/MIN_VALUE -1)
Execution error (ArithmeticException) at java.lang.Math/multiplyExact (Math.java:949).
long overflow
user=> (unchecked-multiply Long/MIN_VALUE -1)
-9223372036854775808
We encountered a surprising scenario recently: Delivered promises are affected by thread interrupts. I did search if that has already been discussed, but did not find anything. Apologies if I missed something. Here is some code to reproduce what I mean:
(def p (promise))
(def f (future
(println "Future: Waiting for promise to be delivered.")
(let [v @p]
(println "Future: Got promise value:" v)
;; Something interrupts this thread; normally this would be another thread, maybe calling future-cancel.
(.interrupt (Thread/currentThread))
(println "Future: Interrupted.")
(println "Future: Reading promise value again.")
;; This will not print, as @p will throw an InterruptedException.
(println "Future: Promised value:" @p))))
(deliver p :hello)
@f ; => Execution error (InterruptedException) at java.util.concurrent.locks.AbstractQueuedSynchronizer/acquireSharedInterruptibly
In our case, this was surprising, since we deref
the promise in a catch
, but asserted before with a :pre
condition that the promise is already delivered.
I would argue that this is a bug, as dereferencing a delivered promise should not be considered a “blocking” call, right? Other promise implementations, e.g. Promesa using Java’s CompletableFuture
, don’t throw InterruptedException
in this scenario. What do you think?This is a shorter example:
(let [p (promise)]
(deliver p true)
(.interrupt (Thread/currentThread))
(deref p))
I decided to report this as a problem in http://ask.clojure.org: https://ask.clojure.org/index.php/12861/delivered-promises-are-affected-by-thread-interrupts
The main issue here I guess is the call to .await on the countdownlatch (on the clojure promise
impl for deref
), on CompletableFuture
, the deref just calls get
which returns immediately if promise is completed without any synchronization
Yep, could probably be fixed by something like this:
clojure.lang.IDeref
(deref [_]
(let [v* @v]
(if (identical? v* d)
(do (.await d) @v)
v*))
Happy to provide a patch if this helps @U064X3EF3I'm looking for a Clojure notebook (clerk, gorilla, etc.) that has good LaTex support. I think I saw that Gorilla supports it, but I also want to be up with the latest. The only notebooking I've done was with Jupyter with Clojure on the backend, but I want to be all in on Clojure apps if possible. Any recommendations?
If I have a clojure source file with a bunch of symbols that were :refer
ed in the ns form, is there a tool that can take a source code file and a map of namespace->alias pairs and replace all the referred symbols with the aliased symbol? I know I could probably do this manually with tools analyzer and rewrite-clj, but wondering if this exists yet
So I want to do
(use-aliases "path/to/my-file.clj" {'medley.core 'm})
to replace in the source file calls like (map-vals ...)
with (m/map-vals ...)
(`map-vals` is a function in medley.core)Clojure is missing a "codemods" repo with common stuff like this and utils to easily build them IMO
I have a hazy memory that clojure.core.cache has a way to put a size limit on a cache? I can’t find any documentation why i think this but I thought i remembered core.cache having an example or some docs composing a ttl cache with a size bounded cache. does that ring any bells with anyone?
the memoize lib talks about https://github.com/clojure/core.memoize/blob/master/docs/TTL.md, maybe you are thinking of that?
maybe that’s it. because i don’t see anything about size (in terms of mb, etc) from core cache
fifo with a threshold is the size limited cache.
Oh, you mean memory, not number of elements?
but yeah i think this was what i was thinking of. thanks @UE21H2HHD @U04V70XH6
You can also check out https://github.com/ben-manes/caffeine/ which has a bunch of useful features.
caffeine is a good bet, I think even datomic uses it internally, I suppose it has the rh stamp of approval
There's also the https://github.com/ptaoussanis/encore/blob/b8b44ed5ac34c425821cef7fd6ddb73078a9e925/src/taoensso/encore.cljc#L2614 function in ptaoussanis/encore, which supports size, ttl, etc