Fork me on GitHub
#clojurescript
<
2018-07-26
>
souenzzo00:07:42

I need to pack a javascript lib that will be used in django/PHP/template-like sites by <script src...> and myLib(....) besides exporting, there is any other concerns ?? can my bundle become incompatible with other's bundle?

justinlee02:07:18

@souenzzo you mean you want to compile cljs to js and then include it via script tag in another js program?

justinlee02:07:11

if so, then I’m pretty sure that you cannot include more than one cljs-compiled bundle in a single environment

souenzzo13:07:02

how can I google more about that? there is some buzzword or a issue to start?

justinlee17:07:02

@souenzzo i’m just reporting what i’ve seen in this channel. you might hop into #shadow-cljs and describe what you are doing. there a lots of people who have been doing similar things

Aaron16:07:28

Hi all, I am using lein to build my re-frame project, and have hit a lot of trouble when trying to get cider working in Emacs. Long story, now my project won't build from the command lein or through Emacs. Here is the error:

error in process sentinel: Could not start nREPL server: java.lang.Exception: Error loading /home/aaron/Source/grownome-admin/project.clj 
And more detailed:
Caused by: clojure.lang.Compiler$CompilerException: java.lang.IllegalArgumentException: No value supplied for key: {:builds {:dev {:source-paths ["src/cljs"], :figwheel {:on-jsload "grownome-admin.core/mount-root"}, :compiler {:main grownome-admin.core, :output-to "resources/public/js/compiled/app.js", :output-dir "resources/public/js/compiled/out", :asset-path "js/compiled/out", :source-map-timestamp true, :preloads [devtools.preload day8.re-frame-10x.preload re-frisk.preload], :closure-defines {"re_frame.trace.trace_enabled_QMARK_" true, "day8.re_frame.tracing.trace_enabled_QMARK_" true}, :external-config {:devtools/config {:features-to-install :all}}}}, :min {:source-paths ["src/cljs"], :compiler {:main grownome-admin.core, :output-to "resources/public/js/compiled/app.js", :optimizations :advanced, :closure-defines {goog.DEBUG false}, :pretty-print false}}, :test {:source-paths ["src/cljs" "test/cljs"], :compiler {:main grownome-admin.runner, :output-to "resources/public/js/compiled/test.js", :output-dir "resources/public/js/compiled/test/out", :optimizations :none}}}}, compiling:(/home/aaron/Source/grownome-admin/project.clj:1:1) 

Aaron16:07:46

And here is my project.clj

Aaron16:07:36

I've tried formatting and modifying many things, and just can't figure out what is going on.

thheller17:07:05

@aaron993 note the extra map in {:prod ...}

thheller17:07:34

its {:dev {...} {:prod ...}}

thheller17:07:59

should be {:dev {...} :prod {...}}

Aaron17:07:06

@thheller thank you! Man I've been losing my mind over this, especially on top of trying to get figwheel to work

Aaron17:07:57

Now back onto getting figwhee;/piggieback working ...

john17:07:24

Hey folks, got a new example of tau.alpha up on a github page, showing an automaton stress test both on the main thread and off the main thread: https://twitter.com/Doxosophoi/status/1022357248201379840

justinlee18:07:36

@john doesn’t seem to work for me. clicking does nothing

john18:07:39

yeah, probably should have been a bit more explicit. It won't work unless you enable SharedArrayBuffers in <chrom://flags>

justinlee18:07:14

shared memory the horror.

john18:07:16

it was nontrivial getting it to barely work 😉

justinlee18:07:39

the only thing beautiful about this language is that you don’t have to worry about this crap haha. why is everybody mad.

john18:07:19

:man-shrugging:

justinlee18:07:04

okay i concede that’s a pretty effective demo, though 🙂

justinlee18:07:14

would be really helpful for rendering pdfs in the browser

john18:07:44

Yeah, I think it proves the point. You can squeeze more juice out this way

justinlee18:07:40

so are you sharing the raster that backs the canvas directly? (assuming that’s a canvas)

john18:07:57

Yeah, typed arrays

john18:07:09

Canvas now uses a Uint8ClampedArray

justinlee18:07:24

so the main ui thread literally does nothing?

john18:07:20

it just moves a typed array as fast as js can manage. Which is apparently pretty fast.

john18:07:30

I've got a version that doesn't use SharedArrayBuffers, instead passing Transferables. But there's still transfer overhead and the benefits wash out for a lot of scenarios.

justinlee18:07:58

so it gets a notification that there’s new stuff in the array and then copies that into the canvas? and there must be some kind of synchronization around the copy?

john18:07:16

