tools.namespace

Read/analyze ClojureScript and conditional read sources

Details

  • Type: Enhancement Enhancement
  • Status: Resolved Resolved
  • Priority: Major Major
  • Resolution: Completed
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None

Description

Clojure 1.7 and ClojureScript 3308 introduced support for the Conditional Reader.

tools.namespace started out as a Clojure-only library. Support for the conditional reader was added in TNS-34, but it was hard-coded for Clojure (.clj and .cljc) files only.

Some high-level features of tools.namespace, such as code reloading via c.t.n.repl/refresh, are coupled to the Clojure(JVM) implementation, and could not easily be ported to ClojureScript. I regard that as a non-issue for now, since other tools (e.g. Figwheel) exist to do reloading in ClojureScript.

However, other features of tools.namespace, such as namespace dependency analysis, do not depend specifically on Clojure(JVM). It might be useful to apply those tools on ClojureScript source files.

The deeper problem is the multi-layered structure of tools.namespace. The Clojure/ClojureScript distinction only really matters in the "lower" layers such as c.t.n.file and c.t.n.parse, but the layered structure makes it awkward to pass options through from the "higher" layers such as c.t.n.dir and c.t.n.find.

See also comments on TNS-29.

This ticket is a place to capture work and notes about this problem.

Activity

Hide
Stuart Sierra added a comment - - edited

Breakdown by namespace:

c.t.namespace is deprecated

c.t.n.dependency has no JVM-specific coupling, can be trivially ported to .cljc

c.t.n.track has no JVM-specific coupling, can be trivially ported to .cljc

c.t.n.parse has read-ns-decl calling clojure.core/read, which always uses default platform feature :clj. Can be modified to support reading .cljc files with the :cljs feature by replacing clojure.core/read with tools.reader.

c.t.n.file defines clojure-file? hard-coded to .clj and .cljc since TNS-34. Would be trivial to add clojurescript-file?.

c.t.n.dir calls c.t.n.file/clojure-file?

c.t.n.repl calls c.t.n.dir/scan

c.t.n.find calls c.t.n.file/clojure-file? and also uses hard-coded .clj and .cljc as file extensions to search within JAR files.

c.t.n.move is hard-coded to .clj files but is still "alpha" and not widely used

Show
Stuart Sierra added a comment - - edited Breakdown by namespace: c.t.namespace is deprecated c.t.n.dependency has no JVM-specific coupling, can be trivially ported to .cljc c.t.n.track has no JVM-specific coupling, can be trivially ported to .cljc c.t.n.parse has read-ns-decl calling clojure.core/read, which always uses default platform feature :clj. Can be modified to support reading .cljc files with the :cljs feature by replacing clojure.core/read with tools.reader. c.t.n.file defines clojure-file? hard-coded to .clj and .cljc since TNS-34. Would be trivial to add clojurescript-file?. c.t.n.dir calls c.t.n.file/clojure-file? c.t.n.repl calls c.t.n.dir/scan c.t.n.find calls c.t.n.file/clojure-file? and also uses hard-coded .clj and .cljc as file extensions to search within JAR files. c.t.n.move is hard-coded to .clj files but is still "alpha" and not widely used
Hide
Laurent Petit added a comment -

couldn't `read-ns-decl` call `clojure.core/read` with `:read-cond` and `:features` options set appropriately? Is it really necessary to add `tools.reader` as a dependency (I would avoid it if possible)?

Show
Laurent Petit added a comment - couldn't `read-ns-decl` call `clojure.core/read` with `:read-cond` and `:features` options set appropriately? Is it really necessary to add `tools.reader` as a dependency (I would avoid it if possible)?
Hide
Stuart Sierra added a comment -

The reason you can't just pass different options to clojure.core/read is because, on Clojure(JVM) read will always add the platform feature :clj. There is no way to call read and force it to omit the platform feature.

See the Reader Conditionals design page, "The platform feature (:clj) will always be present."

Show
Stuart Sierra added a comment - The reason you can't just pass different options to clojure.core/read is because, on Clojure(JVM) read will always add the platform feature :clj. There is no way to call read and force it to omit the platform feature. See the Reader Conditionals design page, "The platform feature (:clj) will always be present."
Hide
Laurent Petit added a comment -

Oh, I didn't know that. It's kind of a shame, no, since it is well known that ClojureScript is compiled via Clojure (JVM) ...

Show
Laurent Petit added a comment - Oh, I didn't know that. It's kind of a shame, no, since it is well known that ClojureScript is compiled via Clojure (JVM) ...
Hide
Stuart Sierra added a comment -

As far as I know, ClojureScript has used tools.reader instead of clojure.core/read for some time.

Show
Stuart Sierra added a comment - As far as I know, ClojureScript has used tools.reader instead of clojure.core/read for some time.
Hide
Stuart Sierra added a comment -

My current thinking is:

c.t.n.dependency and c.t.n.track are platform agnostic.

c.t.n.file and c.t.n.parse can be extended to support Clojure & ClojureScript by adding an optional argument read-opts passed through to tools.reader/read.

c.t.n.find can be extended with optional arguments to select a "platform," either Clojure or ClojureScript, which will encapsulate both valid file extensions and reader options.

Reload/refresh functionality will remain Clojure(JVM) only for now: c.t.n.dir, c.t.n.reload, and c.t.n.repl.

c.t.n.move is still alpha and does not even support .cljc files. It can be handled under separate tickets or deprecated.

Work-in-progress visible on branch TNS-35-cljs-experiments currently at commit e9327295

Show
Stuart Sierra added a comment - My current thinking is: c.t.n.dependency and c.t.n.track are platform agnostic. c.t.n.file and c.t.n.parse can be extended to support Clojure & ClojureScript by adding an optional argument read-opts passed through to tools.reader/read. c.t.n.find can be extended with optional arguments to select a "platform," either Clojure or ClojureScript, which will encapsulate both valid file extensions and reader options. Reload/refresh functionality will remain Clojure(JVM) only for now: c.t.n.dir, c.t.n.reload, and c.t.n.repl. c.t.n.move is still alpha and does not even support .cljc files. It can be handled under separate tickets or deprecated. Work-in-progress visible on branch TNS-35-cljs-experiments currently at commit e9327295
Hide
Stuart Sierra added a comment -

.cljc support for read/parse/dependencies in 0.3.0-alpha* release

Show
Stuart Sierra added a comment - .cljc support for read/parse/dependencies in 0.3.0-alpha* release

People

Vote (1)
Watch (3)

Dates

  • Created:
    Updated:
    Resolved: