Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

1) I don't understand what this example is supposed to demonstrate.

2) By "power" I meant a formal notion of expressiveness: Neither feature expressions nor feature macros add anything to the language that you can't already express with existing constructs. Like I said: It's about affordances, not capability.



The example demonstrates how you can define a macro that runs its code in Clojure but can emit code to both Clojure and ClojureScript. How would you do this with feature expressions?


  #+clj
  (defmacro my-macro []
    (cond
      (contains? *features* :clj)  `(some-clojure-thing)
      (contains? *features* :cljs) `(some-cljs-thing)))
If that was too verbose for you, you could of course write a `feature-case` function that looks almost identical to what you have in that example.


This was a great example, and I think you are absolutely right that it is the identical in function, if not in form, to mine.

Interestingly, in the course of concocting a counter-counter example, I came up with this in an effort to show the two dynamic variables we stipulate - host and target - were absolutely required:

    #+clj
    (defmacro my-macro []
      (cond
        (contains? *features* :clj)  `(some-clojure-thing)
        (contains? *features* :cljs) `~(do (require 'some-ns)
                                           ((resolve 'some-ns/some-fn)))))
My hope was to make the point that 'some-ns/some-fn would run in a context where (features :cljs) is true - as it is in the caller's (macro body) environment - which would result in the system attempting to run ClojureScript code, which would explode because the macro is Clojure. Then I realized that require runs load, and load is in the macro body. The load/require available in the environment is Clojure-specific! Thus, load/require can bind disj :cljs and conj :clj before reading and compiling some-ns.

My counter-example failed, but did bring me a little closer to the truth - that we only need one dynamic variable, platform. Any platform that has the ability to load code also has an opportunity to bind platform and thereby inform macros of target. This simplifies the Feature Macro proposal by half and we are excited to amend it.

Our updated cross-platform example becomes:

    (case-platform
      :cljs nil
      :clj (defmacro my-macro []
          (condp = *platform*
            :clj  `(some-clojure-thing)
             :cljs `(some-cljs-thing))))
Instead of host and target, we are down to just platform. We continue to see no need for a features set because of Clojure's platform-symbiosis.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: