Converting between interactive and non-interactive soft scope code

Never was a fan of some local scopes being made “soft”, meaning reassigning global variables without declarations in interactive contexts (REPL, notebooks) instead of making a local variable; for example, for _ in 1 s=0 end and @eval for _ in 1 s=0 end don’t do the same thing there. So for consistency when copy-pasting between interactive and non-interactive contexts (.jl files, eval, include_string), on top of writing global declarations as required in the latter, I also write local declarations in soft scopes not nested in any hard scopes to avoid silently reassigning global variables (which could be sneakily introduced by an include) in the former.

Not everyone goes that far though, so I’ve seen a few situations where copy-pasting caused issues. Weirdly I’ve only seen someone complain about silent reassignment of sneaky globals once ever, so I presume that is a rare coincidence and wouldn’t always cause bugs. The more common issue is copy-pasting code from notebooks or the REPL (REPLHistory.jl makes this easier) to .jl files that throw UndefVarErrors. This crops up every once in a while for newcomers who started to learn to code in interactive contexts and hadn’t gotten around to fully grasping the (imo complicated) scoping rules, and notebooks converted to .jl files without adjustment sometimes show up in Github repos.

Is there a way to add the unambiguous global/local declarations to soft scopes if we provide whether it is an interactive or noninteractive context, whether as a text edit or a macro?

2 Likes