# \[ANN\] Higher productivity (fewer Julia restarts) with Revise.jl

**URL:** <https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564>\
**Category:** Community\
**Tags:** package, announcement, productivity, development\
**Created:** [June 30, 2017, 1:36pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564 "2017-06-30T13:36:56Z")\
**Posts on this page:** 13\
**Page:** 3

<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:** [April 29, 2018, 4:00am UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/41 "2018-04-29T04:00:53Z")

</div>

For those who don’t want to watch a long video, could you please summarize the gist of that approach?

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [April 29, 2018, 5:28am UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/42 "2018-04-29T05:28:16Z")

</div>

I mean 2.

---

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [April 29, 2018, 6:47am UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/43 "2018-04-29T06:47:21Z")

</div>

The video talks about [TDD](https://en.wikipedia.org/wiki/Test-driven_development), which is a great workflow for coding.

With respect to this discussion, Chris also used `Pkg.test("PackageName")` function in REPL. Here’re my observations when I tried to use it for my package development:

Pros

1. It works flawlessly, even if I make changes to a struct (for which Revise could not work… at least with Julia v0.6.2… not sure about v0.7)

Cons

1. It takes a few seconds to run (seems to have some startup overhead).

2. It runs the whole test suite from `runtests.jl`. That’s probably not too annoying if the tests run quickly. When I test SASLib it goes through many file read operations so it’s less efficient than using Revise.

3. It does not recognize the package if it’s not installed in the Julia’s standard package directory.

---

<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:** [April 29, 2018, 7:10am UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/44 "2018-04-29T07:10:03Z")

</div>

> [@tk3369](#):
>
> The video talks about TDD , which is a great workflow for coding.

I see. I would say that this is mostly a solution to an orthogonal question. One can do TDD independently of using Revise.jl.

---

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [April 29, 2018, 7:52am UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/45 "2018-04-29T07:52:14Z")

</div>

Right.

In the video, Chris also demonstrated the use of `Pkg.test` function. I’ve clarified in my post above as such.

---

<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:** [April 29, 2018, 8:10am UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/46 "2018-04-29T08:10:18Z")

</div>

> [@tk3369](#):
>
> changes to a struct (for which Revise could not work… at least with Julia v0.6.2… not sure about v0.7)

Indeed, this is an open issue. See

> <https://github.com/timholy/Revise.jl/issues/18>
>
> Since \`struct\`s cannot be redefined, attempting to do so currently gives a \`fail…ure to evaluate changes\` warning.
> 
> I wonder if this can be worked around by triggering a reload of the entire module in this case.

> <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.)

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [April 29, 2018, 8:15am UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/47 "2018-04-29T08:15:32Z")

</div>

Using the eval-in-module functionality in Juno was frequently used as a manual “poor man’s Revise” before Revise was made. The great thing about Revise is that there is no need to manually evaluate the things you want to update. That is taken care for you.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [April 29, 2018, 2:30pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/48 "2018-04-29T14:30:28Z")

</div>

> [@tk3369](#):
>
> With respect to this discussion, Chris also used Pkg.test(“PackageName”) function in REPL. Here’re my observations when I tried to use it for my package development:

I do that after I think something works because Juno in-module or Revise utilize your current state, and sometimes you’ll mix random stuff from the REPL with your tests and it’ll “work”. `Pkg.test` tests in a completely clean environment to make sure that nothing can be wrong. But since it then runs all of the tests, that’s why I use it sparingly, and most of the video is how to avoid `Pkg.test`.

As @kristoffer.carlsson stated, Revise.jl is a more powerful form of what Juno has built in. You could use either one to do development like this, YMMV.

---

<div class="post-metadata">

**Author:** ![jlperla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlperla/32/34332_2.png) [@jlperla](https://discourse.julialang.org/u/jlperla)\
**Post date:** [April 29, 2018, 3:55pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/49 "2018-04-29T15:55:04Z")

</div>

> [@Tamas\_Papp](#):
>
> I would say that this is mostly a solution to an orthogonal question. One can do TDD independently of using Revise.jl.

Certainly not mutually exclusive, but when thinking about modifying the default Julia experience (and documentation, and tutorials presumably?) to enable better workflows, I think it is important to consider ways people work with Julia. The Chris workflow makes TDD easy, but you don’t need to use it.

The reason I like the Chris workflow is that you get immediate feedback after you modify your core functions (ie the shift-enter tells you if it compiles), the visual feedback is local to what you are modifying, and it doesn’t need to recompile or mess with any other functions.

Then when you are messing with the code to test your modified functions, you can do it in whatever order you wish (ie you can just execute the lines of testing code effected by your modified function with a shift enter) and the visual feedback is again local to where you are running the code. Of course, you need to run the full Pkg.test eventually, but not while you are figuring things out.

Not to say that this is necessarily incompatible with Revise.jl workflow, but I haven’t tried that approach with Revise turned on… For example, if I happen to save my file while doing my approach, would revise end up recompiling a whole bunch of things, redoing the using, etc? Not sure,but I think some testing should occur before merging Revise.jl into the default experience

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [April 29, 2018, 4:03pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/50 "2018-04-29T16:03:12Z")

</div>

> [@jlperla](#):
>
> The Chris workflow makes TDD easy, but you don’t need to use it.

Should that be the ChrisWorkflow™? 🤓

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [April 29, 2018, 4:09pm UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/51 "2018-04-29T16:09:47Z")

</div>

> [@ScottPJones](#):
>
> Should that be the ChrisWorkflow™? 🤓

Give the Juno team the credit.

---

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [April 30, 2018, 1:02am UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/52 "2018-04-30T01:02:51Z")

</div>

> [@ChrisRackauckas](#):
>
> Pkg.test tests in a completely clean environment to make sure that nothing can be wrong. But since it then runs all of the tests, that’s why I use it sparingly, and most of the video is how to avoid Pkg.test.

Exactly. I pretty much follow this work flow:

1. Use REPL for testing
2. Use Revise so I don’t have to restart the REPL when a module is changed
3. Restart REPL when Revise fails to hot swap my change e.g. struct changes

I’m unsure if `Pkg.test()` is any better than just invoking the test script from the shell. In fact, when I have multiple test scripts, I would rather run a test script that’s targeted for my change. Then, once in a while, I would invoke `julia runtests.jl` to ensure that nothing is broken.

---

<div class="post-metadata">

**Author:** ![djsegal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djsegal/32/13752_2.png) [@djsegal](https://discourse.julialang.org/u/djsegal)\
**Post date:** [April 30, 2018, 2:13am UTC](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564/53 "2018-04-30T02:13:24Z")

</div>

Hate to do this again, but Rails has this cool tool called guard that automatically runs tests as you save files.

// you can manually configure it so that it regex’s to find all relevant tests

[https://github.com/guard/guard-minitest](https://github.com/guard/guard-minitest)

* * *

I always thought Revise.jl could be the cornerstone of a dev framework for all sorts of toys like this (e.g. testing)

[Previous page](https://discourse.julialang.org/t/ann-higher-productivity-fewer-julia-restarts-with-revise-jl/4564.md?page=2)
