[ANN] SafeREPL: use BigInt by default at the REPL

This is some nice work @rfourquet. It’s good to see people think seriously about ways to easily provide arbitrary precision arithmetic (or other reinterpretations of literals) in a way that causes minimal friction.


Not to be defensive, but I’m a little confused about this statement:

I’m not sure what exactly you’re referring to. Could you clarify what the problem is with typing 1 in this mode? Here’s what I see:

julia> using ReplMaker

julia> function Big_parse(str)
           Meta.parse(replace(str, r"[\+\-]?\d+(?:\.\d+)?(?:[ef][\+\-]?\d+)?" => x -> "big\"$x\""))
       end
Big_parse (generic function with 1 method)

julia> initrepl(Big_parse, 
                prompt_text="BigJulia> ",
                prompt_color = :red, 
                start_key='>', 
                mode_name="Big-Mode")
REPL mode Big-Mode initialized. Press > to enter and backspace to exit.

julia> >

BigJulia> 1
1

BigJulia> typeof(1)
BigInt

If I am to give you honest feedback here, I think SwapLiterals.jl is a cool and useful pacakge and if it’s used for something like SafeREPL.jl, that should be in an isolated REPL mode (not necessarily one provided by ReplMaker.jl, but I think a dependancy on ReplMaker would make your life easier :man_shrugging:). The way you’re hot-modifying the existing, standard julia repl mode to make it evaluate code in a non-standard way makes me very uncomfortable.

To my mind, repl modes are basically a nice way to automatically apply a macro (sometimes a string macro) to code automatically. They change the meaning of code. It should always be obvious that such a thing is happening such as with a custom prompt and it should be easy to get back to standard julia when needed. This is why julia requires that macro invocations begin with the @ sigil, otherwise it would never be clear when you’re looking at code that will be evaluated normally.

I understand that you show how to add stuff to your startup.jl to make it more clear what’s going on and be able to toggle this behaviour on or off, but I think it’s a serious flaw to make those things opt-in rather than opt-out and I don’t like that they can only be done before the repl has been started up.

That’s more to do with SwapLiterals.jl though, right? Presumably something using actual repl modes could have the same relation to SwapLiterals.jl as SafeREPL.jl does, correct?

I think that having a non-standard REPL that evaluates code differently is very likely to cause other, unforeseen problems for new users that they may not be equipped to deal with if they’re unable to use repl modes. I do not look forward to trying to help someone in #helpdesk debug their code only to learn 20 minutes into the conversation that they had something like SafeREPL enabled but forgot.

Composability is an interesting problem. Thinking of repl-modes as string macros, you basically can never have the sort of composability where two separate string macros get to operate on the string, but if your transformation only needs to operate on the AST level, rather than the string level, it would actually be pretty easy to do that in replmaker. You basically just do

initrepl(transformation2 ∘ transformation1; kwargs...)

I could even make a method where initrepl takes in a Vector of transformations and applies them sequentially and allow people to push! or modify that vector whenever with the only caveat that the first transformation needs to take in a string, and the subsequent trasnformations need to be able to handle whatever output the previous transformation gives. Could be a String or an Expr I suppose.

2 Likes