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

Switch to Euclidean division for Int, resolves #161 #168

Merged
merged 5 commits into from
Apr 22, 2018

Conversation

hdgarrood
Copy link
Contributor

Also provide quot and rem, like Haskell does, for users who do want
truncating division - the one which matches what JS does.

I've temporarily exported intDiv and intMod so that I can use those
in the tests and the compiler won't 'inline' different definitions of
them; we'll want to modify the compiler to change this before merging.

I've also done a more detailed writeup in a separate repo but I thought that might be a bit much for these docs.

Also provide `quot` and `rem`, like Haskell does, for users who do want
truncating division - the one which matches what JS does.

I've temporarily exported `intDiv` and `intMod` so that I can use those
in the tests and the compiler won't 'inline' different definitions of
them; we'll want to modify the compiler to change this before merging.
exports.intDiv = function (x) {
return function (y) {
return Math.sign(y) * Math.floor(x / Math.abs(y));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Math.sign is ES2015 unfortunately

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the simplest alternative is something like:

return y > 0 ? Math.floor(x / y) : -Math.floor(x / -y);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, thanks, I wasn't aware of that.

-- | mod 2 (-3) == 2
-- | rem 2 (-3) == 2
-- | ```
foreign import rem :: Int -> Int -> Int
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we should provide quot and rem in purescript-integers, since they are Int specialised, rather than constrained to EuclideanRing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that wouldn't be a bad option. I think it makes sense to put them here, because they do form a valid EuclideanRing instance (even if we're no longer using it as the default instance for Int), and also because these functions were available from Prelude before, but I don't have a strong preference.

-- | negative infinity if the divisor is positive, and towards positive infinity
-- | if the divisor is negative. Note that all three definitions are identical if
-- | we restrict our attention to nonnegative dividends and divisors.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a -- | here I think 😄

@garyb
Copy link
Member

garyb commented Apr 15, 2018

This looks good to me, aside from those few comments above. I've opened a PR to remove mod inlining for Int already: purescript/purescript#3309 and it appears we didn't inline integer division already... I found that a bit of a surprise!

@garyb
Copy link
Member

garyb commented Apr 15, 2018

Ah no, we do, but it's done differently than the mod case. I'll update that PR accordingly.

@garyb garyb changed the base branch from master to compiler/0.12 April 22, 2018 20:27
@garyb
Copy link
Member

garyb commented Apr 22, 2018

Thanks again for working on this!

@garyb garyb merged commit dc51981 into compiler/0.12 Apr 22, 2018
@garyb garyb deleted the euclidean-int branch April 22, 2018 20:27
@hdgarrood
Copy link
Contributor Author

Happy to :) just one thing though - I just realised that the code here still exports intDiv and intMod, and I didn't mean for that to stay in the final version. I guess now that the compiler PR to stop inlining div and mod has been merged, we should remove those exports and update the tests to use div and mod instead.

@garyb
Copy link
Member

garyb commented Apr 22, 2018

Yeah, thanks for the reminder - I went ahead and did that already. I did move quot and rem to Data.Int too, since I felt it was a little strange to have some monomorphic functions in a module that is otherwise purely polymorphic. I'll include a note in the release notes when we finally get around to it pointing out the breaking change and the option to use those functions.

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

Successfully merging this pull request may close these issues.

2 participants