This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-01-08
Channels
- # aleph (1)
- # architecture (4)
- # aws (5)
- # beginners (105)
- # boot (1)
- # boot-dev (72)
- # cider (5)
- # clara (15)
- # cljs-dev (51)
- # cljsrn (5)
- # clojure (155)
- # clojure-austin (3)
- # clojure-dusseldorf (2)
- # clojure-finland (1)
- # clojure-greece (37)
- # clojure-italy (17)
- # clojure-nl (1)
- # clojure-russia (6)
- # clojure-spec (23)
- # clojure-uk (6)
- # clojurescript (7)
- # community-development (1)
- # css (10)
- # cursive (15)
- # datomic (45)
- # defnpodcast (1)
- # duct (97)
- # emacs (5)
- # fulcro (46)
- # hoplon (8)
- # instaparse (25)
- # keechma (11)
- # leiningen (16)
- # off-topic (2)
- # onyx (9)
- # planck (2)
- # re-frame (5)
- # reagent (3)
- # reitit (2)
- # ring (6)
- # shadow-cljs (35)
- # spacemacs (9)
- # specter (9)
- # sql (18)
- # uncomplicate (4)
Is it for performance? Asking, because Closure doesn't inline/break-up the IIFE when they're deep inside a function.
Just removing the IIFE in that case reduced my code size by 5% (both, gzipped & non-gzipped)
@dnolen I mean why do any IIFE's at all in a let
? We should only need them in a loop
where we need to lock-in the mutable loop variables, right?
I don’t really understand why you keep talking about let
and far as I know what you’re describing shouldn’t be true - but you’ll have to point me to some code you think isn’t doing the expected thing
rewinding a bit - in JS many kinds of statements cannot syntactically be present in certain positions - so we must introduce IIFEs to get around that, as FEs are one of the few forms in JS that can appear nearly anywhere legally.
Ok let's back up. Why does this code:
(fn []
(let [a 1, b 2]
#()))
Create an IIFE:
function (){
var a = (1);
var b = (2);
return ((function (a,b){
return (function (){
return cljs.core.List.EMPTY;
});
;})(a,b))
}
The thing is: Because most real world code has some kind of bindings in the function we currently wrap all functions within a defn
with an IIFE and passing all local bindings.
I did a quick hack on the emitter and removed the local let bindings from the IIFE, the result is a --IMO pretty significant-- 5% reductions in code size. I'm going to guess that the performance would also actually improve (to be tested).
To answer myself: B/c otherwise this would regress: https://dev.clojure.org/jira/browse/CLJS-154
FWIW, emitting a const
js syntax for let
s would fix this and shift the burden to Google closure compiler to do the right thing.
that’s not compiler IIFE in general, that an IIFE which explicitly captures local vars for the loop problem.
re: const
won’t Closure do something similar to prevent reassignment? Need to know what Google Closure will generate before bothering.
@dnolen Closure is currently buggy. Does some very very strange stuff: http://bit.ly/2CUs2IE (link to closure compiler on app spot)
@dnolen Re "how does Closure compile const captures": It looks like it passes in a JS object with the local bindings and resets this JS object on every loop. Then creates an IIFE with a single variable (the JS object).
Shadowing doesn't actually work properly with dashes in the first segment of the ns. For instances, my entire project is under srs-c.*
and I do:
(let [srs-c "works", srs_c "boom"]
(anything-calling-somethign-from-srs-c-fails))
I certainly don't want to make the compiler 2x slower with this. Looking through git history a bit earlier and there used to be a ns-first-segments
, that was a set of the first segments of all namespaces. Maybe this should be re-introduced and maintained as namespaces are parsed?
See: https://github.com/clojure/clojurescript/commit/1c71ab3bff27dc4a099b06e122ec3fdf5a2a8ba8
Hi cljs team. We (http://workframe.com) are working 100% in cljs on the frontend, looking at 2018 as a time to contribute in whatever way benefits the most developers. Planning to send out out a survey to Clojure NYC (which we run) and other meetup lists to gain and share knowledge about the ecosystem and js dependencies in particular. We’d love your input on the content if you have any https://docs.google.com/forms/d/e/1FAIpQLSeheqZbpIpMQycTllcOkdJuX6_8C6tr0_I0zunCTb-g2F5zzA/viewform
I tested my Closure update patch with new 20180101 release and it is broken again (or probably I did something wrong when I tested master two weeks ago). I'll try bisecting Closure-compiler changes to see what breaks this.
I think I got the processing working again. Had to change to passes being called during module processing.
Looks like compiler now needs a change to call all functions from processed modules using ["default"]
property
@andyparsons seems like useful information
@dnolen great, I’ll share results with everyone
I think I got the processing working again. Had to change to passes being called during module processing.
Looks like compiler now needs a change to call all functions from processed modules using ["default"]
property
@juhoteperi even if exported?
for example CJS create-react-class or left-pad which only export single function module.exports = function() { ... }
are now turned into module$path$left_pad$index = {}; module$path$left_pad$index["default"] = function() { ... };
And in React's case the object is exported under default
I think all CJS modules use default
to match ES6 modules
@juhoteperi or is it because we’re processing every module as :es6
?
https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/closure.clj#L2278
Closure ES6 passes only touch scripts which use ES6 module features
https://github.com/google/closure-compiler/commit/6f43ec65e570b983a46bc7a652e42f89f1f92e67 this includes CJS test cases using default
Skipping ES6 passes and only using CJS results in the same output for CJS modules
makes this even more relevant https://dev.clojure.org/jira/browse/CLJS-2376
Yes, though it will be really confusing to implement this now that we need to use default property even for CJS modules
Latest patch here: https://dev.clojure.org/jira/secure/attachment/17612/CLJS-2389-wip-2.patch / https://github.com/clojure/clojurescript/compare/master...Deraen:closure-update-4
@juhoteperi not that confusing, but maybe breaking change. whenever you used :as thing
and directly accessed that (thing)
you now you :default thing
instead which is consistent with ES6