Is it OK to re-export something from a different package?

As the title say, i am wandering if it is OK to reexport a method from a different package. I currently have :

module MyPackage

using OtherPackage

struct mytype end
OtherPackage.function(x::mytype) = 1

end

The fact is that MyPackage provides new methods to this function, on types that are defined in MyPackage (so no type piracy), but the generic is only exported if I do :

using MyPackage
# Cannot use `function`
using OtherPackage
# Now i can 

Would it me OK to export OtherPackage.function, so that i could do:

using MyPackage
# `function` is available

?

1 Like

If I’m understanding you correctly, in this case you could. It is also natural to just tell your users they must load both packages.

3 Likes

Thanks. Do you know if there is a ‘standard’, or a good practice regarding the choice between re-exporting and telling people to load both packages ?

1 Like

I would say that it depends on the relationship between your package and the other package. If your package builds “on top of” the other package but a user wouldn’t particularly need to be aware of the underlying package then re-export. If your package is an addition that a user would be using while also using the underlying package directly then advise they load both.

9 Likes

Seems fair, thanks.

What is the exact syntax for re-exporting a function from another package?

This is not working for me.

EDIT: Sorry, this was a git and a dev vs. add issue. The code below is now working as intended.

module MyPackage
using AlgebraOfGraphics
export draw

struct MyType
    data::SomeOtherType
    plot::Layer # type from AoG
end
export MyType

function f()
    # computations
    return MyType(data, plot)
end
export f

end # module 
julia> using MyPackage

julia> results = f();

julia> draw(results.plot)

I did get an unexpected error when I wrote export AlgebraOfGraphics.draw instead of export draw though. I would have thought either would work?

julia> using MyPackage
[ Info: Precompiling MyPackage [d29f79e6-4313-439e-a1e0-c6c95527bf41]
ERROR: LoadError: syntax: "module" at <file_path>.jl:1 expected "end", got "."

If you have package B and C which extend a method from package A, is it okay if both B and C export the extended function from A? Any best practices to be aware of?

Hello,

I’m in a similare situation, where this time OtherPackage is LinearAlgebra. In my package QuantumToolbox.jl I apply several methods of the LinearAlgebra.jl functions to my types.

What should I do? I it a good idea to reexport LinearAlgebra?

For those checking this thread in the future, the Reexport.jl package is useful when you need to reexport modules of your main package:

In that case you can do

module MyPackage

using Reexport

@reexport DepPackage1
@reexport DepPackage2
...

end

Here is a real example.

Thanks.

I was currently aware of Reexport.jl. My question was more related to the choice or not to re-export the LinearAlgebra package.

I see that many people just re-export their dependencies belonging to the same ecosystem. So I was wondering if re-exporting a Base library like LinearAlgebra was something to avoid or not.

I don’t think anything “bad” would happen, but, personally, I would definitely frown upon in. If you don’t “own” it, it seems to me you shouldn’t export it. (“Own” can mean “in my org”, so re-exporting from a base package is fine).

But then, I’m fairly conservative when it comes to exports, anyway. I might even lean towards considering it a bad idea altogether (it pushes people towards “star imports”, i.e., unqualified using, which took the Python community years to root out after finding out that it was a really bad idea). Maybe now that we have public, packages shouldn’t declare exports at all anymore. But in any case, I think of export as “public plus convenience in the REPL for throwaway code”. If you think in terms of public, it feels even weirder to declare something public that you don’t own. So, the same should apply to export. But I don’t think there’s a “correct” answer here. This is completely opinion based, so at best, you’ll get a community majority opinion poll on how people feel about exports, which will probably be divided between the types of people that I might call “users” and “developers” :wink:

In your case, is there any concrete benefit to users not having to do an explicit using LinerAlgebra? I believe the mantra “explicit is better than implicit” holds.

4 Likes

Thanks for the detailed reply.

In my case I declare many methods like

LinearAlgebra.tr(A::QuantumObject) = tr(A.data)

and many more.

This implies that, if the user needs to compute the trace, the LinearAlgbebra package has to be imported. That’s why we decided to use Reexport.jl.

It is also fine for me to import LiearAlgebra every time I import my package. But of course avoiding it is simpler for the new user.