This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-05-28
Channels
- # beginners (67)
- # boot (31)
- # cider (1)
- # cljs-dev (12)
- # cljsjs (1)
- # cljsrn (23)
- # clojure (86)
- # clojure-russia (2)
- # clojure-spec (6)
- # clojure-uk (12)
- # clojurescript (171)
- # core-async (2)
- # core-matrix (1)
- # cursive (3)
- # events (1)
- # lumo (6)
- # off-topic (118)
- # om (51)
- # onyx (16)
- # perun (3)
- # re-frame (14)
- # reagent (19)
- # uncomplicate (5)
- # unrepl (6)
- # untangled (6)
does anyone know whether figwheel compiles macros (on the first build, not autobuilds)? i would think so, but i'm getting that "wrong number of args" error that would point to no...
@sophiago the ClojureScript compiler loads your macros
i was pointing to the issue here about how they're compiled in a separate stage and that's why in self-hosted cljs it exposes form and env args: http://blog.fikesfarm.com/posts/2015-09-07-messing-with-macros-at-the-repl.html
@anmonteiro i guess you're saying i'd experience that behavior regardless of using figwheel's local server?
@sophiago hrm you need to clarify what you’re trying to do
macros in ClojureScript need to be written in Clojure and required with :require-macros
I’m guessing you’re not doing that and running into weird errors
yes, exactly. but i assumed that was only an issue of running the files locally and that the figwheel server would compile the macros, which must be incorrect
anyway, wouldn't it make sense to use cljc these days instead of :require-macros
or would that not do it?
you can write the macros in a .cljc
file. that is orthogonal to what I’m describing
because the compiler effectively runs in Clojure (on the JVM), your macros are expanded during analysis
that’s why they need to be written in Clojure
the macros would be written in the :clj
branch, so yes
there’s absolutely no difference to the CLJS compiler if your macros are in a foo.cljc
or foo.clj
file
ah ok. i understand what you're saying now: they're still compiled to clj so i need to require them for the cljs compiler
@anmonteiro sorry, one more thing. isn't it possible to use refer-macros
or :include-macros true
on the same namespace? the github wiki shows how to do this for required namespaces, but not for the current one
yeah you can self-require
(ns foo.core
(:require-macros [foo.core :refer [macro-you-wanna-refer]]))
there’s no :refer :all
in ClojureScript
figwheel is telling me Could not locate Foo/core__init.class or Foo/core.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.
@sophiago can you make a minimal repro I can look at?
should be fairly easy
something with just the requires should be enough
lol, well i created a whole figwheel project file with just the requires and an empty macro and still get the error
can you put it on GitHub or in a gist?
so is that a .cljc
file?
your macro needs to be defined in Clojure…
you need to create a core.clj
file where you define your macro
now i'm trying to call them from the aliased clj namespace and getting clojure.lang.PersistentList cannot be cast to clojure.lang.IFn
. does that make any sense?
@tiensonqin I hit the error:
[exp] goog.require could not find: figwheel.connect
after a recent upgrade, so thought I'd pass on the solution. (I think we need to get a handle on exp/clojuresript upgrades somehow - they are not easy to do.) Anyway, if you hit this error, you need to change figwheel-bridge.js
like so:
https://github.com/WintonCentre/unspun/commit/a030d5596e9c046ae3329b3bf543aa0392a44e17#diff-a8aaf4a8ec45fa1d7054daff091c9365L228
@tiensonqin See also, https://github.com/drapanjanas/re-natal/issues/80 and the similar fix in re-natal at https://github.com/drapanjanas/re-natal/commit/999615e921555e0d42728e14a6f91d80eed63cc4#diff-a27f34062e9e57b68e6346717e0db9e5L223
Can anyone give me some tips on debugging macros in cljs? A common technique is to put (println) statements everywhere, which obviously doesn't work when evaluating macros (not to the js console, anyway).
sometimes what works is macroexpanding (probably in a clj repl), and then debugging the expanded code, finally converting back to fixed macro
A little tricky because it is generating cljs code which can't be evaluated in a clj repl but should give me some more visibility at least.
macroexpand doesn't care if the code it shows you is valid
you can copy paste to cljs
@danielstockton Connect to the NREPL before you start figwheel (manually).
qqq: Well, you can go down the road of adding self-hosting via cljs.js
. There is some info at https://clojurescript.org/guides/self-hosting, but of course this is a pretty deep topic
in cljs, what is the most efficient way of going from "a string representing a PNG" to "a core.matrix reprensetatino of the same iamge" ?
is http://thi.ng/ndarray still maintined? why is it pulling in clojure 1.7
@danielstockton At a regular ClojureScript REPL, if your macro is defined in code on disk, you can use macroexpand
, and if it doesn’t look right, change the code, and then (require-macros 'foo.core :reload)
and expand again and/or try evaluating a form.
If your macro is fairly self-contained (relies only on ClojureScript), you can fire up Lumo or Planck or any other self-hosted ClojureScript environment, and try different variations on the macro right in the REPL by abusing the $macros
pseudo-namespace as described in http://blog.fikesfarm.com/posts/2015-09-07-messing-with-macros-at-the-repl.html
What is a good straightforward lein template for a ClojureScript utility project? (That is, ClojureScript code that will be used only as a dependency of other projects)
@mfikes Thanks, I'll give that a look.
@deg I’d normally just do lein new mylib
and simply add ClojureScript as a dep in project.clj
and go from there. You’d probably want to also set up for unit testing your lib using some other community developed thing (like doo
, or even Tach
, if you are also targeting self-host)
The main idea is that a ClojureScript lib is really just JAR dep with some ClojureScript source in it
Thanks! Meanwhile, the simplest one I found on Clojars was mies, which looks pretty close to that.
The curse of the vibrant ecosystem is that there are so many templates available, most of which are ancient or irrelevant.
@deg see scope: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
@deg Let's say you want to make a ClojureScript library. For maximum usability, you want to make your library code only depend on some very old version of ClojureScript. So, in your project.clj
you might have [org.clojure/clojurescript "1.7.28" :scope "provided"]
. But, you don't want downstream clients of your library to accidentally have that old version transitively pulled in and placed on their classpath. Instead, you want the client to be able to specify any newer version of ClojureScript. The "provided"
bit communicates that the consuming environment will provide that dependency. Ideally, the Maven system would choose the latest on its own, but the dependency resolution rules are not that straightforward. So, by using "provided"
you work around that particular issue.
Is there a way to have query params in cljs-ajax automatically url-encoded?
@danielstockton one thing that no one mentioned is the println
technique you said you can't use
Turns out you actually can, but the output will be directed to your terminal instead
The trick is wrapping your println
statements in binding [*out* *err*]
It works at the clj repl but I think I need to play with my setup to see that when compiling the cljs. I'm running figwheel and it doesn't print to the cljs repl.
#?(:clj ~(binding [*out* *err*]
(println "test")))
It shouldn't print into the CLJS REPL
That'll print when the analyzer expands the forms
Yeah, I didn't think it should. Just trying to work out where I can get it to print, except for evaluating it in the clj repl. If I evaluate it in the clj repl, I can see the expanded form anyway.
trying to use the latest org.clojure/clojurescript "1.9.542"
and [org.clojure/clojure "1.9.0-alpha17"]
but getting error when compiling via figwheel
Failed to compile "resources/public/compiled/cards.js" in 5.656 seconds.
---- Could not Analyze resources/public/compiled/cards/cljs/pprint.cljs ----
Invalid :refer, macro cljs.pprint/deftype does not exist
is this familar to anyone, any tips? thankshm.. this is not the latest, tried with cljs 1.9.562
but getting this same compilation error 😕
just trying to start with empty project and latest deps.. lein project with cljsbuild :main to a cljs.user file
(ns cljs.user
(:require
[om.next :as om]))
(enable-console-print!)
and trying (start-figwheel [:build :dev :cards])
from the replI removed :cljsbuild :compiler :preloads [devtools.preload]
and got it to compile with lein cljsbuild
but still fails via figwheel with Invalid :refer, macro cljs.pprint/deftype does not exist
I notice that with lein cljsbuild I get some warnings:
Compiling "resources/public/compiled/cards.js" from ["src/clj/client" "dev/cards"]...
WARNING: Use of undeclared Var cljs.pprint/pprint at line 15 resources/public/compiled/cards/devcards/util/utils.cljs
WARNING: Use of undeclared Var cljs.pprint/with-pprint-dispatch at line 23 resources/public/compiled/cards/devcards/util/utils.cljs
WARNING: Use of undeclared Var cljs.pprint/code-dispatch at line 23 resources/public/compiled/cards/devcards/util/utils.cljs
WARNING: Wrong number of args (1) passed to UUID at line 564 resources/public/compiled/cards/cljs/reader.cljs
WARNING: Use of undeclared Var clojure.string/starts-with? at line 822 resources/public/compiled/cards/cljs/analyzer.cljc
WARNING: Use of undeclared Var clojure.string/ends-with? at line 972 resources/public/compiled/cards/cljs/analyzer.cljc
WARNING: Use of undeclared Var clojure.string/starts-with? at line 2643 resources/public/compiled/cards/cljs/analyzer.cljc
perpahs some mixed clj/cljs versions? will probably consider downgrading from these latest versions for now
no, but i do use a let
statement outside of the quasiquoted part (a hack to evaluate gensyms)
well, yes given the let
. but that's never been an issue when in the same clj namespace
(defmacro square-limit [image n]
(let [img (image)]
`(do
(corner-split (flip-horiz (below-top (beside-left ~img))) ~n)
(corner-split (below-top (beside-right ~img)) ~n)
(corner-split (flip-vert (flip-horiz (below-bottom (beside-left ~img)))) ~n)
(corner-split (flip-vert (below-bottom (beside-right ~img))) ~n))))
oy, now i'm wondering if i need to qualify all those functional calls or if the expansion just occurs in the other ns and it's fine once required?
Maybe that (image) is the problem, you could move the backtick one level up and gensym the img.
sorry, i forgot earlier. usually i use that hack for gensym. in this case i'm just passing a function in userland
Yes (image) is just in the reader, isnt treated as function. So it isnt called. Youd need eval bit it doesnt exist in cls
but i don't see how that could be the problem when it expands fine when i don't need to require it to a cljs ns
unless it's not being expanded because the function calls are in the cljs namespace, which i haven't required to the clj one...etc. etc.?
No, shouldnt matter. You can require .clj macros and use then in .cljs, ive only encounter problem with that using lumo, but then id need to clean the cash. Maybe recompiling would be needed in your case. So you should be able to rule that out.
@hlolli i mean when your macros call functions from the cljs ns...whether you need to require that ns to your clj one and then qualify the function calls?
@mfikes where are you going with this? it does seem to match the error message exactly...
Try adding the backtick to front of let and give img# a hashtag at the end, i think it will work.
welp, my hypothesis about the function calls obviously made no sense since you cannot require a cljs ns into a cljs one!
@hlolli to be clear, you're saying (let [img# (image)] ...)` will cause the call to image to be evaluated?
Yes, then the macro returns an expression that knows what to do with (image) otherwise its just in a reader, so that you could for example apply functions to the argumwnts of (image) before evaluation.
that hack with let
works when it's in the same ns, but when requiring a macro from another you don't want anything actually evaluated at expansion
so in this case, i actually do need runtime evaluation for that call to make any sense. hence why it's being interpreted as a list
so it might make more sense for you to forego the let
entirely and replace your ~img
with (~image)
well, the let
still makes sense for efficiency, it just needs to be inside the quasiquote
anyway, now i'm running into a problem where all the functions i'm calling in that macro are undeclared. i assume i need to unquote them?
symbols inside a syntax-quoted form are automatically prefixed with the namespace in which you're expanding the macro
but if that's the issue i'm not sure how to resolve it considering you can't import a cljs ns into a clj one
i thought the answer before was that since nothing is being evaluated in the clj ns i'm fine
it's telling me all the function calls in the macro (which are from the cljs ns) are undeclared. i'm confused since that's the ns the macro is actually being evaluated in
@mfikes actually your way is the way i should have been doing it...not sure why appending gensym to the local var was suggested
@sophiago Is square-limit
defined in a Clojure namespace with a name matching the one where the ClojureScript function corner-split
is defined?
Syntax quote will end up qualifying the corner-split
symbol with the namespace where the macro is defined.
See foo.core/add*
here: http://blog.fikesfarm.com/posts/2016-01-05-clojurescript-macros-calling-functions.html
but the local var img is still giving me trouble. i suppose i need to qualify that with the cljs ns as well?
do you mean expand it without args? in that case i get "no such var." expanding it as i'm calling it just qualifies the function i'm passing
Just wondering if the result of macroexpand
on the form results in valid ClojureScript.
oh no, that just gave me back exactly how i called it except qualifying the function passed
Whatever that passed back will be evaluated as ClojureScript. Perhaps that's not what you want.