I was just talking about the potential problems of FX last night - very interesting to see such an impressive and simple alternative approach. I'm not sure what the drawbacks are, but looking forward to seeing the discussion that grows from this.
Many of the most useful applications of feature expressions simply will not work as macros. You'd need to create one new feature-cond enabled macro for each other macro use case. Feature expressions, on the other hand, are a general solution that can be used at the call site without having to reinvent every macro that may ever need platform-conditional behavior, like your ns+ macro.<p>Consider the proposed +clj form in the body of an extend-protocol or a deftype:<p><pre><code> (defmacro +clj
"Form is evaluated only in the JVM."
[form]
(when (= :clj *host*) form))
(deftype Foo
SomeCommonProtocol
(aMethod [blah blah] ...)
(+clj
JvmOnlyInterface
(someMethod [blah] ...)
)
)
</code></pre>
Of course, this <i>does not work</i>. The deftype macro gets the +clj form unmodified and must handle it on its own.<p>At best, you could have a syntax-quote style wrapper form:<p><pre><code> (feature-quote
(deftype Foo
SomeCommonProtocol
(aMethod [blah blah] ...)
(+clj
JvmOnlyInterface
(someMethod [blah] ...)
)
))
</code></pre>
However, this is essentially what Feature Expressions are anyway. Only broken, since macros don't only operate on syntax/edn, they can operate on any compile-phase value, like dates and times or the output of any tagged literal handler. Without being part of the phase before the macro expander, you can't prevent platform specific types from reaching the macro body.<p>The reality is that Clojure, in the tradition of most lisps, has rigid read/compile/run phase separation where each phase has a varied evaluation strategy, but the phases run interleaved. Unlike say something like Mathematica, which does not run the reader interleaved with the evaluator - and the evaluator uses normal-order rather than applicative-order! Without such a uniform evaluation strategy (nevermind Mathematica's evaluator's other problems) it simply doesn't make sense to fight so hard against beefing up the read phase.<p>Related: I've written before about how I don't think that this impacts tooling as badly as you guys thing it does. I just don't understand why you guys are so against feature expressions, nor do I think you've succeeded in proposing a desirable alternative.
It seems to me that Feature Macros will be trivially implementable as a library once Feature Expressions land:<p><pre><code> #+clj (def *host* :clj)
#+cljs (def *host* :cljs)</code></pre>
I am looking at one of the examples:<p><a href="https://github.com/feature-macros/clojurescript/blob/feature-macros/feature-macros-demo/src/demo/util.clj" rel="nofollow">https://github.com/feature-macros/clojurescript/blob/feature...</a><p>But if I run Clojure on the JVM, the following fails:<p><pre><code> (def host nil)
(defn foo [] (when (= :cljs host)
(gstring/format "something")))
</code></pre>
... the error being that there is no "gstring" namespace.<p>Since the proposed solution with macros would produce such code (I am right?), how does it solve the issue of namespaces that only exist in a specific platform?
tldr:<p><pre><code> git clone git://github.com/feature-expressions/clojurescript
cd clojurescript/feature-macros-demo
make deps
make demo</code></pre>