Executing on the root Task from the REPL

I would like to a explore a mechanism by which a user could execute a command from the REPL on the root task rather than the backend.

Motivation: JavaCall

Without JULIA_COPY_STACKS=yes it appears JavaCall will only function correctly if executed on the root Task (Base.roottask) even when using Java 11 or higher.
https://github.com/JuliaInterop/JavaCall.jl/issues/101
Trying to use JavaCall.init() without JULIA_COPY_STACKS=yes will currently cause a segmentation fault. I’ve discussed a potential PR with Avik to throw an error first rather than segfault.

Currently all the REPLs except the fallback mode send all commands to a backend on a different Task due to the use of @async:

This means that JavaCall cannot be used at all from the LineEdit REPL unless JULIA_COPY_STACKS=yes is set via an environmental variable. However, it could be used if the fallback REPL is forced by using something like $ cat | julia -i

Proposal

We create a mechanism by which the user can execute certain commands on the REPL frontend rather than the backend. Here are a few options to enable a user to execute on the root Task frontend rather than asychronously in the backend:

  1. Create a new REPL mode where all commands are executed on the root Task. This could be done from a package like JavaCall.
  2. Quote the expression using a macro in such a way that a conditional can redirect the AST to be executed on the frontend.
  3. Throw an exception that can be caught by the REPL which would then try to execute the command on the root Task
  4. Create a special Channel by which the REPL backend could send commands to the root Task frontend for execution.