Fork me on GitHub
#clojurescript
<
2019-06-23
>
dpsutton00:06:21

@mfikes annotated a forward declaration with the functions signature in bean. (declare ^{:arglists '([x])} bean?). What’s the purpose of this?

dpsutton00:06:06

Oh interesting. New to me. Thanks

chepprey02:06:35

I'm rendering hiccup, need to show a String of what I guess you'd call "untrusted data" and I want to "safe escape" it. What's the common method(s) for html-escaping?

chepprey02:06:24

... this is in a Reagent context. After some searching it perhaps sounds like Reagent escapes things by default. hmm...

chepprey02:06:57

yyyyyep. Sorry for the interruption. Brain too used to the non-Clojure ways of making html, assumed burden of escaping was on me.

Pavel Klavík16:06:28

Hi, I am trying to use Bidi + Accountant for client-side routing and after clicking on links, the address changes in the navigation bar correctly. When I use history buttons, the address changes, but nothing changes in the app. The setup I have:

(accountant/configure-navigation!
    {:nav-handler       #(rf/dispatch [:app-state/changed-route %])
     :path-exists?      #(b/match-route routes/routes %)
     :reload-same-path? true})

oskarkv19:06:30

I'm curious, why is macroexpand a macro in ClojureScript?

mfikes20:06:57

@oskarkv Perhaps one (unsatisfactory) answer is that it cannot be a function.

oskarkv20:06:10

Yes, quite unsatisfactory

mfikes20:06:51

If it were a function, it would exist at runtime (in the JavaScript target environment, where the Clojure compiler doesn't exist—at least not in JVM-based ClojureScript.)

mfikes20:06:28

@oskarkv Here is a post making use of self-hosted ClojureScript to write a version of macroexpand that is indeed a function. It might help in thinking about the JVM ClojureScript case: https://blog.fikesfarm.com/posts/2015-09-05-runtime-macroexpand.html

mfikes20:06:56

Re-reading that article, I failed to point out that, even though this lets you have a function version of macroexpand in your code... it causes the entire compiler to be brought with your code into your target environment. 😜

oskarkv21:06:25

Hm I read that "ClojureScript namespaces can require macros from the selfsame namespace, so long as they are kept in different compilation stages. So, for example a foo.cljs or foo.cljc file can make use of a foo.cljc or foo.clj file for its macros." here https://clojurescript.org/about/differences#_macros But when I tried to make a macro in a cljc file, and :require-macros it from a cljs file the macro didn't work. What did I do wrong?

oskarkv21:06:32

And about that "so long as they are kept in different compilation stages", well how do I know?

lilactown21:06:24

"the macro didn't work" isn't nearly enough info to know why it didn't work and what might need to change

lilactown21:06:36

What happened when you tried to use the macro?

oskarkv21:06:15

Sorry, I restared my Emacs and don't quite remember what I did, but I might have made a mistake. Never mind for now.

oskarkv21:06:48

OK, so it seems that if I have macros in some-ns.cljc they work, unless I also have a some-ns.clj file, then the macros in cljc act as functions.

(ns game.core
  (:require
   [game.bla :as b :include-macros true]))

game.core> (b/trice (println 1))
1
1
1
nil
game.core> (b/twice (println 1))
1
(do nil nil)

oskarkv21:06:57

Here, trice is defined in the clj file, but twice in the cljc file

oskarkv22:06:47

And, it means that if I have some code that only works in Clojure, and I therefore create a .clj file, then macros that could work in both if I had reader conditionals now do not, since they have to be defined in the .clj file instead of .cljc.

lilactown22:06:23

hmm. I’m surprised by that behavior

lilactown22:06:56

I thought that if you have some-ns.cljc and some-ns.clj, that the .clj file will be picked over the .cljc one

lilactown22:06:11

by the :include-macros / :require-macros

lilactown22:06:50

it might be the other way around. but either way I’m surprised that it would load both at all

lilactown22:06:08

so if trice is in one, and twice is in the other, I would expect only one to exist

lilactown22:06:32

I’m assuming that game.core is a .cljs file

lilactown22:06:09

re: reader conditionals, you probably don’t need reader conditionals for macros

lilactown22:06:21

you might be surprised by the behavior of a macro using reader conditionals

lilactown22:06:48

since most ClojureScript projects use the JVM CLJS compiler, all ClojureScript macros take the :clj path in a reader conditional

lilactown22:06:21

since the macro is executed in the context of the JVM ClojureScript compiler

lilactown22:06:15

if you need a macro that needs different implementations depending on the target (e.g. if it’s used in a CLJS file vs. a CLJ file) then you’ll need to use something other than reader conditionals within the macro

thheller22:06:51

my 2 cents are: don't ever use .cljc files if you can avoid it. macros are confusing enough as it is, writing them in .cljc is exponentially harder to get right 😛

oskarkv22:06:42

@lilactown Oh, good to know about the :clj reader conditional

oskarkv22:06:12

@thheller Hm, except for this gotcha with having both clj and cljc files, what's so hard? 😛

thheller22:06:36

might just be me 😛

thheller22:06:48

isolating macro-only code properly etc

mfikes23:06:31

The rule with .cljc / .cljs / .clj files is that a platform-specific file will be loaded in preference to a .cljc file. Applied to ClojureScript, this means that .cljs will be loaded in preference to .cljc for runtime namespaces and that .clj will be loaded in preference to .cljc for macros namespaces.

oskarkv23:06:15

Hm, I don't like that rule, because as soon as I have something that only works in Clojure, for example, and create a .clj file I have to move all my macros. 😛

oskarkv23:06:40

Unless I want to have a bunch of reader conditionals in a .cljc

oskarkv23:06:53

Oh, and if I want my library to work for both clj and cljs, I have to choose either clj + cljs or cljc, I can't mix. 😛

Crispin03:06:06

You can mix them all together in one project, just not in the same namespace.