I work with multiple grammars in the repl. The grammars use same names for some of their rules.
One of the documentation recipes mentions full qualification, to disambiguate type annotations in function pattern matching (it's in a note of the load
function, but not in the code of this page - the .jar has it correct). But that might become tedious, so maybe there is aliasing for imports (like in Python import regex as r
)?! And using full qualification in the first argument of the parse
function doesn't seem to help to disambiguate all parse rules that are invoked recursively, parse(#lang::java::\syntax::Java18::CompilationUnit, src)
. At least it produces weird errors if I also import lang::java::\syntax::Java15.
In general, what is a safe way to handle symbols from different modules with same names?
Alternatively, is there a way to "unload" a module in the repl?
Some background information:
data
, syntax
definitions and overloaded functions can be extended by importing another module; In this way you can extend a language and its processing functions by importing another module and adding rules and function alternatives at leisure.import
ing and extend
ing a module. In particular import
is not transitive and fuses only the uses of a name inside the importing module, while extend
is transitive and also fuses recursive uses of a name in the module that is extended. So for extending a language, you'd default to using extend
, while for using a library of functions you'd use import
.fusing
behavior from import
completely in one of the releases of 2020. After this all conflictingly imported non-terminal names must be disambiguated by prefixing with the module name, and prefixing will not have a side-effect of fusing recursively used non-terminals from different modules anymore. Not so for extend
, which will still fuse the non-terminal and functions all the way.So to answer your questions:
import
that is.Unimporting a module:
rascal>import IO;
ok
rascal>println("x");
x
ok
rascal>:un
undeclare unimport
rascal>:unimport IO
ok
rascal>println("x");
|prompt:///|(0,7,<1,0>,<1,7>): Undeclared variable: println
To work around these issues, a way is to write functions inside a different module for every separate language/language version, and create a top module which imports these if you want to bundle the functionality in a single interface. This way, because import
is not transitive, the namespaces stay separate and clean. Of course this does not solve the REPL issue; the only thing I can offer there is to start a fresh REPL for each language version you are playing with.