Yeah, the tau implementation uses twice the memory you specify, on the inside. swap!ing on it alternates the write point, so reads never block, like clojure atoms

john18:07:04

notifications are still in progress. I haven't fixed up the add-watch solution for this SAB version

john18:07:37

So in that example I'm using a separate, local atom to trigger a watcher, to restart the next render

justinlee18:07:02

that is Most Excellent. I would not have thought you could swap the full raster that fast.

john18:07:46

but once I have watchers back up on this SAB implementation, we can just put the watch on the tau itself and the implementation code for this example will be even more succinct.

john18:07:06

The main thread automatons still run a little faster, but once you get all six of either scenario going, you can see the main thread scenario slows down too much, and the interface becomes unresponsive.

mfikes18:07:02

I saw Craig Andera give a demo that essentially involved drawing a map with some simulated weather effects, written in ClojureScript, and he had it calculating the weather for different regions in the canvas in background tasks in the browser. Perhaps something like this Tau stuff would have made it simpler for him to code up.

john18:07:47

the memory management is naive right now. You have to know before hand how large your memory workload is.

john18:07:09

It sounds like in that scenario, he could def have managed that

john18:07:03

A better memory management scheme might make it more general, but I see no avenue for expanding the size of SABs synchronously, on or off main thread, atm

john18:07:24

I imagine the WASM folks will need to do that eventually though, in order to port over all these langs

justinlee18:07:08

where is the mathy stuff happening? in a webworker? i’m just trying to figure where that code is because i thought that you don’t have access to the canvas element in a webworker and so i was wondering how you are doing the drawing

john18:07:47

I'm doing the automaton stuff in the automaton namespace in the example subproject

john18:07:46

It just runs across a 1d array, reading cells from the left and writing new ones to the right, as if it's a 2d array

john18:07:30

It's probably not a fully faithful implementation. I just threw it together to show some brute force computations

mfikes18:07:09

FWIW, it is really good at making use of cores https://twitter.com/mfikes/status/1022550658522771456

fan 4
🔥 4
justinlee18:07:34

damn well i’ll have to wait for offscreencanvas and shared memory to become mainstream 🙂

justinlee18:07:09

that’s a super cool demo though

john18:07:19

Personally I think if this path is efficacious, folks should be keeping their head-space on the webworker side and only push logic to the main thread as if it's just a screen

john18:07:40

the demo is not written that way, but I may eventually have other examples that show doing things that way

justinlee18:07:42

the problem is if you need to draw a bunch of, say, text to the screen, you have to do that in the main thread afaict

john18:07:24

SABs and webworkers are now in Node too, behind an experimental switch.

mfikes18:07:55

If it ever happens (things like https://webkit.org/blog/7846/concurrent-javascript-it-can-work/) then ClojureScript is really primed to work well in this space (small experiment https://github.com/mfikes/mt-cljs)

👍 4
john18:07:08

and with a non-SAB implementation, you could have an isomorphic "pool" of tauons that are on both the server and client, but appear to be local to one aonther

john18:07:19

(on client-tauon (do ...

john18:07:13

We're def primed to "fix" JS's concurrency problems, once they're ready to take them on 😉

john18:07:39

Or you could merge multiple tauon pools between multiple node instances. The webworker and the websocket postMessage interface are very similar

john18:07:56

It's just a matter of writing up the routing and then wrapping in a clojury abstraction

Dunk18:07:44

Hi. Just wondering - does figwheel play nicely with CIDER at all, or is it always inf-clojure that people use?

john19:07:00

@mfikes what I like about the tau method over the mt method you showed, is that in this tau scheme, threads are still uninterruptible, so a given js context is still semantically consistent. You can only "wake" a thread up via the single response a particular thread is waiting on.

mfikes19:07:34

Ahh, that would make some things easier.

john19:07:36

So you have to structure things circularly, but some of the apparent benefits of singlethreadedness from the js world is still maintained

mfikes19:07:25

Is that why you were focused on agents? (They could bash on their own state safely?)

mfikes19:07:45

(I recall you mentioning agents in Baltimore)

bbss19:07:03

@clojuriansslack722 I always used it with cider. Working with shadow-cljs lately, but especially with cider 0.18.0 it should work.

john19:07:05

I just think agents will be a convenient minimal interface to operate over tauons in some scenarios

john19:07:35

Yeah, I'll have a SAB backed agent implementation up in the near future

john19:07:33

It basically fans out tasks over a pool, and synchronizes their invocations

mfikes19:07:36

Maybe a SAB-backed agent would largely “just work” without having to revise the code ClojureScript emits. :thinking_face:

mfikes19:07:11

(If you abide by some mild constraints in your code, like not messing with the state the agent operates upon, behind its back.)

john19:07:29

you can't do that, iiuyc

john19:07:53

taus are atomic and nobody can step on anybody

Dunk19:07:57

@bbss Is there a guide somewhere? I am a bit lost.

mfikes19:07:23

Ahh, so maybe if you do something like (agent x), no matter what the value of x is, a copy would be made for the SAB impl, and it can party on that copy.

bbss19:07:39

admittedly it's a bit verbose and not all steps might be needed anymore, cider 0.18.0 addresses this by making it more easy (i.e. a wizard that asks some steps)

mfikes19:07:44

That kind of facility could be extremely useful. Hmm.

Dunk19:07:09

@bbss "Even though this has recently become easier, you should still consider setting up a workflow that includes nREPL as an advanced undertaking as it requires a lot of contextual knowledge of the Clojure environment if something goes wrong.", eep.

Dunk19:07:33

@bbss I have been rolling with figwheel-main

bbss19:07:22

Yeah then go with that using-figwheel-main link, it's meant to have made it a tad easier.

john19:07:33

I haven't thought about the SAB backed implementation of agents in a little while. But the non-SAB backed version, each send basically fanned tasks out to a pool of tauons that didn't share state between them.

Dunk19:07:38

@bbss Will give it a go, thanks

👍 4
john19:07:51

in a synchronized way

john19:07:35

And you can have 1000 agents that all leverage the same pool of a dozen or so workers

john19:07:55

Basically similar to clojure's semantics

john19:07:12

For a SAB backed version, anyone waiting to write on a particular shared tau will block their thread while waiting for access.

Josh Horwitz19:07:03

Any recommendations for Clojurescript podcasts?

john19:07:15

not specific to just clojurescript that I'm aware of.

dijonkitchen22:07:05

Anyone have any strong opinions either way for https://material-ui.com/ or https://ant.design/docs/react/introduce with CLJS?

bbss22:07:23

@dijonkitchen I have, I have! I love material-ui, and have been using the latest version a bit. The older version has https://github.com/madvas/cljs-react-material-ui/ but I think the maintainer hasn't got time to figure out the new version (it's quite a drastic change).

stephen22:07:12

I tried upgrading it on this fork, but was unable to get it working for my project. https://github.com/stephenway/cljs-material-ui

bbss22:07:32

The way I use it does depend on #shadow-cljs ability to import npm packages easily, but I guess it could be done with recent improvements to cljs compiler/figwheel as well. I basically wrote a macro in clojure to take all the dirs in the node_modules dir of @material-ui/core. That, matches up with the components in the docs. Then I generated a big file with all those Symbols, and called a factory react creating function on them. It's ugly as I'm not sure how it advanced-compile/tree-shakes (probably not well). But I'm able to use it like I would any ported cljs react library. Input fields work (they can be tricky to port), and every other thing I've tried so far works too.

dijonkitchen22:07:16

http://cljsjs.github.io/ doesn’t help instead of npm-deps or shadow-cljs?

bbss22:07:24

Hmm, I'm not a big fan. cljsjs was super useful, but not needed anymore.

stephen22:07:35

anyone know if there’s a way of stopping execution as a result of a (when)? kind of like an empty return in javascript

bbss22:07:36

It includes the react version, which is not what you want

dijonkitchen22:07:38

I tried some basic stuff with the cljsjs/material-ui one and it was OK.

bbss22:07:01

Oh okay, I haven't tried it. Could be good.

justinlee22:07:01

@stephenway what do you mean by stopping execution?

bbss22:07:19

I hadn't seen the cljsjs version. I probably would have gone with that if I hadn't hacked my own version. But yeah it does mention the inclusion of its own react versions: https://github.com/cljsjs/packages/tree/master/material-ui

justinlee22:07:56

does it not just work with shadow-cljs?

stephen22:07:45

In js if i do something like if (disableMyFeature) { return; } it will stop executing beyond that line inside the function and return undefined. In cljs I could do something like (when disableMyFeature js/undefined) but I’m unsure if it will stop at that point?

bbss22:07:43

@stephen you'd need to slurp the body that you don't want executed into a (when (not disabledMyFeature) body)

stephen22:07:25

@bbss yea that’s what I’ve been doing

stephen22:07:37

@lee.justin.m thanks, I’ll check that out

john23:07:01

BTW, there was a bug in tau that made the example code less pretty than it could have been. This is an updated version I'll be pushing up shortly. Especially note the swap-on! function that replaced the send-work function. Much cleaner and more understandable.

john23:07:04

The slow load time to first render should be fixable too