This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-07-13
Channels
- # announcements (1)
- # babashka (29)
- # beginners (64)
- # calva (4)
- # cider (5)
- # cljs-dev (3)
- # cljsrn (2)
- # clojure (100)
- # clojure-australia (2)
- # clojure-conj (7)
- # clojure-dev (9)
- # clojure-europe (31)
- # clojure-germany (1)
- # clojure-nl (2)
- # clojure-uk (13)
- # clojured (2)
- # clojurescript (62)
- # community-development (2)
- # conjure (1)
- # cursive (21)
- # datomic (39)
- # events (2)
- # fulcro (7)
- # graalvm (24)
- # graalvm-mobile (11)
- # holy-lambda (3)
- # jobs (7)
- # lsp (15)
- # malli (26)
- # music (1)
- # nyc (2)
- # off-topic (18)
- # reagent (23)
- # reitit (5)
- # remote-jobs (1)
- # shadow-cljs (2)
- # tools-deps (26)
- # vim (6)
- # xtdb (17)
Morning!
had my 2nd 💉 on sunday @U052TDWT7 - here i think you can see my immune system kick into gear in the middle of that night, as my heart rate jumps 10-15 bpm over the course of an hour - i was feverish yday, but it seems to have mostly passed now https://photos.app.goo.gl/DTmFJQSP2TpPJdWY8
My heartbeat is usually way more higher than that 😅
måning
Good morning!
so, this rather innocuous looking expression (/ (* 100 score) max-score)
just threw a
{:type java.lang.ArithmeticException
:message "Non-terminating decimal expansion; no exact representable decimal result."
:at [java.math.BigDecimal divide "BigDecimal.java" 1693]}
on me...
obvs easy to work around for an individual expression, but i'm left wondering how many other seemingly innocuous arithmetical expressions in this codebase will explode at some point in the future because the postgres JDBC driver decided to map to a BigDecimal
you can hook into bigdec's precision api with the (with-precision 10 (/ (* 100 1M) 3M))
too ... I've done that in the past when I needed to convert to specific representations ... and you can put that way up the stack if you have a lot of calculations and you just want to not get this exception 😉
oh, cool, that's useful - thanks @U0P0TMEFJ - looking at that macro, it sets a threadlocal binding - https://github.com/clojure/clojure/blob/clojure-1.10.1/src/clj/clojure/core.clj#L5100 - so perhaps most useful within a single fn or where a synchronous flow can be guaranteed
yeah ... it depends what you're up to ... you could, for example have ring middleware that wraps all requests in that binding ... or (set! *math-context* ...)
at startup ... or something else ... 😉
so, if you know things are just going back into a db, you could make sure you bind it to something that just gets the right number of significant figures or something 😉
will think on it... our api handlers are doing async i/o so dynvars don't work out so well, so maybe setting the root is the sane thing to do
Yeah, that trips me up from time to time (with MySQL).
I try to remember to always use double literals in expressions which prevents that:
dev=> (/ (* 100 1M) 3M)
Execution error (ArithmeticException) at java.math.BigDecimal/divide (BigDecimal.java:1715).
Non-terminating decimal expansion; no exact representable decimal result.
dev=> (/ (* 100.0 1M) 3M)
33.333333333333336
yeah, that's my workaround too... but it's still feels like a bit of a powder-keg - was it a good decision on the part of the mysql and postgresql drivers to map to BigDecimal
by default ?
for them it was good or irrelevant... I mean for a Java author and consumer a bigdec will be conveyed by type signatures
perhaps an underemphasized point is that clojure.core +
, /
etc are notably generalized functions optimized for certain characteristics
nobody forces us to use those. One can quite trivially create specialized, per-type +
etc and your code will be just as clojurey as before. I found https://github.com/ztellman/primitive-math an interesting precedent in this regard
ah, ofc, i'm forgetting bigdec doesn't participate in the java numeric tower
i certainly found it surprising to get something like a NaN for a non-zero divisor though... i wonder if there are other examples like that in the numeric tower - where the result is defined, but the implementation says no in certain circumstances
i guess there are the boundaries around max and min for each type... so i need to add a new "take care not to accidentally let bigdecs into your arithmetic" to my internalised compendium of clojure numeric intuition