This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-11-08
Channels
- # aws (3)
- # bangalore-clj (1)
- # beginners (47)
- # boot (137)
- # cider (1)
- # cljs-dev (67)
- # cljsrn (7)
- # clojure (122)
- # clojure-argentina (5)
- # clojure-berlin (4)
- # clojure-czech (12)
- # clojure-france (27)
- # clojure-italy (9)
- # clojure-russia (88)
- # clojure-spec (44)
- # clojure-uk (157)
- # clojurebridge (2)
- # clojurescript (236)
- # datomic (5)
- # devcards (3)
- # dirac (23)
- # emacs (13)
- # hoplon (29)
- # incanter (1)
- # leiningen (41)
- # microservices (1)
- # off-topic (78)
- # om (145)
- # onyx (13)
- # parinfer (8)
- # pedestal (4)
- # planck (15)
- # protorepl (1)
- # re-frame (72)
- # reagent (25)
- # ring (2)
- # specter (23)
- # test-check (9)
- # untangled (106)
- # vim (8)
- # yada (1)
@johanatan here is a writeup on code splitting / deferred loading : https://rasterize.io/blog/cljs-dynamic-module-loading.html (haven’t done it myself)
@hueyp ahh, so this isn't automatic. any reason why the compiler can't just auto-modularize on CLJS module boundaries? @dnolen ?
@johanatan doing it around human module boundaries doesn’t actually generate optimal modules
Google Closure actually employs cross module code motion so the production “modules” represent the actual optimal code split
@dnolen: I'm confused. Are you saying that GC actually does automatically break things into production modules and that the article that @hueyp shared is only for if you want to or need to override that?
however this is just to tell GC what must belong to a specific “module”, but GC will create the true optimal split
Google believes their approach produces optimal splits and based on the amount of data they have about stuff like this - I’m inclined to believe them too
Hi All....so, I have this clojurescript+nodejs command line app that works awesome...now I want to give it to others like QA to consume...im struggling to find a good model to package this thing up because of two issues: 1) the nodejs target of course emits a tree of files instead of the single browser.js you get elsewhere, and 2) some of the npm deps I am using have native .o builds (GRPC, etc).
even something like "lein npm install -g" would be fine, but this doesnt seem to produce what I expect or can figure out how to invoke
to put it another way, I am not constrained to need platform/arch neutral packaging (though this would be a bonus) but rather the most idiomatic way to produce something straight forward for others to share/use
hello~ anyone know if there's an easy way to get a cljs repl in the terminal like clj on linux?
@akiroz I dont know if I would classify it as "easy" but there I have been successful with figwheel
I want something like a command I can run anytime instead of having to cd
to my sandbox project, run lein figwheel
and open a browser to test something simple
so, the repl runs in the terminal, and my app runs in the terminal, but I suspect that is not your use case
(at first, I thought you were saying your repl was running in the browser, but after looking at how I run it I kind of doubt thats what you meant)
That sounds like it could work actually!
I'll just write a (loop (print (eval (read))))
, compile it to a node js file and run node repl.js
and then, I run "lein figwheel repl" to launch the repl in one terminal, and node repl/repl.js in the second
For generating externs for google closure advanced compilation, I find an actually pretty old idea from https://gist.github.com/Chouser/5796967, make some changes to the gist, now it works for some react native apps of mine. https://github.com/tiensonqin/exponent-cljs-template/blob/master/resources/leiningen/new/exponent/env/dev/externs.clj
Please correct me if I’m wrong. If I’m calling a function in a normal javascript package that I don’t have externs for using the (.functionName js-object js-arg)
format, then it won’t survive advanced compilation, right? So the safe way to do it is to ((aget js-object “functionName”) js-arg)
?
@seantempesta Yeah, I think so.
((aget js-object “functionName”) js-arg)
is too tedious,
externs.clj
already helps this one,
currently it don’t support:
1. (.-member js-object)
2. (ui/Facebook.logInWithReadPermissionsAsync …args)
3. ui/Permissions.REMOTE_NOTIFICATIONS
I’m starting to learn the cljs analyzer, as long as the ast has all the informations we need, maybe we can solve this problem.
I’m not expert on cljs or google closure, so maybe I’m wrong.
@dnolen: How can GC know about temporal relations of functions? It would seem that part of being "optimal" here would involve putting functions likely to be called later into the deferred modules. And I wasn't asking for anything to change-- just trying to understand how it all works now and if I need to do anything (such as outlined in that article @hueyp posted) to get the benefits.
@jonathan you need to define the entries
of each module (ie. a ns
with a function in you will call when you load the module). You then need to define how the modules depend on each other. Given that information the GC will move things around.
Hey, would the community weigh in on their boot/lein preference and more importantly - some reasoned arguments as to why they favour what they do
Is there a reason the clojurescript compiler doesn’t automatically generate externs when it sees we are accessing javascript properties or calling javascript functions? Is there any other reason to use the (.-attr
or (.fn-name
operators?
Or at least convert those references to (aget js-obj “js-attr”)
and ((aget js-obj “js-fn”) js-args)
?
@seantempesta yes you would damage dead code elimination and other production build optimizations
@pseud an interesting question but this isn’t really the right channel for that discussion
@tiensonqin @seantempesta there’s a ClojureScript repo branch called externs-infer
which will attempt to do what you all are describing in a more disciplined way
@dnolen Thank you, will check it soon. I’m looking at https://github.com/mneise/clojurescript/commits/CLJS-1074.
@tiensonqin yes it looks likes Maria wrote some nice stuff we should use for knowing what things we already have externs for - should just copy that
my branch goes a bit further in propagating extern info for inference in local contexts
I’ll learn both repos, don’t know too much about cljs internals. Thank you for your help!
@seantempesta give cljs-oops a try
is there a way to have (type x) match against the protocol in clojurescript like you can have it in clojure with class?
#?(:clj (defmulti branch? class)) #?(:cljs (defmulti branch? type)) (defmethod branch? :default [_] false) #?(:clj (defmethod branch? clojure.lang.IPersistentVector [v] true)) #?(:clj (defmethod branch? clojure.lang.IPersistentMap [m] true)) #?(:clj (defmethod branch? clojure.lang.IPersistentList [l] true)) #?(:clj (defmethod branch? clojure.lang.ISeq [s] true)) #?(:cljs (defmethod branch? cljs.core/PersistentVector [v] true)) #?(:cljs (defmethod branch? cljs.core/PersistentArrayMap [m] true)) #?(:cljs (defmethod branch? cljs.core/List [l] true)) #?(:cljs (defmethod branch? cljs.core/IndexedSeq [s] true)) #?(:cljs (defmethod branch? cljs.core/LazySeq [s] true)) #?(:cljs (defmethod branch? cljs.core/Cons [s] true))
https://github.com/clojure/clojurescript/blob/78f6504e1c67c935c283a362ecf6cb5a3766022e/src/main/clojure/cljs/core.cljc#L2033
or alternatively implements?
if you want the check to be a bit faster:
https://github.com/clojure/clojurescript/blob/78f6504e1c67c935c283a362ecf6cb5a3766022e/src/main/clojure/cljs/core.cljc#L2007
@dnolen: Please excuse my ignorance of compilers in general, but couldn’t the compiler check to see if externs are available for the variable in question, and then decide whether to enable optimizations?
@darwin: cljs-oops looks perfect. Thanks for the tip!
@seantempesta I don’t understand what you are asking
I’m only stating how Google Closure Compiler works - we don’t have control over many of the optimization details
Ah, I see. Well thanks for clearing that up. Also thanks for everything you’ve done for clojurescript. It’s so nice to be able to write in a sane language. 🙂
what is the best way to detect that my macro is being expanded from clojure as opposed to clojurescript?
@thheller I think you misunderstood my question. ClojureScript is a dynamic language. This means that static analysis cannot in large part determine when various functions will be called. Since part of the allure of the module system is its ability to "defer" loading of chunks of code until the point when they are actually needed, this inability to determine temporality of such chunks is defeating to that effort.
@jonathan why is that important? you define the entry, if that entry is the only one to use cljs.core.something
that something will be moved into that module
@thheller I'm referring to the natural state where you leave GC to decide the module boundaries as @dnolen mentioned
@johanatan I think what can be said about how it works has been said
@dnolen once again, I'm not asking for anything to change. I am only asking what I am asking.
A) namespaces B) Google Closure modules which are a code splitting feature and has nothing to do with A)
other than when you want the code split, you specify which namespaces you want to for sure in a split
yes, so my question is regarding your statement: "https://clojurians.slack.com/archives/clojurescript/p1478569203014569"
@johanatan there’s nothing more to say about that
And my question is: https://clojurians.slack.com/archives/clojurescript/p1478585634014633
but you keep combining a bunch of things which are considered separately by Google Closure
@johanatan I wrote a very short post about it more than a year ago if you want an overview
Ok, so you're saying that if I define N splits and give it some namespaces that I want in each, GC will try to aim for that but will still migrate chunks of code as appropriate. But, if I say define zero splits, GC won't migrate anything anywhere and there will end up being just one .js with everything in it?
@wilkerlucio landed https://github.com/clojure/clojurescript/commit/80bbded9527dce6216f36763f23b7e5ebf8930df, give it a spin your project
@dnolen nice! thanks for the notice
My attempt at making dynamic scoping work in JS. https://gist.github.com/anonymous/d6476b301685c6cb0ce7b523496bf9c1
in a way similar to clj(s), tries to rebuild basic things on top of a few primitives. here given just the scope thing does function arg passing, local variable defs and self-like OO.
this should be a fairly easy question: ideal tools for benchmarking cljs vs. js? not sure if it's relevant if i'm using om and react respectively. thanks!
but not like i'd find something like criterium in this case for the many obvious reasons. i was hoping for something maybe inching towards that
I don’t know that trying to measure CLJS/JS React perf will be interesting without a bewildering array of tests
3 years ago I when I was testing CLJS+React I was satisfied with the generic conclusion “it’s not slow” 🙂
right, like as a library developer you'd see if you massively screwed something up. when i write code that does a lot on the gpu it's more useful for speed. but looking for "om is x magnitudes faster than my previous workflow" i doubt i'll get in any way at least i'd believe
but i have to think i'm getting a very significant speed up along those lines, especially with lifecycle managed for me, just too many factors for a profile to encompass them all
having watched people use Om for years now, it’s not my impression that people see performance benefits over plain React
but everyone just likes the simpler programming model + Figwheel makes everyone feel productive
well thank for the anecdotal evidence. that's worth a lot. i certainly didn't think it was slower. and om.next is a massive improvement in workflow for me coming from using the top-level api. i suppose it's just the react overhead adds so much the speed of cljs over js isn't doing much is the point?
otoh, if i make use of om.next's network routing interfacing it with the backend code that might change drastically. again, though, tough to measure
@sophiago fwiw, my impression of people that make the jump from React to ClojureScript is that they like the fact that the whole community is unified around simple React architecture
Webpack, Babel, gulp, grunt - it’s all become a plugin mess - not actually delivering on modularity
so I hear that as well - users like the fact ClojureScript just deliver JS module management to everyone in a unified way
yes, that was obvious in one day. my point in the last statement was about resetting between UUIDs, though. i'm not sure how far those performance gains in rendering go. it doesn't seem like outside of om there's much use of that...like a hidden feature almost
@sophiago: You might find this post interesting - not specific to CLJS at all, but it seems pretty relevant. http://elm-lang.org/blog/blazing-fast-html-round-two There are also some alternative VDOM implementations in CLJS if you want to follow the rabbit hole further - no idea if there are any comparisons of them against react or anything like that though
@shaun-mahood thanks! i'll give it a look
Oh, and the original post included Om, which came in quite a bit faster than React at that point.
2014 though, so a lot has changed since then on all fronts
yeah, it wouldn't even be the version of om i'm using at all so not sure i should be quoting any of it
re: webpack...the thing i wonder (having always avoided jsx) is if facebook doesn't want to help develop it what will they do if it falls apart?
last i remember it was mainly developed by one guy! they chose to make the main react workflow rely on a somewhat arbitrary tool developed by one guy their multibillion dollar company doesn't employ...
in comparison Google Closure Compiler for all of it’s lack of visibility is a healthy project with many devs delivering core functionality
yeah it’s tough, Google Closure Compiler has horrible documentation and marketing - but solid technology
I hope that ClojureScript can over time provide the best documentation / front end to it
huh, this is interesting: a skim view shows the new React tutorial looks really good feature wise, but they sidestepped their whole deprecated babel-browser issue by just using codepen and not mentioning how to build it at all in the entire thing. i guess you get quite far before realizing the entire tooling ecosystem you're signing up for...
@shaun-mahood that elm article has many points that seem awfully specious... one being how optimizing react requires "refactoring" it into smaller and smaller components, when that's just how react should be used from the start...or basic modular library design for that matter. the other being how they immediately wrote off optimizations based on immutable data structures because they're too hard for their developers or something then went into array allocation? i've never used elm and am not sure who actually wrote this thing, but it appears they missed the two main points behind all of frontend dev (both React and Angular2) in the time period they're discussing
i also don't know how i can believe those two year old figures claiming over a 50% speedup using om vs. react based solely on immutability based on David saying React's overhead massively trumps those considerations
@sophiago: It was written by Evan Czaplicki, the creator of Elm - based on everything I've read and seen that he's done, I would tend to give him the benefit of the doubt for most things.
and my main thing immediately was he clearly didn't seem to understand the React workflow
like his "unoptimized" version appeared to have what, like a few large components doing everything?
That’s not strictly true. Phonegap / Cordova allows throwing regular webapps on a phone with API’s for interfacing with phone-specific features like the camera. You can then, provided your environment allows JS interop, use whatever frontend technology that makes you happy.
well, it's not like i'm switching from what i've been doing for a while. the whole analysis just strikes me as having many odd points
Every solution is wanting, you’ll also find plenty of posts saying React native isn’t as great as it’s made out to be if you’re actually trying to target Android and iPhone both. Granted, React native might be less broken (I really don’t know), but Cordova/Phonegap draws its strength from how closely it resembles regular webapps and thus how easily skills transfer. Mocking a few things out and you can basically work & test on a PC should you want.
but I’ve also talked to plenty of people who didn’t think Cordova was the answer for “native” clients
Elm doesn’t run on the backend (Clojure does), we have a much more sophisticated production build story thanks to Closure etc.
i'm mainly left confused about the om vs. react numbers from two years ago, but perhaps i should take them with a grain of salt
@sophiago if you can write simple React apps that work purely via reference equality checks for shouldComponentUpdate
you can replicate the results
@dnolen the first link on "In Stillness, Movement" (Google Closure Modules) seems to be broken. Do you have a better link for it?
but my experience is that for non-trivial stuff, you won’t see such big gains - it’s also why om.next doesn’t work that way anymore
ah, ok. yeah, i didn't understand om to diff any less often than react. you're saying it can/used to for a small percentage of use cases
@sophiago yes, it doesn’t scale as the component tree deepens - you still have to check too much
@dnolen I think this is it if you want to fix the broken link: http://swannodette.github.io/2015/02/23/hello-google-closure-modules
@johanatan thanks, but not that important to me
this does explain the analysis then because he seems to be saying elm isn't so modular (no experience personally) compared to React or Angular2
well that would explain why they can get a slight speedbump in those current benchmarks
something which I think is still quite useful even in a mostly functional approach to UI
How impractical would people say it is to use clojurescript in an environment where I want to keep my script size down to around 130KB? Playing around with this a bit, it seems like this will be hard to achieve if I make use of persistent data structures and the core library at all.
Actually, I realized my constraints aren't all that restrictive - still interested to hear what people have to say about this though. In particular, has anyone written anything significant in cljs that completely avoids the built-in data structures and core lib for the sake of keeping the built size as small as possible? Avoiding javascript's syntax might be enough to make that worthwhile...
@tomc that sounds totally possible dude to removal of deadcode by google closure. are you just comparing the cljs files or the compiled js?
I looked at the advanced compiled js - my decision after experimenting with this for a while is that it's doable but probably unpleasant. You really can't use anything in the core lib without checking its implementation to be sure it won't bloat the output. A hello world that uses (.log js/console) is tiny - about 16KB if I remember correctly, but one that uses (prn) pulls in a lot of clojurescript code, ending up around 90KB. If I ever have the need to deliver really small output files I'd consider doing that over working with javascript directly, particularly if I was already using clojure, but fortunately I was wrong earlier about my requirements, so I can continue on w/ immutable data.
i'm confused. if you're saying you need to write javascript directly then the answer is still that clojurescript compiles to tiny javascript, it's just that your handwritten javascript is making the files magnitudes larger
you'd be better off writing the javascript inside clojurescript and then still being able to transcompile it
otherwise you can get rid of the clojurescript parts and still be left with js that's far too large for your needs
@tomc JavaScript developers generally consider and compare the gzip size - it’s certainly the case that’s the only thing we’re actually concerned about
@tomc eliminating (all of) the standard library / core data structures isn’t possible - so you’re looking at > 25K gzipped to do anything at all
but if really you’re just looking for something that generates absolutely minimal output - then ClojureScript is probably not the right choice
@sophiago sorry I was unclear - I wasn't saying that I need to write javascript directly, just that I think (very non-idiomatic, interop-full) clojurescript could be a reasonable choice over javascript where built script size is highly constrained, just because clojure has a better syntax.