# Question about transitioning to a Revise-based workflow

**URL:** <https://discourse.julialang.org/t/question-about-transitioning-to-a-revise-based-workflow/14273>\
**Category:** General Usage\
**Tags:** question\
**Created:** [August 29, 2018, 9:36pm UTC](https://discourse.julialang.org/t/question-about-transitioning-to-a-revise-based-workflow/14273 "2018-08-29T21:36:14Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![omalled](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/omalled/32/12532_2.png) [@omalled](https://discourse.julialang.org/u/omalled)\
**Post date:** [August 29, 2018, 9:36pm UTC](https://discourse.julialang.org/t/question-about-transitioning-to-a-revise-based-workflow/14273/1 "2018-08-29T21:36:14Z")

</div>

I am making the move from 0.6 to 0.7 and transitioning from a `reload("MyModule"); include("myscript.jl")` workflow to a [Revise](https://github.com/timholy/Revise.jl)-based workflow as recommended in the deprecation warning for `reload`. I am using the setup described in the [Using Revise by default](https://timholy.github.io/Revise.jl/stable/config.html#Using-Revise-by-default-1) section of the documentation.

I’ll try to demonstrate the issue I am having with a MWE module called `MyMod` that goes through three versions and it seems like `Revise` falls a version behind and can’t get me up to the latest version of `MyMod`. Here’s what I see from within julia (version 0.7.0) as I go through this:

```julia
julia> import MyMod #importing version 1 of MyMod
[Info: Precompiling MyMod [39b22132-abcb-11e8-1d53-e5fa610b8d45]

julia> revise(MyMod) #calling revise after going to version 2 of MyMod
true#note that "asdf" is not printed as I would anticipate for version 2

julia> revise(MyMod) #calling revise after going to version 3 of MyMod
asdf #now it prints "asdf"!
true #however, it doesn't print "blah" as I would anticipate for version 3 -- it seems like I am at version 2

julia> revise(MyMod) #calling revise again with the code still at version 3 of MyMod
true #neither "asdf" nor "blah" isn't printed -- still doesn't appear as if version 3 has been loaded

```

Here are the different versions of MyMod:

Version 1:

```julia
module MyMod
macro mymacro()
	:(1)
end
@mymacro
end

```

Version 2:

```julia
module MyMod
macro mymacro()
	println("asdf")
	:(1)
end
@mymacro
end

```

Version 3:

```julia
module MyMod
macro mymacro()
	println("asdf")
	println("blah")
	:(1)
end
@mymacro
end

```

The only way I can see to get to version 3 with a `Revise`-based workflow is by starting a new julia session. With the `reload`-based workflow I could have just `reload`ed and not had to restart julia. Given that the purpose of `Revise` is to reduce the number of times you have to restart julia (and given Tim Holy’s godlike julia prowess), I feel as if I am missing something or doing something wrong.

Is there a way to get to version 3 with a `Revise`-based workflow without restarting julia? With julia 0.7, is there a simple way that I can be confident that the latest version of my module has been loaded aside from restarting 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:** [August 30, 2018, 6:55am UTC](https://discourse.julialang.org/t/question-about-transitioning-to-a-revise-based-workflow/14273/2 "2018-08-30T06:55:57Z")

</div>

Why do you need to call `revise` explicitly? I thought that it hooks into `import` and then just watches the files for changes, so if you are following the default setup, everything should work automatically.

---

<div class="post-metadata">

**Author:** ![oatlzzvztd](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oatlzzvztd/32/3285_2.png) [@oatlzzvztd](https://discourse.julialang.org/u/oatlzzvztd)\
**Post date:** [August 30, 2018, 1:24pm UTC](https://discourse.julialang.org/t/question-about-transitioning-to-a-revise-based-workflow/14273/3 "2018-08-30T13:24:01Z")

</div>

> [@Tamas\_Papp](#):
>
> Why do you need to call `revise` explicitly?

From [the docs](https://timholy.github.io/Revise.jl/stable/limitations.html):

> If you change a macro definition or methods that get called by `@generated` functions outside their `quote` block, these changes will not be propagated to functions that have already evaluated the macro or generated function.

> You may explicitly call `revise(MyModule)` to force reevaluating every definition in module `MyModule` . Note that when a macro changes, you have to revise all of the modules that _use_ it.

I would file an issue with Revise.jl.

---

<div class="post-metadata">

**Author:** ![omalled](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/omalled/32/12532_2.png) [@omalled](https://discourse.julialang.org/u/omalled)\
**Post date:** [August 30, 2018, 3:35pm UTC](https://discourse.julialang.org/t/question-about-transitioning-to-a-revise-based-workflow/14273/4 "2018-08-30T15:35:01Z")

</div>

Yeah, that second part you quoted from the documentation was what led me to start calling `revise(MyMod)`.

I also thought of `revise(MyMod)` as a replacement for `reload("MyMod")`. That is, it ostensibly provides an explicit mechanism (which I love) to get latest version of a module rather than an implicit mechanism (which I merely like).

I’ll open an issue at the Revise repo.

---

<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:** [August 30, 2018, 6:22pm UTC](https://discourse.julialang.org/t/question-about-transitioning-to-a-revise-based-workflow/14273/5 "2018-08-30T18:22:29Z")

</div>

> I’ll open an issue at the Revise repo.

I happened to notice this and beat you to it. Indeed there’s already a fix posted at [Store unexpanded macros in defs (fixes #174) by timholy · Pull Request #175 · timholy/Revise.jl · GitHub](https://github.com/timholy/Revise.jl/pull/175).

To explain, let me at least show what was and wasn’t happening. This was my live session:

```julia
julia> push!(LOAD_PATH, "/tmp/pkgs")
4-element Array{String,1}:
 "@"        
 "@v#.#"    
 "@stdlib"  
 "/tmp/pkgs"

shell> cp MyMod1.jl MyMod.jl

julia> import MyMod
[Info: Recompiling stale cache file /home/tim/.julia/compiled/v1.0/MyMod.ji for MyMod [top-level]

julia> MyMod.@mymacro
1

shell> cp MyMod2.jl MyMod.jl

julia> revise(MyMod)
true

julia> MyMod.@mymacro
asdf
1

shell> cp MyMod3.jl MyMod.jl

julia> revise(MyMod)
asdf
true

julia> MyMod.@mymacro
asdf
blah
1

```

On balance I’d say things mostly look good, right? However, I’m guessing you’re puzzled about why `@mymacro` doesn’t run each time. Here’s some insight:

```julia
julia> fi = Revise.fileinfos["/tmp/pkgs/MyMod/src/MyMod.jl"]
Revise.FileInfo(OrderedCollections.OrderedDict(Main=>FMMaps(<0 expressions>, <0 signatures>),MyMod=>FMMaps(<1 expressions>, <0 signatures>)), "/home/tim/.julia/compiled/v1.0/MyMod.ji")

julia> fi.fm[MyMod].defmap
OrderedCollections.OrderedDict{Revise.RelocatableExpr,Union{Nothing, Tuple{Array{Any,1},Int64}, RelocatableExpr}} with 1 entry:
  :($(Expr(:macro, :(mymacro()), quote… => nothing

julia> first(fi.fm[MyMod].defmap)
:($(Expr(:macro, :(mymacro()), quote
    println("asdf")
    println("blah")
    $(QuoteNode(1))
end))) => nothing

```

In brief, what this means is that Revise is only storing a single expression, the definition of the macro itself. I am guessing that you’re expecting it to re-evaluate the macro? Note that wouldn’t happen if you said `using MyMod` again, so in a sense this is OK.

**However** , this was related to a real bug. Let’s change this to a macro that performs a transformation on a method definition:

```julia
# MyMod1.jl
module MyMod
macro change(foodef)
    foodef.args[2].args[2] = 1
    esc(foodef)
end
@change foo(x) = 0
end

# MyMod2.jl
module MyMod
macro change(foodef)
    foodef.args[2].args[2] = 2
    esc(foodef)
end
@change foo(x) = 0
end

# MyMod3.jl
module MyMod
macro change(foodef)
    foodef.args[2].args[2] = 3
    esc(foodef)
end
@change foo(x) = 0
end

```

then we get something that _is_ clearly a bug:

```julia
julia> push!(LOAD_PATH, "/tmp/pkgs")
4-element Array{String,1}:
 "@"        
 "@v#.#"    
 "@stdlib"  
 "/tmp/pkgs"

shell> cp MyMod1.jl MyMod.jl

julia> import MyMod
[Info: Recompiling stale cache file /home/tim/.julia/compiled/v1.0/MyMod.ji for MyMod [top-level]

julia> MyMod.foo("hello")
1

shell> cp MyMod2.jl MyMod.jl

julia> revise(MyMod)
true

julia> MyMod.foo("hello")
1

shell> cp MyMod3.jl MyMod.jl

julia> revise(MyMod)
true

julia> MyMod.foo("hello")
2

```

and the reason is that the macro has been expanded:

```jullia
julia> collect(fi.fm[MyMod].defmap)
2-element Array{Pair{Revise.RelocatableExpr,Union{Nothing, Tuple{Array{Any,1},Int64}, RelocatableExpr}},1}:
 :($(Expr(:macro, :(change(foodef)), quote
    (foodef.args[2]).args[2] = 2
    esc(foodef)
end))) => nothing                         
                                                           :(foo(x) = begin
          2
      end) => (Any[Tuple{typeof(foo),Any}], 0)

```

You can see the `@change` isn’t present in the last entry. That’s because Revise was expanding macros in order to parse the signature (necessary for the recent fix of [Line numbers · Issue #51 · timholy/Revise.jl · GitHub](https://github.com/timholy/Revise.jl/issues/51), and now more obviously by Rebugger). But it should have been storing the _unexpanded_ version of the expression, which is what the fix in [Store unexpanded macros in defs (fixes #174) by timholy · Pull Request #175 · timholy/Revise.jl · GitHub](https://github.com/timholy/Revise.jl/pull/175) does:

```julia
julia> collect(fi.fm[MyMod].defmap)
2-element Array{Pair{Revise.RelocatableExpr,Union{Nothing, Tuple{Array{Any,1},Int64}, RelocatableExpr}},1}:
 :($(Expr(:macro, :(change(foodef)), quote
    (foodef.args[2]).args[2] = 3
    esc(foodef)
end))) => nothing                         
                                           :(@change foo(x) = begin
              0
          end) => (Any[Tuple{typeof(foo),Any}], 0)

```

---

<div class="post-metadata">

**Author:** ![omalled](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/omalled/32/12532_2.png) [@omalled](https://discourse.julialang.org/u/omalled)\
**Post date:** [August 30, 2018, 10:23pm UTC](https://discourse.julialang.org/t/question-about-transitioning-to-a-revise-based-workflow/14273/6 "2018-08-30T22:23:55Z")

</div>

Thanks for the quick fix and detailed response. I really appreciate all your contributions to the julia ecosystem.
