Skip to content

Resolve boxed math warnings #64

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

Merged
merged 9 commits into from
Jul 7, 2023
Merged

Resolve boxed math warnings #64

merged 9 commits into from
Jul 7, 2023

Conversation

valerauko
Copy link
Contributor

  • added a bunch of type hints to resolve boxed math warnings
  • enabled warnings in the dev profile to motivate people to fix things

@valerauko valerauko requested a review from KingMob as a code owner November 8, 2022 05:37
Copy link
Collaborator

@KingMob KingMob left a comment

Choose a reason for hiding this comment

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

The non-clj-commons namespaces are deprecated. I'd prefer not to update them for anything other than security fixes.

@valerauko valerauko requested a review from KingMob November 8, 2022 08:06
Copy link
Collaborator

@KingMob KingMob left a comment

Choose a reason for hiding this comment

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

Some minor changes, but looks fine otherwise

Comment on lines 34 to 35
(hash wrapper)
(hash type)))
^long (hash wrapper)
^long (hash type)))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmmm. hash returns an int, not a long. But the compiler uses the hint to force a cast. Not sure which is faster, though.

Before:

    public int hashCode() {
        return RT.intCast(Numbers.xor(((IFn)const__4.getRawRoot()).invoke(this.wrapper), ((IFn)const__4.getRawRoot()).invoke(this.type)));
    }

After:

    public int hashCode() {
        return RT.intCast(RT.uncheckedLongCast((Number)((IFn)const__4.getRawRoot()).invoke(this.wrapper)) ^ RT.uncheckedLongCast((Number)((IFn)const__4.getRawRoot()).invoke(this.type)));
    }

Truthfully, the best thing is to skip hints here and use explicit conversions to match the types involved. Try:

(hashCode [_]
    (int
      (bit-xor
        (long (hash wrapper))
        (long (hash type)))))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does Clojure even allow ^int type hints? It gives me an "Only long and double primitives are supported" error.

I'll change to explicit cast.

Copy link
Collaborator

Choose a reason for hiding this comment

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

^int is a valid type hint, but not for function parameters or return values. It's fine in local contexts, like a let.

Hell, it used to be (iirc) that unboxed parameters weren't allowed at all, but it seems like they're allowed for fn arities up to 4 now.

Copy link
Collaborator

Choose a reason for hiding this comment

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

(You shouldn't need to hint hashCode btw, that's defined by Object.)

(Conversion. (fn [x options] (s/map #(f % options) x)) (+ cost 0.1)))))
(Conversion. (fn [x options] (s/map #(f % options) x)) (+ ^double cost 0.1)))))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Seems like the hint should be higher up, but it's not working. I forget if this is a limitation of deftype or not.

Probably preferable to convert at the top of the let, like:

(let [cost (double cost)
      m' (assoc-in ...

Copy link
Collaborator

Choose a reason for hiding this comment

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

Or a limitation of defprotocol, I mean, which defines IConversionGraph. (Which should be named something else, since it's not an interface.)

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 I tried to add the hint both on defprotocol and deftype but it errored...

Copy link
Collaborator

Choose a reason for hiding this comment

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

Not surprised. I get the compromises necessary to interop with Java, but the whole deftype/protocol/record system is ugly and sticks out.

@valerauko valerauko requested a review from KingMob November 8, 2022 09:38
@KingMob
Copy link
Collaborator

KingMob commented Nov 9, 2022

You know, we already use clj-commons.primitive-math elsewhere, we should probably do the same here for consistency. Sorry, can you change it?

@valerauko
Copy link
Contributor Author

@KingMob late, but I updated to using primitive-math. Is this what you were referring to?

Are the boxed math warning around line 130 in graph.clj also unfixable due to #68 ?

^ByteBuffer (.limit (int (min lim (+ (int %) ^long chunk-size))))
.slice)
indices))
#(-> buf
.duplicate
^ByteBuffer (.position (int %))
^ByteBuffer (.limit (int (min lim (p/+ (int %) chunk-size))))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmmm. I wonder why we downcast the index to an int. Since chunk-size is long, the index will be immediately widened back to a long for the addition.

Copy link
Collaborator

@KingMob KingMob left a comment

Choose a reason for hiding this comment

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

Looks good, but we've been using p as the alias for primitive-math elsewhere, instead of m. Can you make it consistent?

@valerauko
Copy link
Contributor Author

we've been using p as the alias for primitive-math elsewhere, instead of m

I used m because p was already taken. Should I change the existing alias to something else?

@KingMob
Copy link
Collaborator

KingMob commented Jul 6, 2023

I think p is more consistent with existing primitive-math examples, and would prefer proto for protocols.

@valerauko
Copy link
Contributor Author

Eastwood fails with the reflection on the (.type dst) which can't be fixed according to the comment

@KingMob
Copy link
Collaborator

KingMob commented Jul 7, 2023

I think this is fine for now. Thanks!

Something is still wrong about that def-conversion/AOT problem, but we're not going to fix it here. It seemed related to CLJ-1650/1741, but the timing is wrong; that bug was fixed in Clojure 1.8. I wonder if it's related to Potemkin and deftype+?

@KingMob KingMob self-requested a review July 7, 2023 07:09
@KingMob KingMob merged commit 86c7726 into clj-commons:master Jul 7, 2023
@valerauko valerauko deleted the develop/boxed-math branch July 7, 2023 08:28
@valerauko
Copy link
Contributor Author

Thanks! I guess the warnings in manifold are next!

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