Skip to content

Conversation

@tkluck
Copy link
Contributor

@tkluck tkluck commented Feb 10, 2020

Prior to this commit, the order parameter was discarded if either by or order was passed. However, there is a sane interpretation for most of these combinations, and we should use that interpretation for least surprise.

The one case that doesn't have an obvious interpretation is when a non-trivial order is passed together with an lt function; in that case it is better to error out rather than let it pass silently.

For context, the reason why I'm interested in this is that I'm using custom subtypes of Base.Order.Ordering to represent monomial orders in PolynomialRings.jl. It can be very useful to pass e.g. by=first together with order=@degrevlex(x > y).

This also cleans up a seemingly unused function ordtype.

Prior to this commit, the `order` parameter was discarded if
either `by` or `order` was passed. However, there is a sane
interpretation for most of these combinations, and we should
use that interpretation for least surprise.

The one case that doesn't have an obvious interpretation is when a
non-trivial `order` is passed together with an `lt` function; in that
case it is better to error out rather than let it pass silently.
@tkluck tkluck force-pushed the tkluck/dont-discard-order-parameter branch from 38e3919 to 805d22b Compare February 10, 2020 15:33
Copy link
Member

@timholy timholy left a comment

Choose a reason for hiding this comment

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

Very nice. You've got a bootstrap issue that needs solving (Revise hides such issues, sadly you'll have to build from scratch), but otherwise this looks good to me.

You might be able to solve it by switching from == to ===.

@tkluck
Copy link
Contributor Author

tkluck commented Feb 10, 2020

@timholy thanks for noticing the issue and for pointing out how to solve it :) Let's see what buildbot says now.

Forgot to add the new test file to the list of  tests.
@timholy timholy added breaking This change will break code bugfix This change fixes an existing bug labels Feb 11, 2020
@timholy
Copy link
Member

timholy commented Feb 11, 2020

Since this is technically breaking, let's see what PkgEval says:

@nanosoldier runtests(ALL, vs=":master")

@nanosoldier
Copy link
Collaborator

Your package evaluation job has completed - possible new issues were detected. A full report can be found here. cc @maleadt

@tkluck
Copy link
Contributor Author

tkluck commented Feb 11, 2020

The nanosoldier build reveals issues with ~20-30 packages, broadly in two classes:

  • the biggest class is those depending on SortingAlgorithms.jl which in turn relies on the removed function Base.Order.ordtype.
  • a few packages depend on CuArrays.jl which uses Base.Order.By(....) directly

The second case is easy to solve: I'll add a backward-compatible constructor

Base.Order.By(key, order=Forward)

As for the first case, bringin back Base.Order.ordtype seems like the easy thing to do. OTOH, for future maintainability it would be better if ordtype would just move to be adjacent to where SortingAlgorithms.jl is doing its Order-juggling. There's no testing for it in Base and it was covered by a shady TODO comment before I removed it.

Having said that, the prudent thing to do is to just leave it in... backwards compatibility is pretty important for a language.

Add a backwards-compatible constructor for Base.Order.By.
Bring back the Base.Order.ordtype function.
@timholy
Copy link
Member

timholy commented Feb 12, 2020

@nanosoldier runtests(ALL, vs=":master")

If this comes out clean, before merging it might be worth adding # TODO: deprecate near Base.Order.ordtype. I'd suggest moving it to deprecated.jl but that's a different module. Tagging it with that kind of flag makes it more likely it will be discovered and dealt with for Julia 2.0.

@tkluck
Copy link
Contributor Author

tkluck commented Feb 13, 2020

it might be worth adding # TODO: deprecate near Base.Order.ordtype. I'd suggest moving it to deprecated.jl but that's a different module. Tagging it with that kind of flag makes it more likely it will be discovered and dealt with for Julia 2.0.

I could even add an if VERSION < v"2.0-", maybe?

@nanosoldier
Copy link
Collaborator

Your package evaluation job has completed - possible new issues were detected. A full report can be found here. cc @maleadt

@tkluck
Copy link
Contributor Author

tkluck commented Feb 13, 2020

Just checked the logs from nanosoldier's failures. It's only 8 now and no smoking guns pointing at this change. I think this is safe to merge.

What's you opinion on an if VERSION < v"2.0-" guard for the ordtype definitions? Then no-one has to worry about it in the future.

@timholy
Copy link
Member

timholy commented Feb 13, 2020

I think this is safe to merge.

Agreed. Thanks for your care here.

What's you opinion on an if VERSION < v"2.0-" guard for the ordtype definitions? Then no-one has to worry about it in the future.

That seems like a good idea to me. Once you add let's merge this.

@tkluck
Copy link
Contributor Author

tkluck commented Feb 13, 2020

Bootstrapping... I'm checking if I can get VERSION and v"...." to work at bootstrap time and will update here.

Pre-deprecate the ordtype function as we don't want to carry this
in v2.0.
@tkluck tkluck force-pushed the tkluck/dont-discard-order-parameter branch from 0d25f9a to 67d81cc Compare February 13, 2020 12:16
@tkluck
Copy link
Contributor Author

tkluck commented Feb 13, 2020

Found a way but it involves ccall. I'll leave it to your judgment whether the ugly code is still better than hoping someone remembers to deprecate it in the future.

# this functionality to those packages in the future; let's remind/force
# ourselves to deprecate this in v2.0.
# The following clause means `if VERSION < v"2.0-"` but it also works during
# bootstrap. For the same reason, we need to write `Int32` instead of `Cint`.
Copy link
Member

Choose a reason for hiding this comment

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

Possibly because Cint isn't defined yet? Using Int32 probably works because of little-endianness: if the return value is actually Int64 but the caller thinks its Int32 on a little-endian system, the value is right. Would fail on a big-endian system, although, of course, we don't support any of those.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Possibly because Cint isn't defined yet?

Yes, that's probably it. I didn't attempt to re-shuffle the bootstrap order although it would be nice to have VERSION comparisons and safe ccall.

Would fail on a big-endian system, although, of course, we don't support any of those.

Do we support any platforms where Cint is different from Int32 at all? I can only find

const Cint = Int32

in the source. If we do, your analysis about endian-ness is sound.

Copy link
Member

Choose a reason for hiding this comment

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

That's a good point, I was thinking of long which is 32/64-bit. I guess I haven't been doing much C programming for a while now 😄

@tkluck
Copy link
Contributor Author

tkluck commented Feb 14, 2020

This is probably good to merge; the buildbot/tester_win32 failure happens during setup stage and seems completely unrelated.

@timholy timholy merged commit 8eb0f9f into JuliaLang:master Feb 15, 2020
@timholy
Copy link
Member

timholy commented Feb 15, 2020

Very impressive work, @tkluck, thanks!

birm pushed a commit to birm/julia that referenced this pull request Feb 22, 2020
Prior to this commit, the `order` parameter was discarded if
either `by` or `order` was passed. However, there is a sane
interpretation for most of these combinations, and we should
use that interpretation for least surprise.

The one case that doesn't have an obvious interpretation is when a
non-trivial `order` is passed together with an `lt` function; in that
case it is better to error out rather than let it pass silently.
KristofferC pushed a commit that referenced this pull request Apr 11, 2020
Prior to this commit, the `order` parameter was discarded if
either `by` or `order` was passed. However, there is a sane
interpretation for most of these combinations, and we should
use that interpretation for least surprise.

The one case that doesn't have an obvious interpretation is when a
non-trivial `order` is passed together with an `lt` function; in that
case it is better to error out rather than let it pass silently.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking This change will break code bugfix This change fixes an existing bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants