cljs-dev

dnolen 2025-11-22T18:05:02.358679Z

interesting stuff discovered while looking into the last two bits of work

dnolen 2025-11-22T18:06:03.750779Z

Reflect.apply is faster than Function.prototype.apply , rest parameters are significantly faster than touching arguments

👀 1
dnolen 2025-11-22T18:07:19.495829Z

the later is big enough that I think we should emit it

2025-11-22T18:09:33.005199Z

really? that's surprising to me

dnolen 2025-11-22T18:25:08.122849Z

I'm thinking the next release we should say that we emit ES-2016 and moving forward

👍 1
dnolen 2025-11-22T22:09:46.937699Z

ok method values in

borkdude 2025-11-22T22:13:47.228409Z

Ah, ...args this is why you were saying ES-2016 moving forward :)

dnolen 2025-11-22T22:19:05.750549Z

yeah ...args + Reflect is fast

dnolen 2025-11-22T22:19:21.664869Z

we don't need to know anything now - i.e. :param-tags

borkdude 2025-11-22T22:21:14.359679Z

yeah I've also been using Reflect.construct in SCI since forever

#?(:cljs
   (defn invoke-js-constructor* [ctx bindings constructor args]
     (js/Reflect.construct constructor (.map args #(sci.impl.types/eval % ctx bindings)))))

borkdude 2025-11-22T22:21:48.828179Z

(I even forgot I had it in there)

dnolen 2025-11-22T22:24:09.375319Z

yeah we avoided for the obvious reasons, too new, and in the beginning not efficient. But time to move ahead now.

borkdude 2025-11-22T22:24:22.484629Z

If ES6 is now the minimum, I also could've stayed with emitting string templates in the str optimization. Not that it matters much probably

borkdude 2025-11-22T22:24:45.573779Z

in squint I do emit them since I assume ES6 there

dnolen 2025-11-22T22:25:20.671419Z

yeah I think anything in ES 2016 is fair game.

dnolen 2025-11-22T22:25:41.045019Z

for people who need earlier support 1.12.42 has plenty of power and stability

borkdude 2025-11-22T22:26:19.072159Z

(let [x 10]
  (str 1 2 3 x))
=>
let x2 = 10;
`123${x2}
`

dnolen 2025-11-22T22:26:33.620129Z

let isn't faster than var

borkdude 2025-11-22T22:26:49.429839Z

the point here isn't let vs var, it's the string template

dnolen 2025-11-22T22:27:22.116059Z

I haven't followed, the string template thing whether it's actually any faster

dnolen 2025-11-22T22:27:48.719599Z

mostly only care about ES 2016 features that are faster or let us achieve some special

borkdude 2025-11-22T22:27:55.952219Z

I haven't noticed any perf difference, just liked reading the output better :)

dnolen 2025-11-22T22:28:13.695869Z

hehe, yeah not a priority

borkdude 2025-11-22T22:28:49.389239Z

I thought CLJS maintained emitting old JS because it had to run on some special devices with old JS engines or so. But I'm not complaining about bumping to ES6

dnolen 2025-11-22T22:29:45.608859Z

well in past there was no reason to use new features because it just complicates things. But also engines historically were only fast on the old specification of the language

dnolen 2025-11-22T22:30:20.958839Z

finally there are perf wins in ES 2016

dnolen 2025-11-22T22:30:37.945719Z

but they are in strange places

dnolen 2025-11-22T22:31:06.614989Z

(wrt. CLJS)

borkdude 2025-11-22T22:33:18.674869Z

ES6 also was the version that introduced import. Does GC now actually support this? I remember it having trouble with this

borkdude 2025-11-22T22:33:37.960499Z

or maybe it was just dynamic import

borkdude 2025-11-22T22:35:23.807079Z

In squint I emit ES6 modules by default (not because they're cool, just because they are expected in the JS world). One huge problem with this is that you can't set! vars in other namespaces because ES6 modules don't allow this.

dnolen 2025-11-22T22:37:54.850809Z

We're never going to do anything with ES6 modules, Google doesn't care about it - it's a hassle for DCE, they compile it away internally.

👍 1
dnolen 2025-11-22T22:45:33.486319Z

Reflect makes doing any thing about ES6 classes less interesting.

dnolen 2025-11-22T22:46:13.260579Z

generators, async still curious about especially if the later can simplify cljs.core.async

dnolen 2025-11-22T22:46:30.822459Z

generators are nice :lite-mode , interop laziness w/o our machinery

borkdude 2025-11-22T22:47:22.995769Z

yep, Reflect is a great tool when you need it for await...of did remind me a lot of core.async channels

borkdude 2025-11-22T22:49:12.273729Z

with machinery do you mean, the go macro?

dnolen 2025-11-22T23:13:28.560069Z

Yeah

dnolen 2025-11-22T23:17:05.458049Z

Oh no for generator I mean the interop methods for JS are not lazy which is annoying - keys entities etc

dnolen 2025-11-22T23:17:35.274189Z

Using map etc pulls in stuff. But if we could return generators could be lazy and lighter

borkdude 2025-11-22T23:18:03.217699Z

that's how squint implements laziness

👍🏽 1
dnolen 2025-11-22T23:18:08.674949Z

JS api for functional operators on generators is coming

dnolen 2025-11-22T23:18:56.486469Z

Nice - squint is definitely giving me some inspiration

borkdude 2025-11-22T23:19:00.950629Z

one difference with CLJS here is that lazy seqs aren't cached

dnolen 2025-11-22T23:19:14.293709Z

For interop that is ok

borkdude 2025-11-22T23:20:01.180039Z

I have a setting where you get a warning where a lazy seq is realized multiple times so you can iron that out. I haven't actually seen that many cases. Most often a lazy seq is just iterated once in typical programs

borkdude 2025-11-22T23:20:33.406319Z

you can iterate them multiple times in squint, but the results are re-calculated

borkdude 2025-11-22T23:21:38.908569Z

when you want to cache you just turn it into an array first.

borkdude 2025-11-22T23:22:47.742199Z

credit where credit is due, @lilactown came up with that idea

borkdude 2025-11-22T23:26:48.314149Z

ok, that's interesting indeed. es6 iterables seem to support .map etc. https://squint-cljs.github.io/squint/?src=gzip%3AH4sIAAAAAAAAE9MoS01W0NDLTSxQ0EgtNtPNLEktSizJL1LQAAll5iUrRBsqGCkYx2pqgniamgCyQJNXMQAAAA%3D%3D

dnolen 2025-11-22T23:37:42.356619Z

Pretty sure all of the Iterator api should work

dnolen 2025-11-22T23:38:09.318969Z

concat is a proposal that is coming I believe

dnolen 2025-11-22T22:10:01.577539Z

the latest stuff needs a bit more coverage, then the Closure Compiler update