Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Numeric hierarchy #3

Open
thumphries opened this issue Oct 5, 2016 · 18 comments
Open

Numeric hierarchy #3

thumphries opened this issue Oct 5, 2016 · 18 comments

Comments

@thumphries
Copy link
Contributor

  • Purescript's Data.Int supports between 32 and 53 bits
  • Presumably there are some horrible restrictions on floats too

Look at what Aeson does when encoding (I guess it goes silently wrong?)

@jacobstanley
Copy link
Contributor

  • Data.Int is 32-bits only
  • Data.Number is a 64-bit floating point, except that it can "magically" support integers up to 53-bits precisely. Presumably javascript engines make use of the 53-bits worth of NaN's that are available in IEEE754 and use that space to be able to store exact integers up to 53-bits - this is the basis behind the Data.Int53 module.

@olorin
Copy link

olorin commented Oct 5, 2016

Purescript's Data.Int supports between 32 and 53 bits

I think it supports 32 bits, and just happens to have an underlying representation capable of representing 53 bits' worth of integers (as IEE754 floats).

Presumably there are some horrible restrictions on floats too

Not that I'm aware of; there's no native support for bitwise operations on them, but it's pretty rare that people who aren't John Carmack need to use them with floats.

Look at what Aeson does when encoding (I guess it goes silently wrong?)

Yep.

@jacobstanley
Copy link
Contributor

jacobstanley commented Oct 5, 2016

Hmm, the NaN thing is probably not right now I think about it, as ints and numbers are not different types in javascript, so there is no need for a tag I suppose, but you could do it that way if you needed to tag them differently and still have them be unboxed.

@olorin
Copy link

olorin commented Oct 5, 2016

You could, but wouldn't you lose hardware arithmetic support that way? I think the advantage of the JS implementation is it's just a 52-bit mantissa with an exponent of 1, so floating-point operations will do (mostly) the right thing without having to use another machine word.

@jacobstanley
Copy link
Contributor

I was thinking you could load the value in to an integer register and mask out the exponent, if you want honest to goodness integer ops. But yeah, it's all moot because there's isn't a difference between ints and floats in javascript, so storing them unboxed but still with a tag isn't useful.

@olorin
Copy link

olorin commented Oct 5, 2016

Yeah, makes sense. Can't say much more without a sense of what the requirements are for speed/range for each target - maybe plausible to do the integer ops in software?

@thumphries
Copy link
Contributor Author

Seems like Int32 and Double are the lowest common denominator for JSON. Should I pin these as the only numeric types for now? Didn't realise we were doing the wrong thing in so many places. The alternative is to keep doing what we've been doing, allow an Int type and just let Aeson do whatever with it.

(I'll be writing some long-winded IO properties to make sure Purescript and Haskell JSON functions are compatible, I guess I'll do whatever makes those props pass)

@thumphries
Copy link
Contributor Author

(Can add other sizes later if we start using this for other things; just refuse to produce JSON if there's an Int64 in the type)

@olorin
Copy link

olorin commented Oct 6, 2016

Should I pin these as the only numeric types for now?

Seems like the safest choice to me, we can always do something else later.

Didn't realise we were doing the wrong thing in so many places.

Yeah; for the JSON case specifically I've been seriously considering just using string instead of number. More strings solves everything right?

@thumphries
Copy link
Contributor Author

thumphries commented Oct 6, 2016

I'm curious if Aeson between Haskell services preserves large integers. It's all strings under the hood!

I guess it has to, else many of our quickcheck props wouldn't pass.

@jacobstanley
Copy link
Contributor

I'm curious if Aeson between Haskell services preserves large integers. It's all strings under the hood!

It should be fine, the JSON standard allows for arbitrary precision real numbers, and Aeson uses Scientific for this purpose.

@thumphries
Copy link
Contributor Author

So Javascript can't safely handle JSON?

@jacobstanley
Copy link
Contributor

jacobstanley commented Oct 6, 2016

So Javascript can't safely handle JSON?

It can't handle JSON losslessly, that is true of many languages I suspect.

The JSON standard has this to say about numbers:

JSON is agnostic about numbers. In any programming language, there can be a variety of number types of various capacities and complements, fixed or floating, binary or decimal. That can make interchange between different programming languages difficult. JSON instead offers only the representation of numbers that humans use: a sequence of digits. All programming languages know how to make sense of digit sequences even if they disagree on internal representations. That is enough to allow interchange.

@thumphries
Copy link
Contributor Author

Ah, so the Integer and Int64 instances are quite OK when they aren't being touched by JS. We aren't doing anything wrong per se in Haskell land. Will probably want to preserve that ability.

I'll have the Purescript JSON backend scream and shout if the bad types show up.

@jacobstanley
Copy link
Contributor

Sounds reasonable to me 👍

@damncabbage
Copy link
Contributor

Bumping this now that we have a bunch of Bikeshed modules that have previously taken numbers (eg. width and height int32s, or some input floats), and are now being forced to take String as a substitute (for now).

@charleso
Copy link
Contributor

charleso commented May 1, 2017

Talked to @damncabbage IRL but at least for things that require, say, numeric summaries this can just be an exploded record of the strings that it needs. I suspect (hope?) this can be extrapolated to most other examples.

@thumphries
Copy link
Contributor Author

thumphries commented May 2, 2017

Yep, and this is the wrong issue for that stuff. This is about how to go about adding numbers, rather than whether to.

I had (perhaps deluded) reuse aspirations for machinator, and some of those thought bubbles involved shuffling actual numbers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants