Fork me on GitHub
#cljs-dev
<
2018-09-25
>
mfikes00:09:22

Is it just me, or does it seem like we have the int? and integer? predicates backwards from what they mean in Clojure?

mfikes01:09:58

Why do I say this? - The subset relations are backwards. - The arbitrary- vs. fixed-precision aspect seems a little backwards.

mfikes01:09:19

Oh, here is what I think happened: This change https://github.com/clojure/clojurescript/commit/bcf60ce194e5292fbc5c4b2d89dfc5a7b886b94c tracked this Clojure change https://github.com/clojure/clojure/commit/20f67081b7654e44e960defb1e4e491c3a0c2c8b Note the commit title "rename long preds to int and cover all fixed precision integer types" It was probably an oversight that goog.math.Integer is not fixed-precision.

mfikes01:09:40

(It is super easy inadvertently draw an incorrect parallel between java.lang.Long : java.lang.Integer and goog.math.Long : goog.math.Integer.)

mfikes01:09:52

Or maybe this was intentional as the docstrings were not copied verbatim

mfikes01:09:51

Hrm. For me, I struggle to come up with a simple mental model for the difference between int? and integer? that spans both dialects. That's why I was digging into this.

mfikes01:09:37

Here's a mental model that may work: integer?: Things that are number? but are "whole" int? (and friends) : Things that work well with spec. (I'd still be a little hard-pressed to explain goog.math.Integer)

Alex Miller (Clojure team)01:09:36

conceptually, I’d say integer? = all integers, int? = integers representable as fixed precision integers

mfikes01:09:15

Yeah, OK. Maybe the goog.math.Integer inclusion was a mistake.

Alex Miller (Clojure team)01:09:35

goog.math.Integer seems like it is a subset of int?

Alex Miller (Clojure team)01:09:50

it really matches Java int right?

mfikes01:09:56

goog.math.Integer is like BigInt

mfikes01:09:22

Google picked a really bad name for that one.

Alex Miller (Clojure team)01:09:34

oh, I see after reading more closely

Alex Miller (Clojure team)01:09:17

yeah, I’d say that’s integer?

mfikes01:09:38

Right, you seem to be where I started at the top 🙂

favila01:09:08

int? = host primitive integer?

favila01:09:33

Rather, a non-fractional real number represents me using a host’s primitive value type for numbers

favila01:09:44

*represented using

mfikes01:09:01

Dang. I feel like this may all be water under the bridge, given this stuff's been in since 2016. Unless you could weasel an argument that these predicates were introduced with spec, which is still alpha. Ugh.

mfikes01:09:14

We may be stuck with things.

mfikes01:09:57

Or... you could play the card that, this is just a bug. We need to fix it.

favila01:09:29

If it helps, I am continually confused by Clojure’s numeric predicates

mfikes01:09:29

I do like integer? is ℤ and int? is a fixed-precision subset of ℤ.

favila01:09:06

Fixed precision by type or value?

mfikes01:09:45

Fixed- as opposed to arbitrary-precision, which is needed to represent ℤ.

favila01:09:47

“Fixed precision” meaning “fits in a long/double”? Or within some range

mfikes02:09:20

Good question. If I had to defined "fixed-precision integer" I'd be happy a 2's complement representation that has a fixed number of bits.

favila02:09:33

Yeah cljs just broken

favila02:09:50

It’s backwards

mfikes02:09:31

If we moved the goog.math.Integer from int? to integer? that would roughly correspond to making things right

favila02:09:33

That parsefloat check is also really strange

favila02:09:59

Long as well

mfikes02:09:59

Good point. Really, you'd then need to consider expanding number?, etc. and at some point it feels like too much. Hrm.

favila02:09:57

In Java, the type and value spaces line up better

favila02:09:28

Because there wasn’t clarity about what it means when they differ, cljs is all over the place

mfikes02:09:30

Perhaps in a few years we will be struggling to find a way to fit js/BigInt into ClojureScript. Maybe that'd be an opportunity to tackle consequences for number? etc., but all of that feels like breaking change

favila02:09:11

Cljs integer? For eg accepts a bigger range than js

favila02:09:35

Even outside the range of safe arithmetic

mfikes02:09:48

For now, maybe a small step would be to remove the arbitrary-precision type (`goog.math.Integer`) from int? (and friends) and change the docstrings for int? and friends to match Clojure's

favila02:09:17

Slack autocomplete is a bear

mfikes02:09:22

(By friends, I mean pos-int? neg-int?, nat-int? etc.)

mfikes02:09:13

I really think there is a good chance we got mistaken by goog.math.Integer looking too much like java.lang.Integer. I'm probably guilty of that mistake back in 2016 when that changeset went it. I recall looking at it at the time and I even think I recall making that mistake.

mfikes02:09:51

Even though it would strictly be a breaking change to remove goog.math.Integer from int?, I'd actually be surprised if any code has even become dependent upon that aspect.

favila02:09:22

Don’t you have to s/int/integer?

favila02:09:08

If following clj Cljs int should accept non-fractional double and goog Long

favila02:09:37

And integer? All int? Plus goog Integer

mfikes02:09:27

Yeah, to really make ClojureScript follow Clojure you'd need to make a lot of drastic changes. You'd need to consider revising number? as well.

mfikes02:09:12

In Clojure this is a chain smaller and smaller subsets: number?, integer?, int?, nat-int? In ClojureScript, when you hit int? the set gets bigger.

dnolen15:09:16

@mfikes I’d say bug - and see what the feedback is

dnolen15:09:31

I’d be surprised if a lot of people are relying on these semantics, we bottom out in JS after all

mfikes15:09:26

Ok, I’ll write a JIRA, at least removing goog.math.Integer from int? and friends

mfikes15:09:22

If we also removed goog.math.Long, that would fix more of it in that you can’t have something that satisfies int? without it also satisfying integer? and number?

mfikes15:09:47

Maybe that second choice is better…

dnolen15:09:41

let’s get this all collected in JIRA for review

mfikes15:09:45

Cool. Yeah—that’s better. Will do.

dnolen15:09:08

@mfikes re the inference stuff, have you checked the perf? At least initial hunch is I would be surprised if much slower - since it’s not really inner loop stuff like the recent optimizations

dnolen15:09:27

re: goog.math.Long why should that not be true for number? and integer?

mfikes15:09:59

One patch (the and/or/if stuff) is currently slowing things down by 10%, and the return-type inference ticket for variadic and multi-arity fns is adding a 5% slowdown.

mfikes15:09:44

We might succeed in squeezing the perf for those still…

mfikes15:09:40

So opting into type inference could be a thing, but maybe we can avoid that and keep things simple

mfikes16:09:02

Yes, number? and integer? could be revised (maybe if we are careful of the consequences)