Yes, and it appears to be the best solution if we want to have compile-time macro support, because the alternative would be a very slow AST-traversal interpreter.
Speed is of course never an issue, except when it is. ^^
A lightweight but hackish alternative would be to special-case modules in the translation process. This could be done by checking, whenever you have an sexpr of the form "((<name1> <name2>) ...)", whether <name1> is globally bound to a module and <name2> to a macro within the module.
A more general way to do this would be, when you have an sexpr of the form "((...) ...)", before doing anything else, to macroexpand the sexpr in functional position. Then you could write modules as macros, expanding to the evaluation of their arguments in that module (the macro equivalent of what mine do via 'defcall now).
I think, but am not sure (so feel free to prove me wrong), that the real dichotomy is not between CL packages and AST interpretation, but between supporting first-class macros or the equivalent, and making the module system part of the language itself (hacking ac.scm) rather than creating it within the language.
A CL-like package system, for example, breaks the symbol-string isomorphism: what symbol a string becomes now depends upon what module you're in, which means you can't just mimic namespaces by 'uniq'ing all the symbols in a module that aren't imported from some other module: 'read, 'sym, etc. need to be changed so that they know from what module they're being invoked. Again, I'm not sure of this, but I think the abstraction will inevitably leak unless you change the translator itself to support your module system.
> A more general way to do this would be, when you have an sexpr of the form "((...) ...)", before doing anything else, to macroexpand the sexpr in functional position. Then you could write modules as macros, expanding to the evaluation of their arguments in that module (the macro equivalent of what mine do via 'defcall now).
Done. The above links to the result of "git diff" after the changes. While I think it works (it loads arc.arc fine), I don't want to actually push it to anarki in case I've made a mistake and there's some existing code it breaks. With it, and my module system, you can do the following:
In "test.arc":
(prn "test.arc evaluated")
(mac mquote (x) `',x)
At the arc repl:
Use (quit) to quit, (tl) to return here after an interrupt.
arc> (load "lib/module/python.arc")
nil
arc> (use test)
test.arc evaluated
#3(tagged module #<namespace>)
arc> (mac test* (x) (test x))
#3(tagged mac #<procedure>)
arc> (test*.mquote foo)
foo
If this gets pushed to anarki, it would be trivial to rewrite lib/module/python.arc so the "(mac test* ...)" line is unnecessary.
Hmm. Looks good, although I'm dubious about the second diff block (problem is that I don't have access to an Arc right now, so I can't quite see where that modification is)
As an aside - could we possibly do this without depending on mzscheme namespaces? It should be possible to have the macro instead be something of the form:
(mac module-name (x)
(case x
member gs42 ; where gs42 is a (uniq)-ed symbol
member2 gs43
(err:string "module does not contain member - " x)))