Fork me on GitHub
#cljs-dev
<
2018-09-13
>
mfikes20:09:32

Anyone recall why js* was purged from core.cljs? (Nothing urgent; I'm just curious.)

dnolen20:09:17

mostly for code cleanliness and to set a good example

dnolen20:09:44

back when I was purging it you would still occasionally find people using it for no good reason

mfikes20:09:41

Cool—Ok js* is closely related to the concept of code gen, cleaner if kept in macros

dnolen20:09:45

right, we could move that stuff into the compiler and get rid of it completely, but that’s also a bit of extra work that isn’t particularly meaningful

mfikes20:09:25

Ahh, yeah. I saw a note on how js* in the and macro can flummox core.async. Maybe some other approach might help

mfikes20:09:51

That's a tough one to solve, I suppose

dnolen20:09:00

you mean our usage of js* or user usage?

dnolen20:09:21

we do not care about the later

dnolen20:09:52

what we do care about is the hole that required someone to want to leverage js*

darwin20:09:02

I use js* to emit some hand-crafted js code in place of macro expanded code, to provide correct line numbering in chrome console / javascript stack traces: https://github.com/binaryage/cljs-oops/blob/master/src/lib/oops/codegen.clj#L283

dnolen20:09:19

sure but you shouldn’t be doing that

dnolen20:09:25

and if your stuff breaks - oh well

dnolen20:09:31

you’ll have to find some other way

dnolen20:09:47

@mfikes sounds like a core.async issue not a ClojureScript one

dnolen21:09:06

now that we’ve reconciled the ASTs

darwin21:09:33

yes, I know, I should not, at least I watch it for breakage under travis/canary

mfikes21:09:33

I agree, my quick take (without digging into it) is that core.async is making some sort of assumption

dnolen21:09:36

a good project would be to copy-pasta core.async Clojure implementation which fixes a lot more bugs than just js*

mfikes21:09:29

Right, I think core.async also has heartburn on #js

dnolen21:09:21

anyway I don’t think and/or are the issue

dnolen21:09:31

if you were doing math in a go block same problem

richiardiandrea21:09:50

well the issue with and macro is weird ... it should not evaluate both expression just because in a go macro no?

richiardiandrea21:09:07

if I understood the problem correctly of course

mfikes21:09:30

Nobody isolated the root cause from what I can tell

dnolen21:09:24

yeah, I would guess that core.async has expectations about how to transform and

dnolen21:09:44

also a good way to test this - return and to it’s old form - it may still not work as expected

dnolen21:09:58

and we can stop blaming js* 😉

dnolen21:09:08

but yeah there’s not enough information in this report

jaawerth21:09:00

I've noticed that in clojure, seq and seqable? both check, and can create seqs from, Java Iterables, but cljs's seqable? et al doesn't do the same for JS via ES2015's iterator protocol. Anyone know whether this is intentional or just hasn't been gotten around to yet post-ES2015? Seems like it'd be trivial to implement since ITER_SYM is already defined in core

jaawerth21:09:25

figured I'd see if anyone knew offhand before I start tinkering with it and/or posting to the google group for the first time

jaawerth21:09:50

seems like there's an opportunity to add a little interop with newer JS features (iterables, Map/Set, etc)

mfikes21:09:50

@jesse.wertheim I’ve never used it, but es6-iterator-seq

jaawerth21:09:54

yep, so that gives you a seq from an iterator (object with a .next() fn) - one would just need to combine that with modifying the the seq-producing core to check Symbol.iterator if other checks fail and do (es6-iterator-seq (. foo ITER_SYM))

jaawerth21:09:28

@mfikes easy enough to do in userland code if necessary, just wondering if it'd be desirable to have parity with clojure's interop with Java's iterator protocol

jaawerth21:09:55

Or if it's being avoided, possibly because some iterables in JS could end up performing weird side effects as you consume their iterator

mfikes21:09:19

I have insufficient experience with that subject to have an opinion. :)

jaawerth21:09:43

no worries, appreciate the response regardless! I'll just play with it when I have time and ask the google group once I've got the specifics nailed down of what underlying cljs bits I'd need to modify

jaawerth21:09:20

or just see if the patch gets accepted I guess? I haven't contributed before so was just gonna follow the contributing guide verbatim re: etiquette

mfikes21:09:18

This channel is definitely an appropriate place to discuss such a potential change.

jaawerth21:09:20

ah, great. In any case, I think it's a good idea - it'll allow for easy consumption of ES Map/Set and any custom iterables - and things like NodeLists on the DOM are iterable now, as well. The danger is that native iterators in JS are also iterable iterators, so if this were implemented, (seq some-es-iterator) would, rather than error, invoke Symbol.iterator on it, get the same iterator back, and then consume it

jaawerth21:09:06

but for that to happen you'd have to be doing some pretty weird stuff with mutable things - raw iterators aren't usually just hanging around

mfikes21:09:52

core.async doesn’t realize that it is not ok to lift the arguments out of js* and let-bind them

(def cards :foo)

(js*
 "((~{}) && (~{}))"
 (vector? cards)
 (< 0 (count cards)))
gets converted to
(let [temp-1 (vector? cards)
      temp-2 (< 0 (count cards))]
 (js* "((~{}) && (~{}))" temp-1 temp-2))
and this results in premature evaluation of
(< 0 (count cards))

mfikes22:09:36

So, TL;DR, core.async thinks js* is a function, effectively. It doesn’t realize it is a special form.

mfikes22:09:06

^ this is the result of taking a look at the JavaScript generated for

(go (and (vector? cards) (< 0 (count cards))))

mfikes22:09:27

I’ll try removing the js* logic from and to be sure…

mfikes22:09:47

Actually, this is cut-n-dry and easily seen if you

(macroexpand '(go (and (vector? cards) (< 0 (count cards)))))

dnolen23:09:16

thinking about cutting a release soon just for the perf stuff

❤️ 4
dnolen23:09:33

also I think we should default :npm-deps to false

dnolen23:09:52

and do this simple enhancement for people who want to use code splits https://dev.clojure.org/jira/browse/CLJS-2903

dnolen23:09:12

at Rich’s Datomic Ions talk yesterday in NYC, a user asked me about this, and I agree it’s an oversight

mfikes23:09:56

Yeah, a release would probably be good. I'm thinking that any of the newer type inference stuff should probably wait until the beginning of another dev cycle. The fix for this defect is probably safe enough to include in a release https://dev.clojure.org/jira/browse/CLJS-2883

mfikes23:09:40

I agree that :npm-deps false is a good default.