What is the problem with making packages be hashtables? Then you could use foo!bar to get function bar of package foo. Like this:
(use foo)
(foo!bar 1 2 3)
With renaming:
(use foo as f)
(f!bar 1 2 3)
I don't think Python-like importing into the global namespace is a good idea for a system where you are supposed to be able to change things in the REPL. Once you copy a module's function to your environment you aren't able to reload the module to change the function. This also means you need a module registry, so you don't load two copies of the same module.
There is no problem with that, in fact I like it... ;) But as almkglor says, this doesn't play nicely with macros...
So what you say is to simplify it to a function 'use' that creates a table of symbols? How do you solve the references within modules? I don't see that, but otherwise it's very good. I would even remove the 'as', and make it a simple optional parameter:
(use 'foo 'f)
(f!bar 1 2 3)
Or maybe what (use ...) can do is simply return the table:
Easy: redefine "def" from within a 'use form (possibly using kennytilton's faux special globals) such that it keeps a table of defined functions (which is what you intend to do anyway). Replace all locals with (uniq)'ed names (in case someone uses uses a function name as a local - (def foo () nil) (def bar (foo) (foo))) ). Then for each expression in the file, replace all symbols (outside of quote-forms) that match a key in the table to references to the table itself.
The hard part is the replacing of local variables with (uniq)'ed symbols. But I think local variables should be replaced anyway, because otherwise macros will override local variables with the same name.
Yes, I thought of that after I wrote the comment. Avoiding repetitions like this is exactly what macros are for. I guess I'm not used to thinking in lisp yet.
pau wants 'use to be a function, though, so there would have to be a separate macro, or the other way around, or something.