On Wednesday, June 18, 2014 11:29:43 PM UTC-7, Nahuel Greco wrote: > Jason, thanks for the quick reply. I understand your point, but sometimes is > better to have an in-situ check without needing to return an if-cljs form, > like in: > > > > > (defmacro aaa [] > (let [xxx (if-cljs yyy zzz)] > ... do something complex with xxx)) > > (defmacro bbb [] > > > (aaa)) > > > So as you said the alternative options are: > > A- refactorize aaa to return `(if-cljs ...) forms... always possible? > > > B- add an explicit env parameter to aaa, but then all your macro libraries > intended to be used from CLJ&CLJS must follow this style. > > > C- use the old approach, but is incompatible with having 'cljs.analyzer > loaded for other reasons. > > I feel there is an unsatisfied need here, but maybe A is sufficient. Also, I > would like to know if there is a rationale behind &env being in a way (CLJS) > in the first macro level and in another way (CLJ) in the next ones, if is > intended or is an implementation limitation.
I'm in over my head a little bit here, but my guess is that preferring (A), and falling back to (B) if you can't/don't want to expand to if-cljs is probably not a huge burden. I think generally calling a custom macro from another macro (rather than expanding into it) is also pretty uncommon in my experience (excluding built-in clojure macros). I also think (C) is just a natural consequence of what macros are and how they are called -- a macro is just a function, so when calling a macro from another macro, the environment is naturally that of the first Clojure macro, not the outermost function. > > > > > > > Saludos, > Nahuel Greco. > > > > On Thu, Jun 19, 2014 at 2:59 AM, Jason Wolfe <[email protected]> wrote: > > > > > The problem with our old solution is that if you called a macro in cljx code, > and that fn was itself called from Clojure code involved in macroexpansion of > ClojureScript, it would get the cljs version and barf. > > > > > > I think our current solution mostly solves this, in that macros that want to > emit cross-platform code should emit forms like `(if-cljs cljs-form clj-form) > -- notice the backtick -- and even if they are called from other macros, the > ultimate expansion takes place in the correct target context (I hope). > > > > > > > If a macro wants to directly switch on the env (rather than emitting an > if-cljs form) the env must be passed in from the parent, but in general I > think it seems like a better approach. In any case, it seems to have solved > our immediate issues that some people were having with cljs compilation, > without breaking any tests. > > > > > > > In your specific example, there's no backtick before "if-cljs", which I > believe is causing the unexpected behavior (although I think your log fn > would have to be changed as well to emit a form, as is typical for macro > helper fns). But I haven't actually tested this, so if this is incorrect > please let us know. > > > > > > > > > > On Wed, Jun 18, 2014 at 10:30 PM, Nahuel Greco <[email protected]> wrote: > > > > > > > > I found a problem in the Chas approach. When you call a macro from a cljs > file, and that macro calls another macro with a(:ns &env) test, it sees a > Clojure &env, so it thinks is being compiled in a CLJ environment. This > doesn't happens with the Prismatic approach (the old one, it was recently > changed for the Chas one). See below: > > > > > > > > > ;;;----- p/macros.clj ------ > (ns p.macros) > > > (defn log [s] > > > > > > > (spit "/tmp/log" (str (pr-str s) "\n") :append true)) > > > (defmacro if-cljs ;; Chas approach > > > > > > > [then else] > (log [:if-cljs-env &env]) > (if (:ns &env) then else)) > > > > > > > > > > > (defn compiling-cljs? ;; Prismatic (old) approach > > > > > > > [] > (boolean > (when-let [n (find-ns 'cljs.analyzer)] > > > > > > > (when-let [v (ns-resolve n '*cljs-file*)] > @v)))) > > > > > > > > > (defmacro other-macro > [] > (log [:other-macro-env &env]) > > > > > > > (log [:if-cljs (if-cljs :cljs :clj)]) > (log [:if-compiling-cljs (if (compiling-cljs?) :cljs :clj)])) > > > > > > > > > > ;;;----- p/core.cljs ------ > > (ns p.macros > (:require-macros [p.macros])) > > > > > > > > > (p.macros/other-macro) > > When you run this, you get the following contents in the /tmp/log file: > > > > > > > > > [:if-cljs-env {&env #<LocalBinding > clojure.lang.Compiler$LocalBinding@18b3f8f5>, &form #<LocalBinding > clojure.lang.Compiler$LocalBinding@7a69c3fb>}] > > > > > > > [:other-macro-env {:column 1, :line 14, :ns {:defs .... }}] > [:if-cljs :clj] ;;; WRONG! > [:if-compiling-cljs :cljs] ;;; CORRECT > > > > > > > > Note, [:if-cljs-env ...] is printed before [:if-cljs ...] as the if-cljs > macro expands inside the other-macro definition before other-macro is > executed from cljs. > > > > > > > > My question is, why the &env in the if-cljs macro call here is not a > ClojureScript one? Bug or feature? :) > > > > > > > > > > > > Saludos, > Nahuel Greco. > > > > > > On Tue, Jun 17, 2014 at 11:01 PM, Jason Wolfe <[email protected]> wrote: > > > > > > > Not anymore (thanks Chas): > > > > https://github.com/Prismatic/schema/pull/113 > > > > > On Tuesday, June 3, 2014 7:21:35 AM UTC-7, Nahuel Greco wrote: > > > check what Prismatic schema uses: > > https://github.com/Prismatic/schema/blob/master/src/clj/schema/macros.clj#L13-20 > > > > > > > > > > > > > > > > > > > > > > > > Saludos, > > > Nahuel Greco. > > > > > > > > > > > > > On Tue, Jun 3, 2014 at 9:40 AM, Ambrose Bonnaire-Sergeant > > <[email protected]> wrote: > > > > > > > > > > > > > > > > > > I would write two different macros. > > > > > > > > > Thanks, > > > Ambrose > > > > > > > > > > > > > > > > > > > > > > On Tue, Jun 3, 2014 at 8:07 PM, Максим Карандашов <[email protected]> wrote: > > > > > > > > > > > > > > > > > > > > > I want to find (in the macro call) what happens: Clojure or ClojureScript > > compilation. It needed for using one name of macro inside Clojure and > > ClojureScript. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Currently I use next approach: > > > > > > > > > > > > (if (nil? cljs.env/*compiler*) > > > > > > (do-something-for-clojure) > > > > > > (do-something-for-clojurescript)) > > > > > > > > > > > > And it's working well. But maybe this is not correct? Or is there another > > way to do this? > > > > > > > > > > > > -- > > > > > > Note that posts from new members are moderated - please be patient with > > your first post. > > > > > > --- > > > > > > You received this message because you are subscribed to the Google Groups > > "ClojureScript" group. > > > > > > To unsubscribe from this group and stop receiving emails from it, send an > > email to [email protected]. > > > > > > To post to this group, send email to [email protected]. > > > > > > > Visit this group at http://groups.google.com/group/clojurescript. > > > > > > > > > > > > > > > > > > > > > > > > -- > > > > > > Note that posts from new members are moderated - please be patient with > > your first post. > > > > > > --- > > > > > > You received this message because you are subscribed to the Google Groups > > "ClojureScript" group. > > > > > > To unsubscribe from this group and stop receiving emails from it, send an > > email to [email protected]. > > > > > > To post to this group, send email to [email protected]. > > > > > > > > > > Visit this group at http://groups.google.com/group/clojurescript. > > > > -- > > Note that posts from new members are moderated - please be patient with your > first post. > > --- > > You received this message because you are subscribed to the Google Groups > "ClojureScript" group. > > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > > > > > To post to this group, send email to [email protected]. > > Visit this group at http://groups.google.com/group/clojurescript. > > > > > > > > > > > > -- > > Note that posts from new members are moderated - please be patient with your > first post. > > --- > > You received this message because you are subscribed to a topic in the Google > Groups "ClojureScript" group. > > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/clojurescript/iBY5HaQda4A/unsubscribe. > > To unsubscribe from this group and all its topics, send an email to > [email protected]. > > > To post to this group, send email to [email protected]. > > Visit this group at http://groups.google.com/group/clojurescript. > > > > > > > > > > -- > > Note that posts from new members are moderated - please be patient with your > first post. > > --- > > You received this message because you are subscribed to the Google Groups > "ClojureScript" group. > > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > > To post to this group, send email to [email protected]. > > Visit this group at http://groups.google.com/group/clojurescript. -- Note that posts from new members are moderated - please be patient with your first post. --- You received this message because you are subscribed to the Google Groups "ClojureScript" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/clojurescript.
