Is it OK to structure my packages like this (benign type piracy)?

nsajko
Thu, 06 Mar 2025 11:24:39 +0000
General Usage

Is this design OK? Is this supported by precompilation? What could go wrong? Could package extensions help here somehow, if necessary?

The idea is basically to define a function with no methods in PackageA and only add methods to it from PackageB. It’s type piracy, but maybe it’s OK if I document it. I think the only way this can go wrong is if someone purposefully makes a third package with the intent of breaking my packages (however that’s always possible, in any case, whether my packages do type piracy or not).

A basic example

package PackageA

Depends only on julia.

module PackageA
    """
        a::Function

    Only add methods if you're `PackageB`!
    """
    function a end
end

package PackageB

Depends on julia and on PackageA.

module PackageB
    using PackageA: PackageA

    # benign piracy?
    function PackageA.a(l, r)
        l - r
    end
end

A slightly more fleshed-out example

package PackageA

Depends only on julia.

module PackageA
    export A

    """
        a::Function

    Only add methods if you're `PackageB`!
    """
    function a end

    """
        A::Type

    Some type. Has multiplication defined on it only after loading `PackageB`.
    """
    struct A <: Number end

    function Base.:(*)(l::A, r::A)
        a(l, r)
    end
end

package PackageB

Depends on julia and on PackageA.

module PackageB
    export B

    using PackageA: PackageA, A

    struct B <: Number end

    function Base.:(*)(l::B, r::B)
        A()
    end

    # benign piracy?
    function PackageA.a(l::A, r::A)
        B()
    end
end

6 posts - 6 participants