# Manually reloading a module in 1.1?

**URL:** <https://discourse.julialang.org/t/manually-reloading-a-module-in-1-1/25572>\
**Category:** General Usage\
**Tags:** question\
**Created:** [June 23, 2019, 2:58pm UTC](https://discourse.julialang.org/t/manually-reloading-a-module-in-1-1/25572 "2019-06-23T14:58:58Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![srs](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/srs/32/8206_2.png) [@srs](https://discourse.julialang.org/u/srs)\
**Post date:** [June 23, 2019, 2:58pm UTC](https://discourse.julialang.org/t/manually-reloading-a-module-in-1-1/25572/1 "2019-06-23T14:58:58Z")

</div>

How do I _manually_ reload a module in Julia 1.1? (I’m on 1.1.1 to be specific)

I’m aware that Revise.jl exists, but it does have its known limitations and I’ve also seen issues and crashes together with Jupyter. These issues should of course be investigated separately. However, I figured there just _should_ be some way to reload a module manually if anything else fails.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [June 23, 2019, 3:08pm UTC](https://discourse.julialang.org/t/manually-reloading-a-module-in-1-1/25572/2 "2019-06-23T15:08:47Z")

</div>

Just re-`include` the file that defines the module, or evalute the module definition manually.

---

<div class="post-metadata">

**Author:** ![srs](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/srs/32/8206_2.png) [@srs](https://discourse.julialang.org/u/srs)\
**Post date:** [June 23, 2019, 3:17pm UTC](https://discourse.julialang.org/t/manually-reloading-a-module-in-1-1/25572/3 "2019-06-23T15:17:58Z")

</div>

Ok, that sounds easy. Thanks!

A follow-up question: Say I have defined my own little module `MyMod` and I’ve configured my `LOAD_PATH` so that I can just say `using MyMod`. Is there now any way to get the defining file from the module object? In this case, I could write my own `reload(module_object) = include(defining_file(module_object))` function without having to remember where I put that code.

---

<div class="post-metadata">

**Author:** ![srs](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/srs/32/8206_2.png) [@srs](https://discourse.julialang.org/u/srs)\
**Post date:** [June 23, 2019, 5:32pm UTC](https://discourse.julialang.org/t/manually-reloading-a-module-in-1-1/25572/4 "2019-06-23T17:32:23Z")

</div>

FWIW, I just wrote my little routine in my `startup.jl` that tries to do a reasonable job at loading the right file. It’s enough for me, but probably doesn’t cover all of Julia’s package system.

```julia
"""
    reloadfj("MyModule")
    reloadfj(:MyModule)

Reload-find-in-julia. Searches load_path() for likely locations of a <mod>.jl file and re-include()s it, which is apparently how you manually reload stuff in Julia.
"""
function reloadfj(mod::String)
    lp = Base.load_path()
    for s in lp
        d, f = splitdir(s)
        if f == "Project.toml"
            filedir = joinpath(d, "src")
        else
            filedir = s
        end
        f = joinpath(filedir, "$mod.jl")
        if isfile(f)
            include(f)
            return # Only reload once if we happen have the same dir twice in the LOAD_PATH
        end
    end
    @error "Module '$mod' not found in LOAD_PATH" mod expanded_load_path=lp
end
reloadfj(mod::Symbol) = reloadfj(string(mod))

```

---

<div class="post-metadata">

**Author:** ![srs](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/srs/32/8206_2.png) [@srs](https://discourse.julialang.org/u/srs)\
**Post date:** [June 23, 2019, 5:44pm UTC](https://discourse.julialang.org/t/manually-reloading-a-module-in-1-1/25572/5 "2019-06-23T17:44:07Z")

</div>

@pfitzseb, I just found another issue. Turns out, re-including doesn’t update the exported identifiers in scope.

Say I changed a function `myfun` in `MyMod`. Then:

```julia
> include("MyMod.jl"); using .MyMod
WARNING: replacing module MyMod.
WARNING: using MyMod.myfun in module Main conflicts with an existing identifier.

```

This leaves _two_ versions of `myfun` in scope: The new one, as `MyMod.myfun` and the old one, as `myfun`. This is a problem, because my code (Jupyter cells / REPL history) mentions the unqualified name.

So to even be able to reload anything, I’d _always_ have to use the qualified name from the beginning. There must be a better way!

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [June 24, 2019, 6:50am UTC](https://discourse.julialang.org/t/manually-reloading-a-module-in-1-1/25572/6 "2019-06-24T06:50:57Z")

</div>

You might be interested in Revise.jl

---

<div class="post-metadata">

**Author:** ![srs](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/srs/32/8206_2.png) [@srs](https://discourse.julialang.org/u/srs)\
**Post date:** [June 24, 2019, 2:03pm UTC](https://discourse.julialang.org/t/manually-reloading-a-module-in-1-1/25572/7 "2019-06-24T14:03:39Z")

</div>

> [@nilshg](#):
>
> You might be interested in Revise.jl

Given what I’ve written in my original question, I would’ve appreciated a bit more than a single-package answer here.

> [@srs](#):
>
> I’m aware that Revise.jl exists, but it does have its known limitations and I’ve also seen issues and crashes together with Jupyter. These issues should of course be investigated separately. However, I figured there just _should_ be some way to reload a module manually if anything else fails.

I noticed that `Revise` exposes a `revise(mod::Module)` function to manually reload a module and one can deactivate automatic reloading via `ENV["JULIA_REVISE"] = "manual"`. I’ll try that now.

Having said that, Revise messes with _many_ Julia internals (just look at ` __init__ ()`!) to get _a lot_ of features (like truely inremental reload). I was hoping for something much simpler and (thus) more stable. Re-including everything doesn’t do the trick.

I’m surprised, frankly, that no such “plain & simple” reloading functionality is included in the language. AFAIS, it shouldn’t be that hard: For every identifier, keep track of the module that defines it and if the user asks to reload that module, just delete it before reloading. I guess there are some intricacies with, say, methods of the same function defined in different modules, but I don’t see anything that should _fundamentally_ prohibit this feature _and_ that is more important than having simple, robust reloading.

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [June 24, 2019, 2:09pm UTC](https://discourse.julialang.org/t/manually-reloading-a-module-in-1-1/25572/8 "2019-06-24T14:09:10Z")

</div>

Apologies, was on my phone this morning and didn’t properly read through your OP, just saw in the last post that you had issues with redefining functions in modules, which is why Revise.jl seemed like an obvious thing to use!

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [July 27, 2019, 11:08am UTC](https://discourse.julialang.org/t/manually-reloading-a-module-in-1-1/25572/9 "2019-07-27T11:08:22Z")

</div>

Use `import` rather than `using` and scope every call (e.g., `MyMod.myfun(x)` rather than `myfun(x)`). Yes, that’s more verbose, but it’s the only “plain & simple” approach there is. Once types get defined (and each function has a type), Julia can’t undefine them; what do you do with old objects of those old types? Everything must have a type, and once a name means one thing it can’t mean another.

Just wishing this were a simple problem doesn’t make it so—Revise is complicated because it’s a complicated problem. It _should_ be pretty reliable and stable, so if it’s not please do report issues.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 27, 2019, 11:39am UTC](https://discourse.julialang.org/t/manually-reloading-a-module-in-1-1/25572/10 "2019-07-27T11:39:34Z")

</div>

> [@tim.holy](#):
>
> Once types get defined (and each function has a type), Julia can’t undefine them; what do you do with old objects of those old types?

AFAIK this problem is in principle solvable ([Common Lisp did it](http://www.lispworks.com/documentation/HyperSpec/Body/04_cf.htm)), it “just” requires a lot of work and is not a priority at the moment.

But it would be awesome. 😉

BTW, do you think that

> <https://github.com/JuliaLang/julia/pull/22721>
>
> Several of us have found \[Revise.jl\](https://github.com/timholy/Revise.jl) to be… a significant productivity booster. In principle, it's now possible to keep a Julia session open for a week or more, at which point one of the main negatives of Julia---the cost of JITting your, e.g., plotting package---becomes a non-issue.
> 
> However, there are two events which prevent this from being commonplace. One is method-deletion (#20048) and the other is type redefinition (https://github.com/timholy/Revise.jl/issues/18). It occurred to me that type redefinition may not be quite as nasty a problem as I've thought. A demo with this PR:
> \`\`\`julia
> julia\> struct Mine
> arg
> end
> 
> julia\> a = Mine(1)
> Mine(1)
> 
> julia\> foo(val::Mine) = val.arg
> foo (generic function with 1 method)
> 
> julia\> Base.shunt\_binding(Main, :Mine)
> Mine#1
> 
> julia\> a
> Mine#1(1)
> 
> julia\> foo(a)
> 1
> 
> julia\> struct Mine{T}
> arg::T
> end
> 
> julia\> x = Mine(3)
> Mine{Int64}(3)
> \`\`\`
> 
> The only catch I'm aware of is:
> \`\`\`julia
> julia\> foo(x)
> ERROR: MethodError: no method matching foo(::Mine{Int64})
> Closest candidates are:
> foo(::Mine#1) at REPL\[3\]:1
> \`\`\`
> 
> However, I wonder if this might be solvable via \`methodswith\` \*plus\* maintaining a cache of the source-code expressions so that they can be re-evaluated. (Revise would like that anyway, since it re-parses and caches every source file so that it can detect diffs. This adds considerably to the package load time, but caching the Exprs to the \`.ji\` file seems both cheap and effective.)

is still a viable approach?

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [July 27, 2019, 1:20pm UTC](https://discourse.julialang.org/t/manually-reloading-a-module-in-1-1/25572/11 "2019-07-27T13:20:56Z")

</div>

> [@Tamas\_Papp](#):
>
> AFAIK this problem is in principle solvable ([Common Lisp did it](http://www.lispworks.com/documentation/HyperSpec/Body/04_cf.htm)), it “just” requires a lot of work and is not a priority at the moment.

What does Lisp do with objects created at the REPL? E.g., `typeof(a)`. Those objects may not have the data needed to “convert” them to a new type.

> [@Tamas\_Papp](#):
>
> …still a viable approach?

Not easily. I think it’s still worth thinking about, but probably an easier solution would be to define new gensymmed type names and have some sort of autoreplacement. A sketch might be

```julia
Tnew = gensym(Told.name.name)
mths = methodswith(Told)
for m in mths
    Core.eval(m.mod, replacesym!(definition(m), Told=>Tnew)
    Base.delete_method(m)
end
Core.eval(mod_of_struct, replacesym!(struct_expr, Told=>Tnew))

```

together with a call to `replacesym!` in Revise’s [REPL loop](https://github.com/timholy/Revise.jl/blob/d160813bed054d80fe29854a3178fb726b3e808b/src/Revise.jl#L949). Would make a great PR for someone interested in learning a bit more about Revise’s internals!

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [July 27, 2019, 4:42pm UTC](https://discourse.julialang.org/t/manually-reloading-a-module-in-1-1/25572/12 "2019-07-27T16:42:11Z")

</div>

> [@tim.holy](#):
>
> What does Lisp do with objects created at the REPL? E.g., `typeof(a)` . Those objects may not have the data needed to “convert” them to a new type.

IIRC you’ll get some kind of error if the layout changed and you’re using the old object, but I don’t remember it actually segfaulting or anything. It was very convenient, although the problem may be more complicated in Julia.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 28, 2019, 5:17am UTC](https://discourse.julialang.org/t/manually-reloading-a-module-in-1-1/25572/13 "2019-07-28T05:17:59Z")

</div>

I don’t think you get an error: new slots are just added and old slots deleted, and then you can, in the typical Lisp manner of course, [customize the whole thing](http://clhs.lisp.se/Body/f_upda_1.htm#update-instance-for-redefined-class). Thinking about this, maybe this is overkill for Julia.

What I would consider a reasonable solution for Julia is have the old types available, but make the name refer to the new type after redefinition. Eg in

```julia
struct Foo end
bar(x::Foo) = typeof(x)
B = bar(Foo())

```

if the type is redefined as

```julia
struct Foo
    a::Int
end

```

then `bar` is recompiled at some point before it is called next time, as then

```julia
B !=== bar(Foo())

```

and the old type would still be available, you just would not be able to instantiate it and it would print differently, eg

```julia
julia> B
Foo [redefined at world age ...]

```

Maybe there is a wrinkle I am not seeing though.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [July 28, 2019, 11:42am UTC](https://discourse.julialang.org/t/manually-reloading-a-module-in-1-1/25572/14 "2019-07-28T11:42:04Z")

</div>

Right, that’s basically the solution I’m hoping for too. The blocker is [https://github.com/JuliaLang/julia/pull/22721#issuecomment-315564890](https://github.com/JuliaLang/julia/pull/22721#issuecomment-315564890).
