# Bug about reloading a package

**URL:** <https://discourse.julialang.org/t/bug-about-reloading-a-package/100193>\
**Category:** General Usage\
**Tags:** question\
**Created:** [June 11, 2023, 5:05pm UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193 "2023-06-11T17:05:03Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![lionisxn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lionisxn/32/37989_2.png) [@lionisxn](https://discourse.julialang.org/u/lionisxn)\
**Post date:** [June 11, 2023, 5:05pm UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/1 "2023-06-11T17:05:03Z")

</div>

I just found that in the latest version v.1.9.×, reloading a function of a package alters the original behavior of the same function of the package when being called independently. For instance, define a module “test” to reload the “Distributions: rand”,

> module test  
> import Distributions: rand  
> function rand()  
> println(“reload!\n”)  
> end  
> end

then, edit a script to call them independently like this:

> include(“D:/test/test.jl”)  
> import .test, Distributions  
> Distributions.rand()

The result is that the last calling of “Distributions.rand()” is affected by the reloading operation of the module test, i.e. to display the string of “reload!” rather than a random number! Such a behavior change is very unexpected. Any suggestion?

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [June 11, 2023, 5:45pm UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/2 "2023-06-11T17:45:34Z")

</div>

This is the normal behavior, although it is pretty unexpected at first. What you’re doing is called “type piracy” and it is frowned upon for that very reason 🏴‍☠️  
As a general rule, you can implement

- existing functions on your own types
- your own functions on existing types
- but never both at the same type, which is what you did by redefining `Base.rand` for no argument

See the docs about it: [https://docs.julialang.org/en/v1/manual/style-guide/#Avoid-type-piracy](https://docs.julialang.org/en/v1/manual/style-guide/#Avoid-type-piracy)

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 11, 2023, 8:28pm UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/3 "2023-06-11T20:28:09Z")

</div>

I’m not really sure why this is unexpected for you, but I’m guessing you expected `Distributions.rand` loaded in your `test` to belong to the module `test`. It’s actually the opposite, imported functions definitely do not belong to the module they’re imported in. They may not even belong to the module you imported them from, because that module may have imported it from yet another module. You can check with `parentmodule(rand)`, which tells you `Base`. A function’s multiple methods can be defined in multiple modules, like `test` or `Distributions`, but they’re just extending the function in its parent module. `test.rand === Distributions.rand === Base.rand`.

Instead of overriding an existing function, you could make your own `rand` function that belongs to `test`. However, if you want to use `Base.rand`, you will have to write out the name since the name `rand` will refer to your function in the scope of `module test`. When you import from `test` to other modules, you’ll also have to make the decision of which `rand` is more important. Imports can also rename now, so name collisions are manageable.

```julia
julia> module Test2
           function rand() println("reload!\n") end

           rand()
           println(Base.rand())

       end
reload!

0.4336162318813531
Main.Test2

```

---

<div class="post-metadata">

**Author:** ![lionisxn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lionisxn/32/37989_2.png) [@lionisxn](https://discourse.julialang.org/u/lionisxn)\
**Post date:** [June 12, 2023, 1:49am UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/4 "2023-06-12T01:49:52Z")

</div>

Many thanks, I just read about the type piracy and understand my code problem. But occasionally I need to extend a package by _only_ modifying the intermediate function. For instance, provided that we already have a package:

> module pkg1  
> needRelaod() = 1  
> b() = 2  
> c() = needRelaod() + b() + 3   
> end

Now, we want to import it into another new package, and want c() to be reloaded by only modifying "needRelaod() " without changing “b()”. In such a case, the most hassle-free manner, however, could be the type piracy

> import pkg1: needRelaod  
> function needRelaod()  
> do something special  
> end

Note that, we can’t reload needRelaod() by other types, since we still want Pkg1.c() can call it. So, the type piracy can meet the requirement. Now, in order to avoid the type piracy, I have to copy the binary file of the pkg1 into my new module folder and take pkg1 as a local file for reloading. I feel such a manner is still not convenient. Could you please share better suggestions?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [June 12, 2023, 2:09am UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/5 "2023-06-12T02:09:12Z")

</div>

> [@lionisxn](#):
>
> So, the type piracy can meet the requirement. Now, in order to avoid the type piracy, I have to copy the binary file of the pkg1 into my new module folder and take pkg1 as a local file for reloading. I feel such a manner is still not convenient. Could you please share better suggestions?

if the author of `Pkg1` intends to support “user customization”, then they should reflect this in their library’s design, one possible way is to change how `c()` is defined:

```julia
c(func::F = needReload) where F = func() + b() + 3

```

or more sophisticated design that involves abstract type and downstream user can specialize to their own types and customize intermediate behavior.

* * *

another possibility is if you’re the author of both pkg1 and pkg2, and they form an “ecosystem”, it might be convenient and more understandable to commit “piracy” since you essentially control both pkgs

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [June 12, 2023, 5:17am UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/6 "2023-06-12T05:17:35Z")

</div>

And another option is to commit the piracy in a glue package called something like `Pkg1Pkg2Utils.jl`. Sure, piracy redefines the behavior for every downstream user, but since when they import that glue package explicitly, we can assume they agree to that. Of course things are different when the glue package is an implicit dependency of something else.

---

<div class="post-metadata">

**Author:** ![lionisxn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lionisxn/32/37989_2.png) [@lionisxn](https://discourse.julialang.org/u/lionisxn)\
**Post date:** [June 12, 2023, 8:26am UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/7 "2023-06-12T08:26:53Z")

</div>

All right, the idea of using glue package _Pkg1Pkg2Utils.jl_ is great, but it still cannot meet the requirement of calling both of Pkg1Pkg2Utils.needRelaod() and pkg1.needRelaod() without interfering with each other.

---

<div class="post-metadata">

**Author:** ![lionisxn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lionisxn/32/37989_2.png) [@lionisxn](https://discourse.julialang.org/u/lionisxn)\
**Post date:** [June 12, 2023, 8:29am UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/8 "2023-06-12T08:29:22Z")

</div>

> [@Benny](#):
>
> imported functions definitely do not belong to the module they’re imported in. They may not even belong to the module you imported them from, because that module may have imported it from yet another module. You can check with `parentmodule(rand)`, which tells you `Base`. A function’s multiple methods can be defined in multiple modules, like `test` or `Distributions`, but they’re just extending the function in its parent module. `test.rand === Distributions.rand === Base.rand`.

I learned it, thank you very much!

---

<div class="post-metadata">

**Author:** ![lionisxn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lionisxn/32/37989_2.png) [@lionisxn](https://discourse.julialang.org/u/lionisxn)\
**Post date:** [June 12, 2023, 8:40am UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/9 "2023-06-12T08:40:23Z")

</div>

Great share! But, I think that package developers are not always aware of all users’ future demands, and confining the ecosystem of a reloaded package to its parent package might be very helpful.

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [June 12, 2023, 9:38am UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/10 "2023-06-12T09:38:02Z")

</div>

In that case I’m afraid you need to redefine both functions.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 12, 2023, 10:21am UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/11 "2023-06-12T10:21:50Z")

</div>

> [@lionisxn](#):
>
> I think that package developers are not always aware of all users’ future demands,

They wouldn’t have to be, jling’s code lets the user input their custom functions. That function’s limitation is it must support addition with `b()` and `3`. That is an expectation that should be documented. You wouldn’t need to make end-users able to use this, you could do this internally to customize behavior in different packages.

---

<div class="post-metadata">

**Author:** ![lionisxn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lionisxn/32/37989_2.png) [@lionisxn](https://discourse.julialang.org/u/lionisxn)\
**Post date:** [June 12, 2023, 3:04pm UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/12 "2023-06-12T15:04:32Z")

</div>

You are right in the case that a package developer intends to let a customer to extend a function as will, but unfortunately, not all cases. Such an awareness of extending functions might require far-sighted code planning. I still believe in the value of limiting piracy type in the scope of a reloading module. Packages, if developed as such, can be shared in more flexible manner.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [June 12, 2023, 3:43pm UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/13 "2023-06-12T15:43:35Z")

</div>

> [@lionisxn](#):
>
> in the value of limiting piracy type

well if there’s another person belive the same thing, you would f\*\*\* each other’s code when someone use both your packages

---

<div class="post-metadata">

**Author:** ![kellertuer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kellertuer/32/220707_2.png) [@kellertuer](https://discourse.julialang.org/u/kellertuer)\
**Post date:** [June 12, 2023, 4:06pm UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/14 "2023-06-12T16:06:05Z")

</div>

But it could be easily solved if you provide your own type (some `struct MyBehaviourType end` and then implement `rand(::MyBehaviourType)` with your expected version of rand?

Otherwise you might “disturb” other peoples code, when the expect `rand()` to behave ad `Base` defines it (I hope no one else does, otherwise that is already type piracy)

You could define `MyPackage.rand()`, and not import `Base.rand` (or any other `rand()` coming from there), then you even can do it without a new type.  
_But_ then please do not export it, otherwise loading your package issues a warning like and both `Base.rand` and yours have to always be prefixed with the package name to resolve the ambiguity (in which rand Is meant).  
Without exporting it, yours has to always be prefixed, bt at least its not type piracy and not breaking other peoples code.

I believe in strongly discouraging _any_ type piracy, since that breaks other people’s code.

---

<div class="post-metadata">

**Author:** ![lionisxn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lionisxn/32/37989_2.png) [@lionisxn](https://discourse.julialang.org/u/lionisxn)\
**Post date:** [June 12, 2023, 4:15pm UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/15 "2023-06-12T16:15:10Z")

</div>

> [@kellertuer](#):
>
> I believe in strongly discouraging _any_ type piracy, since that breaks other people’s code.

All right, type piracy indeed triggers confusion, that is why I recommend to confine it to the reloading package.

---

<div class="post-metadata">

**Author:** ![kellertuer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kellertuer/32/220707_2.png) [@kellertuer](https://discourse.julialang.org/u/kellertuer)\
**Post date:** [June 12, 2023, 4:20pm UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/16 "2023-06-12T16:20:27Z")

</div>

Then I probably do not yet get your full use case here, because even after carefully reading this thread I do not yet see any good case where type piracy should ever be used.

---

<div class="post-metadata">

**Author:** ![lionisxn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lionisxn/32/37989_2.png) [@lionisxn](https://discourse.julialang.org/u/lionisxn)\
**Post date:** [June 12, 2023, 4:33pm UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/17 "2023-06-12T16:33:25Z")

</div>

> [@lionisxn](#):
>
> module pkg1  
> needRelaod() = 1  
> b() = 2  
> c() = needRelaod() + b() + 3  
> end

Briefly, for instance, one just wants to reload b() without altering anything else. Then Pkg1.c() can be called to employ the reloaded b(), in the meanwhile, Pkg1.b() is desired to behave the original strategy.

---

<div class="post-metadata">

**Author:** ![kellertuer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kellertuer/32/220707_2.png) [@kellertuer](https://discourse.julialang.org/u/kellertuer)\
**Post date:** [June 12, 2023, 6:00pm UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/18 "2023-06-12T18:00:41Z")

</div>

But that is impossible.  
_Either_ you do type piracy, then you _overwrite_ even the behaviour of `b` in this case (that is you import `Pkg1.b` and redefine its zero argument definition) _or_ you define a (second) `b()` outside of `Pkg1` then it does not have an effect \_within `Pkg1`. So either way, you do not achieve both things you want at the same time.

---

<div class="post-metadata">

**Author:** ![lionisxn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lionisxn/32/37989_2.png) [@lionisxn](https://discourse.julialang.org/u/lionisxn)\
**Post date:** [June 13, 2023, 2:51pm UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/19 "2023-06-13T14:51:13Z")

</div>

> [@lionisxn](#):
>
> Now, in order to avoid the type piracy, I have to copy the binary file of the pkg1 into my new module folder and take pkg1 as a local file for reloading

That is my comprised solution. It worked to perform both my requirment.

---

<div class="post-metadata">

**Author:** ![kellertuer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kellertuer/32/220707_2.png) [@kellertuer](https://discourse.julialang.org/u/kellertuer)\
**Post date:** [June 13, 2023, 4:02pm UTC](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193/20 "2023-06-13T16:02:04Z")

</div>

I would consider this still type piracy, just that no one can see this any longer, since you hide it in binary files.  
But also if you now change _anything_ in Pkg1 you have to manually copy over the binary?  
I am also not sure how “take pkg1 as a local file for reladong” would work in practice, but anything that defines code but also requires manually copying files – should even less be in anything productive/published/open source, even less than type piracy.  
The source of error (by someone forgetting the manual copy) is just too large.

[Next page](https://discourse.julialang.org/t/bug-about-reloading-a-package/100193.md?page=2)
