Skip to content

Conversation

@nsajko
Copy link
Member

@nsajko nsajko commented Apr 3, 2025

The fact that an important (for the ecosystem) registered package failed to follow the advice/rule provided in the change is evidence to the claim that adding these docs is important. Ref:

Fixes #55866

@nsajko nsajko added the docs This change adds or pertains to documentation label Apr 3, 2025
@nsajko nsajko changed the title manual: methods: new section on avoiding ambiguities: "playing nicely" manual: methods: new section on avoiding ambiguity: "playing nicely" Apr 3, 2025
@adienes
Copy link
Member

adienes commented Apr 3, 2025

I think the information & reminder of the possibility of ambiguity could definitely be useful to have in the docs. But in my opinion I would phrase it more neutrally-informatively as a reminder rather than as an admonition. that would mean bringing the tone from "don't do this as it's impolite" ---> "if you do this, ambiguities can occur"

after all, maybe the package authors are completely fine with creating ABExt.jl to deal with the ambiguity of ==(::A, ::B)

@nsajko
Copy link
Member Author

nsajko commented Apr 3, 2025

The issue is such: an "impolite" package causes method ambiguity with respect to an unbounded number of potential packages. We can't expect either:

  • for the impolite package to depend on packages that don't exist yet
  • new packages to depend on the impolite package, as, there again may be an unbounded number of impolite packages, some of which will only exist in the future

So the gotcha you mention, where the two packages resolve the ambiguity among themselves, without considering the rest of the ecosystem, is valid only when these two packages are in a special relationship where one of the two packages (the dependent package) depends (either strongly or weakly) on the other package (the dependency package) and the dependent package is allowed to access private parts of the dependency package. Such a relationship indicates that the ownership between the two packages is the same or shared. And that's why I included the "unrelated ownership" wording, although the clarity may need to be improved still.

@nsajko
Copy link
Member Author

nsajko commented Apr 3, 2025

Thinking about the gotcha more, I think it would be fine not to mention it in the docs. The gotcha is basically "I defined a method that causes ambiguity, but you don't need to care about it because an ambiguous call may only happen if you access my internals". However that's still impolite because of causing Aqua.jl noise in my opinion.

@mbauman
Copy link
Member

mbauman commented Jul 8, 2025

I'm not sure how to generically discuss this because it depends upon how everyone defines their methods and what the "interface" is. For example, both getindex and setindex! both satisfy your criteria but it's perfectly fine to define getindex(A::A, i...) or setindex(A::A, v).

We definitely can't say that f(::A, ::Any) is invalid. It is true, however, that the symmetric (::Any, ::A) (::A, ::Any) pattern is always problematic, though. And what makes this far more interesting — and actionable! — would be to describe why this is problematic and how to avoid it (e.g., by promotion or single-dispatch-at-a-time internals).

nsajko and others added 3 commits July 29, 2025 21:44
The fact that an important (for the ecosystem) registered package
failed to follow the advice/rule provided in the change is evidence to
the claim that adding these docs is important. Ref:
* JuliaAlgebra/MultivariatePolynomials.jl#310

Fixes JuliaLang#55866
@nsajko nsajko force-pushed the doc_comparison_warn_against_defining_ambiguous_methods branch from 8f5a417 to 07006e2 Compare July 29, 2025 19:46
@nsajko
Copy link
Member Author

nsajko commented Jul 29, 2025

👍

Describing the conditions where this rule applies seems difficult, so I guess I'll adjust this PR to be just a collection of examples, without the general rule, when I get back to it.

@nsajko nsajko marked this pull request as draft July 29, 2025 19:58
Comment on lines +1210 to +1214
* in another (polite) package:
```julia
struct Y <: AbstractFloat end
function Base.:(==)(::Integer, ::Y) end
```
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand, in how far is this more "polite" than the one above? They both seem to be equally "bad"?

* in another (polite) package:
```julia
struct Y <: AbstractFloat end
function Base.:(==)(::Integer, ::Y) end
Copy link
Member

Choose a reason for hiding this comment

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

Ah, it is "polite" because Y is not a subtype of Integer? perhaps this could be made explicit via a comment:

Suggested change
function Base.:(==)(::Integer, ::Y) end
function Base.:(==)(::Integer, ::Y) end # this is fine as Y is not a subtype of Integer

Comment on lines +1186 to +1187
Then:
* Do not add a method to `f` such that the type of either argument is not constrained (type `Any`). For example, this is not valid:
Copy link
Member

Choose a reason for hiding this comment

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

In which sense is it not "valid"? It certainly is valid Julia code, just "impolite" as you call it later on.

How about

Suggested change
Then:
* Do not add a method to `f` such that the type of either argument is not constrained (type `Any`). For example, this is not valid:
Then:
* Do not add a method to `f` such that the type of either argument is not constrained (type `Any`). For example, this violates the rule:

Or perhaps fully lean into this "polite" / "impolite" business:

Suggested change
Then:
* Do not add a method to `f` such that the type of either argument is not constrained (type `Any`). For example, this is not valid:
Then in order to write "polite" code:
* Do not add a method to `f` such that the type of either argument is not constrained (type `Any`). For example, this is not polite:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs This change adds or pertains to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

promote_rule: forbid method definitions which may cause ambiguity for unknown types

5 participants