Skip to content
adrusi edited this page Apr 23, 2011 · 4 revisions

It would be convenient to scope functions to a "namespace" easily, but this doesn't seem quite right yet. As of now, this proposal seems like it would not necessarily be clear to a reader whether you're referring to a variable inside of or outside of a namespace, even if the compiler were able to figure it out.

(defvar my-namespace exports)
(defun outside-namespace-fn () true)
(defvar outside-namespace-var 10)

(namespace my-namespace) ;; this now sets the namespace for all 

(defun inside-namespace-fn () true) ;; this is the same as (defun my-namespace.inside-namespace-fn () true)
(defvar inside-namespace-var 20) ;; in js: myNamespace.insideNamespaceVar = 20;

(inside-namespace) ;; We figure out that this was defined in the namespace
                   ;; and prefixes it accordingly at compile-time.
                   ;; Identical to (my-namespace.inside-namespace-fn)

(console.log inside-namespace-var) ;; We need to check all literals to see if they've
                                   ;; been defined in the current namespace.  This should compile to
                                   ;; console.log(myNamespace.insideNamespaceVar);

(outside-namespace-fn outside-namespace-var) ;; and here we need to figure out that both the function name
                                          ;; and argument name were *not* defined in the current namespace.

(namespace false) ;; return to the default namespace.  is (namespace default) better?

(namespace.inside-namespace-fn) ;; this is now the only way to get at the inside of the namespace

We could also support this:

(defvar my-namespace {})
(namespace my-namespace
  (defvar foo 10)
  (defun bar ()
    (console.log "this is my-namespace.foo:" foo)))

(my-namespace.bar)
(console.log my-namespace.foo)

Comment: It seems like this would have a similar problem as javascript's native with statement—it would become unclear which variable is being changed. You could replicate this using just a plain old function:

(defun using-ns (ns fn)
  (fn.apply ns))

and then you would just use

(using-ns console 
  (lambda ()
    (this.log "console.log")))

Since rather than changing the namespace completely, it just abbreviates it to this, there's no confusion about what is being changed.

Clone this wiki locally