Future development goals with the new Revise

This is basically a reply to [ANN] Juno 0.8 - #23 by pfitzseb, but it also outlines a couple of projects that need doing in Revise. At the outset I should say that given other duties I’m unsure how quickly these will get done by me, so help would be welcomed.

Can you safely Revise.track random files?

Answer: no and yes, and the new Revise is both more dangerous and offers more paths towards fixing it.

Revise is intended mostly to track methods in “package code.” Revise used to do this without eval’ing any code except when methods changed. However that left two gaping holes: @evaled methods (i.e., methods defined by code, e.g., for T in (Float32, Float64) @eval f(::$T) = 1 end) and keyword function “body methods”. In practice those omissions were the main reasons Revise, prior to version 2, couldn’t always live up to its promises. Those have both been fixed (at least in principle) with Revise 2.0. It works by stepping through the lowered code and doing the same preparatory work used to build signatures to define methods. The key functionality is in Revise/src/lowered.jl and the LoweredCodeUtils package.

The consequence, of course, is that Revise steps through the top-level expressions in anything you ask it to track. If those contain things you’d really not re-evaluate, you’ve got problems.

There may be a good solution, and I even got partway towards implementing it before running out of time: introduce “lowered backedges” so you can (1) scan for Expr(:method, ...) expressions in the AST (see https://docs.julialang.org/en/latest/devdocs/ast/#Lowered-form-1) and then (2) determine which statements need to be stepped through to define those methods. That would allow Revise to skip over any code not needed to define new methods, and hence make Revise safer than it has ever been for tracking random files. I just pushed a branch that contains what, at least at one point, was working backedges code; it needs integration into the rest of Revise.

Revise is slower, especially on first revision

I confess this bothers me a lot—I view it as the biggest negative of Revise 2.0. The fundamental problem is that Revise now does a lot more analysis of your code, thanks to JuliaInterpreter and the packages built on top of it. All that additional code needs to be compiled before it’s used.

One could solve this with PackageCompiler. I’ve also done some benchmarks and found that inference, rather than LLVM, accounts for most of the time. Hence in principle this can be mitigated by better precompilation. I’ve started poking at the problem, see https://github.com/JuliaLang/julia/pull/31466.