ClojureScript

Stop using Clojure Namespaces entirely for non-macro names/lookups

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Completed
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • Patch:
    Code and Test

Description

AFAICT, the ClojureScript compiler uses clojure.lang.Namespace in only a couple of situations now:

1. during macroexpansion
2. when reading:

  • to bind *ns* to *cljs-ns*
  • to set aliases (and their referents) for resolving namespaced keywords/symbols

#1 is unavoidable and unproblematic. #2(b) can cause issues at dev-time though, especially when using portable libraries. For example:

(ns simple-check.generators
  (:require #+clj [clojure.core :as lang]
            #+cljs [cljs.core :as lang]
            [cemerick.pprng :as pprng]
            clojure.string)
  (:refer-clojure :exclude [int vector list hash-map map keyword
                            char boolean byte bytes sequence]))

The differing lang alias there will always cause an error for the second compiler that attempts to load the file.

A similar problem would also affect any multitenant ClojureScript compilation environment that didn't use classloaders to provide the compiler with its own static clojure.lang.Namespace environment.

A plan:

1. Enhance tools.reader to provide a dynamically rebindable *namespaces* var (hopefully to contain a map equivalent in structure to the one being used by the analyzer already?).
2. Change the analyzer to:

  • bind that var to the current value of namespaces when reading
  • modify the namespaces map as necessary to account for aliases, etc.

Does this sound sane?

Activity

Chas Emerick made changes -
Field Original Value New Value
Description AFAICT, the ClojureScript compiler uses {{clojure.lang.Namespace}} in only a couple of situations now:

1. during macroexpansion
2. when reading:
   * to bind {{\*ns\*}} to {{\*cljs-ns\*}}
   * to set aliases (and their referents) for resolving namespaced keywords/symbols

#1 is unavoidable and unproblematic. #2(b) can cause issues at dev-time though, especially when using portable libraries. For example:

https://github.com/cemerick/simple-check/blob/cljx/src/cljx/simple_check/generators.cljx

The differing {{lang}} alias there will always cause an error for the second compiler that attempts to load the file.

A similar problem would also affect any multitenant ClojureScript compilation environment that didn't use classloaders to provide the compiler with its own static {{clojure.lang.Namespace}} environment.

A plan:

1. Enhance tools.reader to provide a dynamically rebindable {{\*namespaces\*}} var (hopefully to contain a map equivalent in structure to the one being used by the analyzer already?).
2. Change the analyzer to:
  * bind that var to the current value of {{namespaces}} when reading
  * modify the {{namespaces}} map as necessary to account for aliases, etc.

Does this sound sane?
AFAICT, the ClojureScript compiler uses {{clojure.lang.Namespace}} in only a couple of situations now:

1. during macroexpansion
2. when reading:
   * to bind {{\*ns\*}} to {{\*cljs-ns\*}}
   * to set aliases (and their referents) for resolving namespaced keywords/symbols

#1 is unavoidable and unproblematic. #2(b) can cause issues at dev-time though, especially when using portable libraries. For example:

{code}
(ns simple-check.generators
  (:require #+clj [clojure.core :as lang]
            #+cljs [cljs.core :as lang]
            [cemerick.pprng :as pprng]
            clojure.string)
  (:refer-clojure :exclude [int vector list hash-map map keyword
                            char boolean byte bytes sequence]))
{code}

The differing {{lang}} alias there will always cause an error for the second compiler that attempts to load the file.

A similar problem would also affect any multitenant ClojureScript compilation environment that didn't use classloaders to provide the compiler with its own static {{clojure.lang.Namespace}} environment.

A plan:

1. Enhance tools.reader to provide a dynamically rebindable {{\*namespaces\*}} var (hopefully to contain a map equivalent in structure to the one being used by the analyzer already?).
2. Change the analyzer to:
  * bind that var to the current value of {{namespaces}} when reading
  * modify the {{namespaces}} map as necessary to account for aliases, etc.

Does this sound sane?
Chas Emerick made changes -
Attachment CLJS-632.diff [ 12380 ]
Chas Emerick made changes -
Patch Code [ 10001 ]
Chas Emerick made changes -
Patch Code [ 10001 ] Code and Test [ 10002 ]
Attachment CLJS-632.diff [ 12390 ]
Chas Emerick made changes -
Attachment CLJS-632.diff [ 12380 ]
David Nolen made changes -
Resolution Completed [ 1 ]
Status Open [ 1 ] Resolved [ 5 ]
David Nolen made changes -
Status Resolved [ 5 ] Closed [ 6 ]

People

Vote (0)
Watch (2)

Dates

  • Created:
    Updated:
    Resolved: