Fork me on GitHub
#clojurescript
<
2020-01-22
>
jeroenvandijk09:01:34

Maybe some people here?

jsyrjala09:01:58

There is also #aws-lambda channel

👍 4
Ivan Koz12:01:38

i'm a noob can somebody answer if we plan CLJS on WebAssembly?

thheller12:01:46

no plans. at least until wasm gets support for GC and probably other things.

Ivan Koz12:01:03

whats are other things

Ivan Koz12:01:21

what do we miss in wasm to make clj runtime

thheller12:01:08

don't know. I don't care much at this point. no official work is being done AFAIK.

Ivan Koz12:01:46

alright thank you Thomas, if anyone has more info on missing pieces in wasm, please tag me

vemv15:01:54

Curious, how would you say the clojurescript scene has changed in the last ~2 years? In terms of dominant libraries, techniques etc

Roman Liutikov15:01:15

hmmm, I’d say nothing changed, majority is still using Reagent and re-frame

👀 4
shaun-mahood15:01:01

There is also https://fulcro.fulcrologic.com/ which should be a lot more appealing than it was 2 years ago, particularly if you want to build full stack applications with a Datomic back end.

👀 4
vemv15:01:08

What about React hooks? How good of a decision is it (not) to use them? Particularly when they're all the rage in the wider js world

vemv16:01:48

:thumbsup: I re-read it now. Was aware of it; I'm just not sure if people are using it to build apps, how it compares in practice to a re-frame experience, etc

shaun-mahood16:01:52

I recall some discussions about how hooks and some of the other recent react features essentially replicate already existing functionality from reagent. The only one I could find again was https://news.ycombinator.com/item?id=21772910, which kind of sums up those conversations as I remember them.

vemv16:01:17

interesting thread, thanks!

Filipe Silva16:01:13

heya, are there any breaking changes one should be aware of when updating to 1.10.59 and using cljs.spec.alpha? I'm updating a project's cljs 1.10.520 to `1.10.597` , and my optimised build now fails when loading something spec related

| TypeError: Cannot read property 'prototype' of ...
                                                V
$APP.$cljs$spec$alpha$t_cljs$0spec$0alpha62946$$.prototype.$cljs$spec$alpha$Spec$gen_STAR_$arity$4$ = $JSCompiler_unstubMethod$$(6, function($_$jscomp$256$$, $overrides$jscomp$11$$, $path$jscomp$62$$, $rmap$jscomp$11$$) {
  return $APP.$cljs$core$truth_$$(this.$gfn$) ? this.$gfn$.$cljs$core$IFn$_invoke$arity$0$ ? this.$gfn$.$cljs$core$IFn$_invoke$arity$0$() : this.$gfn$.call(null) : $APP.$cljs$spec$alpha$re_gen$$(this.$re$, $overrides$jscomp$11$$, $path$jscomp$62$$, $rmap$jscomp$11$$, $APP.$cljs$spec$alpha$op_describe$$(this.$re$));
});
(alexmiller was kind enough to direct me here instead of #clojure-spec since cljs.spec.alpha has a different imp than spec.alpha)

thheller16:01:28

did you identify the bit of code responsible for this?

Filipe Silva16:01:55

stepping through the exceptions showed this particular bit as being the one that yielded the final exceptions

Filipe Silva16:01:15

I haven't traced these symbols to see where they are used yet

thheller16:01:21

no I mean the actual source code that lead to this code

thheller16:01:01

likely something including (when gfn (gfn)) and reify

Filipe Silva16:01:03

I think we mean the same thing, insofar as I have to go figure out how these symbols trace back to my source

Filipe Silva16:01:50

I haven't done that yet but it's next on the docket, now that I know there isn't something obvious I should be following to update

thheller17:01:07

also search the source for other references to $cljs$spec$alpha$t_cljs$0spec$0alpha62946$$

thheller17:01:21

other modules or so, just to see if it was maybe moved elsewhere

Filipe Silva17:01:40

will do, thank you for the hint

Filipe Silva23:01:40

I was working on this a bit more today

Filipe Silva23:01:08

I did identify the bit of code that does it by using sourcemaps

Filipe Silva23:01:23

it seems related to reify, but it's in the source for cljs.spec

thheller23:01:37

yes, that was expected

thheller23:01:47

$cljs$spec$alpha$t_cljs$0spec$0alpha62946$$ its in the name 😉

thheller23:01:18

thats pseudo name for a reify in cljs.spec.alpha

thheller23:01:26

would help to know which one

Filipe Silva23:01:01

I think regex-spec-impl, let me double check

Filipe Silva23:01:29

I've been doing release builds all day and trying variations of things to see if I could narrow it down... must have done some 40 at least

thheller23:01:57

what do you get when you look for $cljs$spec$alpha$t_cljs$0spec$0alpha62946$$ in your output?

thheller23:01:10

(note that changes between each compile since its a gensym)

Filipe Silva23:01:13

one second, let me just give you the findings I already have

Filipe Silva23:01:22

I think I've finally hit a way to make it not happen

Filipe Silva23:01:15

• will not error if there are only s/def • will error if there are s/assert or s/fdef • doesn't matter if s/check-asserts was used, or what the value was • only takes a simple assert to fail e.g. (s/def ::str string?)(s/assert ::str "abc") • will error if the assert is in a lazy module • will not error if the assert is in the initial non-lazy module • once there is an assert in the initial non-lazy module, having asserts in the non-lazy modules doesn't seem to cause errors

Filipe Silva23:01:28

that last bit was what I just figured out

Filipe Silva23:01:05

will uncomment all the other asserts to see if it still holds true outside the sample code I was using

thheller23:01:08

so I should be able to reproduce that

thheller23:01:11

hmm dunno how to reproduce ... seems to be working fine

thheller23:01:58

frankly the code in spec scares me ... the macro driven nature makes it extremely hard to follow

thheller23:01:02

and the code it generates is crap

thheller00:01:43

ah no I got it reproduced

Filipe Silva00:01:57

what was missing?

Filipe Silva00:01:27

I managed to get into a bad state again, I think after I uncommented fdefs....

Filipe Silva00:01:40

I'm guessing both assert and fdef need to be in the entry module

Filipe Silva00:01:24

can verify it doesn't even need the s/def, (s/assert string? "abc") is enough

thheller00:01:56

ok the problem seems to be that the closure compiler recognizes the "class" created by reify

thheller00:01:13

but due to cross module motion moves parts of it to the other module

thheller00:01:38

since it doesn't know that the "class" is constructed conditionally

thheller00:01:02

or rather when first calling the fn

thheller00:01:17

interesting ...

Filipe Silva00:01:27

in the codebase I am on, adding this to the entry module makes everything else work ok

(s/assert boolean? true)
(s/fdef boolean? :ret boolean?)

thheller00:01:25

yes, because that prevents the cross-module-motion

Filipe Silva00:01:01

yeah I imagined it'd pull it to the entry

Filipe Silva00:01:16

I'll make an issue

thheller00:01:33

didn't you say :output-wrapper made it work?

Filipe Silva00:01:56

no, output-wrapper made that random weird npm lib work ok

thheller00:01:01

I'm pretty certain this is a bug in CLJS and I'm pretty sure its one they won't fix

Filipe Silva00:01:12

it's pretty easy to work around, just very surprising

thheller00:01:42

I'm surprised this doesn't happen more often

thheller00:01:06

now that I see it its a pretty obvious flaw in reify

Filipe Silva00:01:51

so you can imagine a repro without spec?

thheller00:01:07

well ... I knew about the issue in other contexts. that it affects method motion is news to me 😛

thheller00:01:24

yes. it isn't related to spec at all

Filipe Silva00:01:55

I don't think I understand reify well enough to repro with it

Filipe Silva00:01:10

does the cljs issue tracker issue accept shadow-cljs repros?

thheller00:01:25

the hard part is getting the closure compiler to move the code in a similar way

thheller00:01:28

that I also can't do

thheller00:01:51

no they don't

thheller00:01:10

I think I can repro this without shadow-cljs

thheller00:01:25

don't need the async loader at all

Filipe Silva00:01:32

if it helps, this project has a bunch of lazy modules, not just one

thheller00:01:52

I have it reproduced with 10 lines of code or so

thheller00:01:08

just need to figure out how to configure cljs.main. never really use that.

thheller00:01:09

(ns test.main
  (:require
    [cljs.spec.alpha :as s]))

(s/def ::foo pos-int?)

(defn init []
  (js/console.log "test.main init"))

thheller00:01:16

(ns test.mod-a
  (:require
    [cljs.spec.alpha :as s]
    [test.main :as main]))

(defn init []
  (js/console.log "mod-a init")
  (s/assert ::main/foo -1))

thheller00:01:33

;; shadow-cljs configuration
{:source-paths
 ["src/dev"
  "src/main"
  "src/test"]

 :dependencies
 []

 :dev-http
 {9300 "public"}

 :builds
 {:test
  {:target :browser
   :modules
   {:shared {:entries []}
    :main {:init-fn test.main/init
           :depends-on #{:shared}}
    :mod-a {:init-fn test.mod-a/init
            :depends-on #{:shared :main}}}}}}

thheller00:01:49

<script src="js/shared.js"></script>
<script src="js/main.js"></script>
<script src="js/mod-a.js"></script>

thheller00:01:00

public/index.html

thheller00:01:46

don't really need the "shared" module but CLJS has the implicit cljs_base module so need 3 for testing

thheller00:01:42

if you feel like reproducing with just cljs.main and reporting the CLJS Jira go ahead

thheller00:01:50

way too late for me to try that

Filipe Silva00:01:12

I'm wrecked from looking for this all afternoon, but I think I'll try to repro and report tomorrow morning, or afternoon

Filipe Silva00:01:34

haven't used cljs main either, and that sort of thing is usually a bit hard on windows

Filipe Silva00:01:48

but it might work out with wsl

Filipe Silva00:01:53

thanks for all the help figuring this out

thheller00:01:23

you did all the hard work 😛

Filipe Silva00:01:15

well hard work isn't always enough

thheller00:01:09

ok ... I reproduced it with pure CLJS ... can't sleep anyways when thinking about this

Filipe Silva01:01:18

this sounds like a tough one to fix

Filipe Silva01:01:23

nice minimal code too

Filipe Silva01:01:52

can you link the issue here if you're opening it?

thheller01:01:59

would be great if you open the issue. I don't really have the bandwidth to pursue this further.

Filipe Silva10:01:58

feel free to edit any innacuracies

Filipe Silva10:01:14

will ping David about it as well

Filipe Silva10:01:46

@dnolen in regards to the spec regression on 1.10 that I mentioned a couple of days ago, @thheller looked into it with me and we found it's related to reify across modules. Opened issue for it: https://clojure.atlassian.net/browse/CLJS-3207

👍 4
dnolen16:01:31

@filipematossilva not aware of anything - there were some fixes in the last release but nobody else reported a regression yet - just other bugs / missing things

Filipe Silva16:01:05

coolio, thank you for the info

Filipe Silva16:01:21

I'll try to narrow it down and see if it's something silly we're doing or if there's some regression

dnolen18:01:18

@filipematossilva thanks please file a ticket if you can isolate a regression

Alex Miller (Clojure team)20:01:26

Have you filled out the 2020 State of Clojure Community Survey yet? It's a great source of info in understanding the community, and we'd welcome your participation if you have a few minutes. https://surveymonkey.com/r/2020clojure

❤️ 4
mruzekw20:01:40

Is ISeq implemented for JS objects, arrays, and ES6 sets? I’m wondering if it would be possible to keep immutability through functions rather than the data structures being immutable themselves. The question mainly comes from concern about performance in certain situations like creative coding and interactive graphics. I was told that CLJS’s immutable data structures can be too slow in these cases which led me to wonder if we could just implement the ISeq functions for JS data structures purely

mruzekw20:01:07

This of course wouldn’t defend again third-party code from mutating them, but it would be a step.

Roman Liutikov20:01:29

I think iteration is about 2-3x slower in general, so it really depends on what is slow for you.

Roman Liutikov20:01:43

Also take a look at cljs-bean

👀 4
bfabry20:01:06

all cljs data structures are necessarily javascript data structures underneath. and cljs already has an answer to "discard immutability for speed" (transients) that my guess is is pretty well tuned

bfabry20:01:06

what I'm saying is if you find some big wins see if you can get it back into the cljs transients code 🙂

mruzekw20:01:15

Again, this is just an area I’m interested coding with CLJS in but have been warned against it for performance reasons, including with the use of transients

mruzekw20:01:12

But I don’t have personal experience with this problem yet, nor do I know if said others know about cljs-bean

mruzekw20:01:07

cljs-bean looks promising

andy.fingerhut20:01:56

It is definitely easier for some kinds of code to squeeze out the best performance of the language you can if you use mutable data structures. I do not know for sure, but it might be impossible (or at least highly impractical) to achieve maximum performance in some applications using only immutable data structures. That said, you can often achieve good enough performance using immutable data, when you aren't writing a game engine or the inner loop of some heavy number crunching code.

andy.fingerhut20:01:23

If you are working on code that takes 90% or more of the time and trying to optimize it, then I'm not sure JS is even the right language.

mruzekw20:01:05

I’ve also considered creative coding in Rust 🙂 Cause I don’t want to learn C++

darwin20:01:02

IMO with enough care you can always write cljs code which will transpile into no-overhead js similar to hand-written js (e.g. using a lot of interop and native js arrays and objects) - it just won’t be idiomatic clojure code so I’m pretty confident in using cljs in all scenarios where js would be used, I keep using cljs in idiomatic way and later when I identify performance issues, I rewrite hot paths into non-idiomatic fast cljs or in the worst case I have always escape hatch to rewrite such hot code in js directly and use it from rest of my cljs codebase

👍 8
mruzekw20:01:53

Sure, makes sense

andy.fingerhut20:01:23

It is difficult for us to know how nuanced and thoughtful the suggestion to avoid immutable data was 🙂

bfabry20:01:53

yeah using native js arrays seems like a good trick when you need it

cljs.user=> (simple-benchmark [arr #js [1 2 3 4 5 6 7 8]] (areduce arr i ret 0 (+ ret (aget arr i))) 500000000)
[arr #object[cljs.tagged-literals.JSValue]], (areduce arr i ret 0 (+ ret (aget arr i))), 500000000 runs, 3530 msecs
nil
cljs.user=> (simple-benchmark [arr [1 2 3 4 5 6 7 8]] (reduce + 0 arr) 500000000)
[arr [1 2 3 4 5 6 7 8]], (reduce + 0 arr), 500000000 runs, 38302 msecs

andy.fingerhut20:01:58

I have met some developers who worry about performance when it isn't crucial.

darwin20:01:22

where I see a problem is when my idiomatic cljs code needs to interact heavily with rest of js, that needs marshalling between js native data structures and cljs data structures - it is annoying/error prone and could lead to performance issues

dnolen20:01:04

@mruzekw note nothing is stopping you from writing ClojureScript around JS native types

dnolen20:01:15

that's how ClojureScript itself is implemented

mruzekw20:01:52

But can I use, say, cljs map, filter, reduce with them?

mruzekw20:01:21

Or would it be (.map js-arr …)

dnolen20:01:11

with arrays you can use those yes

mruzekw20:01:55

Whoops haha, js-arr

dnolen20:01:31

transducers perform reasonably well on arrays - in striking distance of handwritten loops (because effectively that's what it is anyway)

dnolen20:01:18

but in my experience the only place you need this kind of stuff is inner loops

bfabry20:01:36

cljs.user=> (map println #js [ 1 2 3 4])
1
2
3
4

👍 4
dnolen20:01:37

people have written games and interactive applications that perform reasonably w/o bothering with this stuff

mruzekw20:01:05

Hmm, alright. Well I’ll have to look further into their claims and what they were working on

dnolen20:01:47

if you know what you are going to do and you know it requires primitive arrays and hand written loops you can do that is all I'm saying

dnolen20:01:01

if you don't know what you are going to do - then I wouldn't worry about it

dnolen20:01:14

and just write your game or interactive application - you'll probably be ok

mruzekw20:01:53

Sure, I honestly don’t know yet. Probably something with WebGL/Canvas/shaders

dnolen20:01:42

if all your serious stuff is in WebGL/shaders then ClojureScript probably won't be much of bottleneck

dnolen20:01:07

if you'll be shuttling buffers around so you can't use ClojureScript data structures here anyway

mruzekw20:01:38

Makes sense

mruzekw20:01:58

Well I guess I’ll just have to try some things out 🙂

mruzekw20:01:07

Thanks for your thoughtful responses everyone

darwin20:01:35

@mruzekw I’m just in the process of porting react-three-fiber examples to cljs, so far it looks plausible (and the code does a lot of interaction with three.js) - at least the dev experience will be on par with writing js+jsx - haven’t done any performance comparisons yet https://github.com/binaryage/cljs-react-three-fiber

👍 8
mruzekw20:01:58

Thanks! Will give it a look

mruzekw20:01:07

Three.js is definitely on my list to check out

mruzekw20:01:49

Wow the demos on the JS lib look great!

darwin20:01:56

I tend to hide all interop-y stuff under helpers namespace and the main code reads quite well, so even Cursive does not complain 🙂

dnolen20:01:47

haven't been following react-three-fiber that is pretty cool

mruzekw20:01:50

I’m also a musician, so I think it would be cool to hook up MIDI or live sound to a music visualizer

mruzekw20:01:59

This would probably work for what I’m looking for

darwin21:01:50

@dnolen react-three-fiber is pretty recent project, they build on the fact that you can write custom reconcilier for react, so you can manage other structures in react-way, not only DOM

darwin21:01:05

@mruzekw if you want to learn it you could take some demos and help me port them - the scaffold is in place, it should be just a matter of rewriting their js code into nice cljs 🙂

mruzekw21:01:18

Sure! I can take a stab at a couple to learn

👍 4
lilactown22:01:30

I whipped up a quick example of using react-three-fiber with helix, too 😄 https://gist.github.com/Lokeh/c0fd5d8df772412be79a034d627f8ff0

👏 4