# Using the new "Contextual Module REPL" to clear the workspace

**URL:** <https://discourse.julialang.org/t/using-the-new-contextual-module-repl-to-clear-the-workspace/98799>\
**Category:** New to Julia\
**Tags:** repl\
**Created:** [May 13, 2023, 5:07pm UTC](https://discourse.julialang.org/t/using-the-new-contextual-module-repl-to-clear-the-workspace/98799 "2023-05-13T17:07:00Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [May 13, 2023, 5:07pm UTC](https://discourse.julialang.org/t/using-the-new-contextual-module-repl-to-clear-the-workspace/98799/1 "2023-05-13T17:07:00Z")

</div>

I was very interested to see the [Contextual module REPL](https://julialang.org/blog/2023/04/julia-1.9-highlights/#contextual_module_repl) in the [Julia 1.9 Highlights](https://julialang.org/blog/2023/04/julia-1.9-highlights/#contextual_module_repl).

People in the past have asked about how to clear the REPL workspace, e.g.,

> [@Clearing workspace](https://discourse.julialang.org/t/clearing-workspace/29465):
>
> Im currently on v1.1.1 using iJulia/Jupyter - i cant find a working method for garbage collection - workspace() and gc() aren’t recognized in REPL or iJulia. Any suggestions?

> [@Clear workspace à la Pluto](https://discourse.julialang.org/t/clear-workspace-a-la-pluto/74484):
>
> A feature that I miss in Julia is the ability to clear my workspace. It is nice to be able to make sure that there is no global ghost-variable somewhere in your code, leading to it breaking if you restart your session. I frequently end up making such variables when prototyping code. Pluto has shown me that it is possible. In Pluto, once you remove definitions, the variable/function is no longer defined. This is all without recompiling everything. If I am not mistaken, Pluto does this by definin…

> [@How to clear workspace variables？](https://discourse.julialang.org/t/how-to-clear-workspace-variables/44095):
>
> I’ve installed it revise.jl How can I use this bag? How can I clear the previous working variables after modifying the program to see the new variable values

It seems like the contextual module REPL goes a long way to enable this. I’d be inclined to put the following function in my `startup.jl`:

```julia
function temprepl()
    name = gensym("REPL")
    @eval module $name; import REPL; deactivate() = REPL.activate() end
    @eval REPL.activate($name)
end

```

That way, `temprepl()` activates a temporary workspace which can be “deleted” (caveat below) by running `deactivate()`. A use case for this would be including some test file or to do some prototyping in the REPL without having to worry about polluting the workspace.

This still requires some forethought, as there’s no way to get an actual new `Main` this way. Also, I don’t think the temporary workspace module would be garbage collected (it remains as a submodule of Main, as far as I understand).

Is this `temprepl` a good idea, or an abuse of what the contextual module REPL is intended for? Any ideas for improvement? There’s probably no way to actually delete (garbage-collect) the temporary module after it is deactivated, right?

---

<div class="post-metadata">

**Author:** ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)\
**Post date:** [May 14, 2023, 11:48am UTC](https://discourse.julialang.org/t/using-the-new-contextual-module-repl-to-clear-the-workspace/98799/2 "2023-05-14T11:48:49Z")

</div>

> Is this `temprepl` a good idea, or an abuse of what the contextual module REPL is intended for?

FWIW, when I was using a branch with this feature some time ago, I did something very similar, and I wouldn’t say this is abuse, if it’s useful to you!

For example, here is what I have as part of my startup script:

```julia
const LAST_MODULE = Ref(Main)
const MAINS = Module[]
const ASSIGNED_MODULES = fill(Main, 9)

function activate_module(s::LineEdit.MIState, mod::Union{Nothing, Module}=nothing)
    last_module = Base.active_module()
    if mod === nothing
        # parse module name in REPL input
        LineEdit.activate_module(s)
    else
        REPL.activate(mod)
        LineEdit.refresh_line(s)
    end
    if last_module != Base.active_module()
        LAST_MODULE[] = last_module
        true
    else
        false
    end
end

function new_Main(mod::Symbol)
    newmod = @eval Base. __toplevel__ module $mod
    # whatever you like to have in your REPL
    using BenchmarkTools
    # ...
    end
    newmod
end

function get_Main(nn)
    modname = Symbol("Main", nn)
    for ii = length(MAINS)+1:nn
        push!(MAINS, new_Main(Symbol("Main", ii)))
    end
    MAINS[nn]
end

activate_Main(s, ii) = activate_module(s, get_Main(ii))
activate_new_Main(s) = activate_module(s, get_Main(length(MAINS)+1))

assign_module(s, ii) = ASSIGNED_MODULES[ii] = Base.active_module()
activate_module(s, ii::Int) = activate_module(s, ASSIGNED_MODULES[ii])

```

And then in my REPL shortcuts:

```julia
    "\emn" => (s, o...) -> activate_new_Main(s),
    "\emm" => (s, o...) -> activate_module(s),
    "\em\em" => (s, o...) -> activate_module(s, LAST_MODULE[]),
    "\em0" => (s, o...) -> activate_module(s, Main),
    "\em1" => (s, o...) -> activate_Main(s, 1),
    "\em2" => (s, o...) -> activate_Main(s, 2),
    "\em3" => (s, o...) -> activate_Main(s, 3),
    "\em4" => (s, o...) -> activate_Main(s, 4),
    "\em\e1" => (s, o...) -> activate_module(s, 1),
    "\em\e2" => (s, o...) -> activate_module(s, 2),
    "\em\e3" => (s, o...) -> activate_module(s, 3),
    "\em\e4" => (s, o...) -> activate_module(s, 4),
    "\ems1" => (s, o...) -> assign_module(s, 1),
    "\ems2" => (s, o...) -> assign_module(s, 2),
    "\ems3" => (s, o...) -> assign_module(s, 3),
    "\ems4" => (s, o...) -> assign_module(s, 4),

```

> There’s probably no way to actually delete (garbage-collect) the temporary module after it is deactivated, right?

Right, but you could go over its bindings and try assigning `nothing` to them.
