This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-30
Channels
- # aws (4)
- # beginners (143)
- # boot (37)
- # cider (31)
- # cljs-dev (53)
- # clojure (303)
- # clojure-conj (5)
- # clojure-dev (106)
- # clojure-dusseldorf (2)
- # clojure-greece (3)
- # clojure-italy (23)
- # clojure-spec (83)
- # clojure-uk (7)
- # clojurescript (328)
- # core-async (25)
- # cursive (2)
- # datascript (2)
- # datomic (3)
- # emacs (10)
- # hoplon (1)
- # jobs (2)
- # lein-figwheel (1)
- # leiningen (13)
- # luminus (6)
- # off-topic (38)
- # onyx (2)
- # parinfer (13)
- # pedestal (2)
- # portkey (5)
- # re-frame (11)
- # reagent (2)
- # shadow-cljs (61)
- # specter (6)
- # unrepl (60)
- # vim (4)
@dnolen @mfikes Is the new :aot-cache
supposed to speed up builds for a single project, or only for another project that uses the same compiler/options?
@rads and I didn’t see much difference when using the cache on a single project.
I have a cljs vector of url strings, and I'd like to pass it into cache.addAll(), which takes a js array. Apparently clj->js isn't working. How else would I do this?
nevermind, I think I found it. transforming to a seq first seems to work.
So turning on :aot-cache
is a kind of “pray it works if my deps don’t use macros which rely on the environment at build time” feature?
any idea how i’d verify that shared-aot working?
afaik it caches the stuff that’s happening in “output-dir” for each jar, so that your output-dir only has your project’s files; ie the stuff that happens before advanced compilation’s reduction process
@robert-stuttaford I guess it should populate ~/.cljs
or something? After I compiled it remained empty
guess it’s time to read the source 🙂
@robert-stuttaford https://github.com/clojure/clojurescript/blob/b2d9e6bcd7913663c35f67cdb9d348b372970794/src/main/clojure/cljs/analyzer.cljc#L3845
On my system it remained empty, so I guess something is not working Scratch that. ls -la ~/.cljs/.aot_cache
is populated.
Hmm, cold compilation in boot didn’t get faster though the second time. Still 1 minute for :none
.
all i know is that the issue is with macros that read the environment. not specifically aware of any libs that do that
it’s pretty much not usable for existing development until those libraries change to goog-define
hey David! should shared-aot work with this? https://github.com/robert-stuttaford/bridge/blob/master/Makefile#L18 only dep is rum
ahh i’ll try clearing it all first and then compare
that’s what I meant. First time compiling with aot-cache on will take longer than the second time.
rm -rf ~/.cljs/.aot_cache
time make compile
clojure -m cljs.main -co "{:source-map \"resources/js/app.js.map\"}" -d resources/js/out -t browser -O advanced -o resources/js/app.js -c bridge.main
make compile 84.16s user 2.49s system 298% cpu 29.012 total
time make compile
clojure -m cljs.main -co "{:source-map \"resources/js/app.js.map\"}" -d resources/js/out -t browser -O advanced -o resources/js/app.js -c bridge.main
make compile 84.46s user 2.67s system 317% cpu 27.429 total
@robert-stuttaford advanced is always a wash
ahh 🙂 ok, then yes, basically on hold until figwheel catches up
good to know, thanks
👍 i’m stoked!
👍 i’m with you. particularly valuable for devs who work on several projects, or when switching around between branches - i.e. all of us, heh
in my dev init function:
(set! s/*explain-out* expound/printer)
(s/check-asserts true)
(stest/instrument)
makes life a lot easier when you’re refactoring stuff 🙂https://github.com/robert-stuttaford/bridge/blob/master/test/bridge/test/util.clj#L8-L27 sets your tests up such that they have what they need without messing with those values, @borkdude, for use with (use-fixtures :once test-setup)
makes for easier tdd in general
I know, controversial, but we write browser tests for now (with etaoin, recommended!)
oh, heh, i have what you said in dev/user.clj
as well. forgot this is #clojurescript -grin-
can anyone provide some tips for debugging the Undefined nameToPath for [node module]
error? i'm using cljs 1.10.238 with :npm-deps {:interactjs "1.3.3"} :install-deps true
in my build config.
@joshkh the most obvious thing I can think of is checking whether node_modules is populated?
@joshkh that usually means there’s something about that library that prevents it from working
since you're here and very much the right person to ask, i was wondering about about this scenario: i have a cljs project that makes use of npm-deps, and the project itself a dependency of a larger cljs project. compiling the parent project doesn't/can't trigger any process that installs npm deps for those found in its dependencies.
the only work around i found was to copy the npm-deps key to the parent project (which is fine in my case). but that seems like a "gotcha" for someone else that might not be aware that one of their dependencies has an npm dependency.
Nice docs about this: https://clojurescript.org/reference/packaging-foreign-deps
Fast question, what is the cljs equivalent of Array.find(predicate) ?
some maybe ?
Yes, I would use some
But the docs are a bit confusing to me, seems that it returns whatever the predicate returns
Is that correct ?
@rdanielo, I usually see (some #(when (even? %) %) [1 2 3])
or if the predicate is membership (some #{2} [1 2 3])
I like some
if it’s set membership and prefer filter
+ first
in other cases … just my preference
Well, filter + first seems like the correct approach. However I'm worried about performance, I don't want to filter the entire collection just to pick the first element
Filter is lazy so calling first with filter will run through the collection until you get to the an element that has not been filtered
for example (take 2 (filter even? (range)))
=> (0 2)
Even in runtime ?
Regarding macros, is there any difference between:
(some-> stuff
:data
first
:stacks
req/get)
And
(some-> stuff
(:data)
(first)
(:stacks)
(req/get))
??@rdanielo why not macro-expand both forms and compare? 🙂
@dnolen Obviously (stupid question from my side), hahaha, is just that I can't imagine how that could be a reality at JS runtime
@robert-stuttaford because I am absolute noob and I didn't know about macro expand
feel the learn, @rdanielo - welcome!
So this is equivalent too (-> x a b c)
(-> x (a) (b) (c))
Can I use this the same way as a function pipe or it is slightly different ?
This seems to be wrong:
(defn Get [url]
(let [c (chan)]
(req/get url
#(>! c (js/JSON.parse (.-body %2))))))
It requires a go block. My question is, should I just use >!!
or a go block, and if I use a go block, whre should I put the go statement? Inside the lambda? outside ?I think in your example, you may want to have the function return the c
and wrap the req/get
form in a go block. Then execute Get
in another go block of another function, and within that other go block you can then pull the value out of the c
that is returned.
and print it or pass it to another function, while in that go block. Unfortunately, as with js promises, once you enter the go context, you have to continue pushing things through more go contexts
How to use outside it's clear
At the end I put the go block inside the lambda
Well, sounds exactly the same trap as promises or monads
I end up with this
(defn Get [url]
(let [c (chan)]
(req/get url
#(go (>! c (js/JSON.parse (.-body %2)))))
c))
Well, I'm used to promises, so they are cool to my eye :grinning_face_with_one_large_and_one_small_eye:
hmm, maybe you don't need a go block for the put? I can't remember. I don't use core.async that often, but you're on the right track.
And according to the stack trace I need the go block for the put too
Is this a correct usage of the #js
macro ?
(#js { "auth":
#js { "user": usr,
"pass": pass,
"sendImmediately": false}})
(it is inside a function which should return that
but you are correct that #js
is only one level deep, and you have to nest them to handle nested maps. clj->js
will do it recursively
What is the cheaper way to create a js object ? This seems to work:
(defn makeAuth [usr pass]
#js { :auth
#js { :user usr
:pass pass
:sendImmediately false}})
#js {...}
and js-obj
are more less equivalent, js-obj
is a bit fancier in that keys can be expressions I believe
In my case, I will
yeah, I'm usually working with nested things, so I'll grab for cljs->js
most of the time anyway
So I will use native JS methods to fetch basic data types (strings, and that stuff) and then #js macro for small payloads I will send
Transit ?
@rdanielo in your case, you will need to be worried about the performance of the conversion?
I am worried about js->clj
, because I'm talking to an API which is, what was the name
That APIs that sends you all available actions and all available relative links...
@dnolen any link to that transit ?
Rancher
Yeah, that's a tough judgment call. I want all my things to be persistent data structures. I want to Clojurify all the things. But if all I'm really doing is going to be pushing JSON out the other end anyway, passing through js values and operating on them raw can be more performant.
I'm using a native js request library, but it returns the body as string, so I can convert it to whatever JSON format I want
So I would prefer to convert to a native cljs format if possible
nothing is going to be faster than JSON.parse(...
but again, if this isn't a performance bottleneck, perhaps your data belongs in clojure-land. If your app basically consumes and produces JSON, or it needs to be super performant...
So it is transit a cljs tool ? Something like the binary format that google uses ?
we’re talking about too many things here because we’re trying to understand what you’re trying to accomplish
even if you can’t find a ClojureScript thing - you still shouldn’t use whatever JS thing you used before
@dnolen I agree with you on all points. however I didn not found any good http library for clojurescript targeting node, that's why I'm using a js one. Also all the examples I saw about this topic (cljs on node +http apis) uses a JS library, no one uses a cljs library
ah yeah, nodes a bit of a different beast. I take it the goog..xhr stuff doesn't work over there?
No, node does not have xhr
It has other better alternatives, IMO
@dnolen me too. There is one, but it is 4 years old
Why does bootstraped cljs tools can't use core.async ? If they all compile down to JS ?
a community thing could definitely follow the patterns in
. I'd probably prefer to consume that.
@rdanielo mfikes ported core.async over. https://github.com/mfikes/andare
I'm not sure what the specific reasons were, but it's usually because some macro stuff from a clj lib needs some mangling over on the cljs side, when a particular lib doesn't port over cleanly (or interop stuff)
@john, I know. I am just curious
Dam, error messages are horrible. What is this supposed to mean ?
Exception in thread "Thread-37" java.lang.IllegalArgumentException: No matching method found: printStackTrace for class java.net.SocketException
There is no info about what caused the errorAt the end I figured the error by executing the resulting javascript and taking a look at the js stack trace wich was a bit nicer
The problem was trying to execute a function partially applied which was not a function, but a partially applied string 🤪
(def (partial arg1 arg2)) instead of (def (partial fun arg1 arg2))
That Java socket exception is unreasonably unhelpful though. I think the repl side may have been able to do a better job here.
How would one refer to an external (possibly non-Google-closure compatible) Module? I am trying to create a new React class using `(require ’[react]) (def myComponent (reify React.Component (render [] (fn ...)))) but I get a NullPointerException for the reify form (I assume React.Component can’t be found) I know React.createClass is deprecated, and that there is a react-create-class patch for npm, but I just have a vanilla clojurescript app. Thanks for any comment...
easiest way to use js libraries is via cljsjs https://cljsjs.github.io/. You can find React there with instructions how to call it.
@U06BUCH6D If cljsjs doesn’t have anything for you, you can read through https://gist.github.com/jmlsf/f41b46c43a31224f46a41b361356f04d for more on the subject. In that post it references one possible way to use webpack for the foreign (non-goog-closure module) bundling and then how to include it (with lein and cljsbuild). That particular part of the story is https://github.com/pesterhazy/presumably/blob/master/posts/double-bundle.md
If you are using Reagent (or re-frame
) then https://github.com/reagent-project/reagent/blob/master/docs/InteropWithReact.md may also shed some insight
Thank you @U0LK1552A and @U662GKS3F - I will look into the doulbe-bundle solution. My ultimate intent is to understand how to get to the “metal” of js interop when forced to extend a non-cljsjs, non-goog-closure compliant, 3rd party lib class without having to be a JS ninja. For example, when trying to sell clojurescript in the enterprise, or to a JS crowd.
@U06BUCH6D work has been going on in cljs itself to have stronger support for NPM based deps. The goal here is to just be able to include them and have them “just work” I believe. However, there are still a lot of tricks there. It isn’t advanced enough to deal with how many NPM modules are structure or something like that.
Thanks @U0LK1552A. I am surprised that this seemingly basic scenario of declaring a subclass (in JS) of a loaded external JS lib - either via npm module or vanilla JS, could be so arduous…It would be a good idea IMO to have the clojurescript main docs document that stuff, if it is not already (I couldn’t find it in the guides)…thanks.
Yeah, it is a hassle still. The JS ecosystem of packaging and modules is pretty confusing as it is
It looks like cljs has a goal to get it to become a smoother process, but it is a long road it looks like
It probably isn’t thoroughly doc’ed in cljs main docs yet, just because it isn’t part of the core compiler to do something like “double bundle”
There is also shadow-cljs
you can look at. It is a “build tool” that I believe has a goal of smoothing the JS ecosystem integration
@U0LK1552A Thanks! Will study shadow-cljs carefully, and your explanations…meanwhile I found a cljsjs solution which works for my small use-case, but only after clicking around tediously: cljsjs/create-react-class works, bbbbBBUT…doesn’t show how the “drop-in” replacement is invoked: it turns out the syntax is NOT js/React.createClass
, or js/createClass
, but actually one has to type js/createReactClass ..
Unless one is familiar with cljsjs clj->camel case conversion patterns, that not intuitive.
I think once understood shadow-cljs should make it possible to cover all use cases for sure.
I haven’t tried messing with cljsjs/create-react-class
, so I wouldn’t have much to add on that without looking at it more.
Yeah, I havent’ used shadow-cljs
as of yet. I think the “double bundle” approach is fine for me currently. I think it depends on your circumstances what is most appropriate really.
Is it safe to assume that React is not google closure compliant? It seems to be the case.
It isn’t written as google closure modules at least. However the cljs NPM integration apparently works on React.
React seems to work with closure compiler based on https://github.com/facebook/react/issues/7551.
Hello. One question regarding channels, if a function that just makes a get request and returns a channel, it is a good idea to close the channel immediately after the response arrives ?
Yes, exactly. When you make a get request and you get a response you usually don't want to take anything else from there
Is this a correct map ?
(map :name collection)
I'm getting nil all over the place. I also tried mapv because I'm not sure if it is a list or a vector. It is a converted array. In any case the result is the same, a list of nils
What are you trying to achieve there? Are you trying to map :name
across the collection of maps, pulling out the value of the :name
key for each one?
Exactly
But seems that js->clj is cheating on me
Looks like it is converting an array of objects into an array of vectors...
How can I check the type of something ?
It is not very helpful
#object[Function]
does not mean anythign to me
Actually what I'm doing is js->clj
, now I'm getting a better answer
cljs.core/PersistentHashMap
Show I'm getting a vector of hashMaps
So I sholud be able to map over it right ?
The way I posted
It is a vector of hashMaps
ah, do they have :name
keys? try mapping keys
across to see what all the keys of each map are
Here is my pipeline: (convert is js->clj with keyworize)
(->> response
.-data
convert
(map keys)
println))
Indeed it contains name keyword:
((:description :group :system :rancherCompose :name :baseType :transitioningMessage :type :created :state :transitioningProgress :actions :dockerCompose :createdTS :binding :externalId :previousEnvironment :id :kind :outputs :transitioning :answers :environment :uuid :serviceIds :templates :previousExternalId :healthState :startOnCreate :accountId :removed :links)...
Can it be a problem in how I am constructing the pipeline ?
Does every map have a :name
? If so, and you're still getting nils, you first need to determine whether those vals are in fact nil, and the function is working correctly
I tried to include a lambda, but the behavior was weird too
I think the problem is how I'm using the pipeline
It is now working :face_with_rolling_eyes:
(->> response
.-data
convert
(map :name)
println))
Seems exactly the same..
Well, now to the next challenge
To find the first that matches certain criteria...
Done! cool
I was using some before
But someone suggested me (first (filter....
At first it was the obvious choice to me
But then I realized that the predicate must return the value or you will get just a boolean
And that is not very idiomatic to me, a predicate should just return true or false
Well, the choice of some
is independent of whether you choose to have your function return a boolean or a logically truthy thing, right? You'd just need to define a function to pass its argument through, if some condition about it is true, right?
Yes, exactly
hi. does anyone know a good boilerplate code/starter for Electron and clojurescript integration?
I think shadow-cljs has one on their main page
Can somebody tell me why I have to make a take at the end of this function ? Knowing that Get returns a channel... Why I can't just allow that to passthrough ? This works:
(defn getStacks [baseUrl envName]
(let [url (str baseUrl "/v2-beta", "/projects?name=" envName)]
(go (some-> (<! (Get url))
.-data
jFirst
.-links
.-stacks
Get
(<!)))))
But this does not
(defn getStacks [baseUrl envName]
(let [url (str baseUrl "/v2-beta", "/projects?name=" envName)]
(go (some-> (<! (Get url))
.-data
jFirst
.-links
.-stacks
Get))))
@rdanielo go returns a channel that then returns a channel. so without the take your consumer would need to take twice
Thanks. I found this one, but it does not seem to work, i am not even getting the first page, just a menu https://github.com/YurySolovyov/eion
@thheller you are right. So the go block always returns a channel, right ?
Would it be the same to make (<! Get)
right ?
But where is that take being injected ? Looks like magic to me
go
always returns a channel that will only ever receive one value. which is the final result of the go
Ok, more clear now
Thanks @thheller
other languages will have to sort out where to put it or throw it away - but for Clojure(Script) it’s pretty cool
At on point in the past, I was using Fressian for clj to clj serialization and I implemented a bunch of handlers and included metadata in that impl
Because it was desirable to have it over the wire. I was really just distributing data to more processes to do work on it. Made sense in that case.
Cool! I don't need any metadata right now, but it is good to know
has anybody ever tried or given thought to doing DCE in clojurescript itself? i realize there’s a better solution with closure, but I was just curious if there was anything about it
This would be pretty difficult thing to do. You can have some javascript code compiled along with your clojurescript code. That thing would have to understand both cljs and js to be usable in such scenarios 🙂
yea i’m sure it’d be very difficult. i was kind of just musing about something along the lines of a first pass. like something that bails when it’s in trouble but might do really well because it understands clojurescript better than clojure understands the compiler output. probably a stupid idea. as i say, just curiosity
i just came across the clojure typed project and it made me think that the idea of doing static analysis on clojurescript seemed plausible and interesting given that the code is basically already handed to you as an AST
@lee.justin.m ferret does some simple treeshaking and other optimizations, doesn’t look like awful lot of code when you operate on clojure-like-ast: https://ferret-lang.org/#outline-container-sec-3
IMO interesting (more serious) area of exploration would be to take clojurescript compiler and instead of javascript emit untyped ocaml Parsetree and then apply their pipeline with BuckleScript, see here: https://github.com/facebook/reason/blob/master/src/README.md#repo-walkthrough
but optimizations wouldn’t be the main benefit IMO, I believe this way we could eventually get something like “optionally typed clojure”, plus compilation to native (via ocamlc)
Yeah that's super cool