Fork me on GitHub
#clojurescript
<
2017-04-12
>
qqq05:04:02

anyone have a workflow that juses uses lumo all the way instead of cljs + figwhell?

qqq05:04:09

I feel like there is something there, but I have now idea how to do it

john06:04:49

does lumo do google-closure advanced compilation?

john06:04:48

If not, your workflow needs to fit in a self-hosted on top of node scenario.

john06:04:34

or the browser, but most web pages won't need a full cljs compiler built in

john06:04:41

btw google-closure.js should allow lumo and planck to do advanced compilation in the future, if they want to go that route. So that could be a thing.

john06:04:04

I haven't heard anybody announce any major progress in putting those pieces together though.

qqq07:04:05

with lumo, how do I load dependencies ?

qqq07:04:23

(I have lumo running fine in inf-clojure in emacs)

qqq07:04:34

I just need to have it load dependencies so I can use it to write node.js apps

cgrand08:04:33

I don’t find an issue in Jira, as the addition of var-set (and var-get for symmetry) to CLJS discussed?

john09:04:05

I'd like to have it, for uniformity. But I think I've heard it intimated before that something like (set! (.-a js/cljs.user) "val") should be sufficient. And that the semantics between clj vars and cljs vars are different. But for cljc purposes, why not, right?

cgrand15:04:27

I missed your reply earlier: the problem is that (set! (.-a js/cljs.user) “val”) requires the var name to be known at compile time. I can work my way around it but var-set would be great

thheller15:04:24

@U3E46Q1DG vars do not exist at runtime in CLJS so no var-set.

cgrand15:04:30

(var foo) returns an object that allows to deref to get the value

thheller16:04:41

just use a volatile!, you can deref that and vreset! looks like var-set if you squint a little

thheller16:04:48

var is a macro that dumps a bunch of compiler information with it. don't use it.

cgrand16:04:25

athheller it’s “dynamic" vars that I want to pass around. So far I use a macro (dynvar *foo*) which expands too (fn ([] *foo*) ([x] (set! *foo* x)))

thheller16:04:40

why not pass the volatile around?

cgrand16:04:29

Because the dynamic var is not mine.

thheller16:04:42

ah you are talking about *out* I guess

cgrand18:04:44

As far as I can tell *out* is not used despite being defined. But yeah basically a host of standard dynamic cars.

john18:04:56

what is a Volatile in cljs?

john18:04:14

How can something not be atomic in a fully synchronized, non-interruptible runtime?

cgrand18:04:44

@john blind guess: an atom without watches nor validators?

john18:04:20

it's just set!

john18:04:34

I'm fully confused about the var system in cljs 😕

john18:04:50

perhaps it steps outside of persistent datastructure semantics...

john18:04:19

I think atomicity in js world pushed the boundaries of the meaning of atomic, maybe.

thheller14:04:00

absolutely not a fan of bindings in an async context. core.async doesn't know about your bound-fn so it won't work.

cgrand15:04:34

It’s not a general purpose solution. You would have to bake it into core.async somehow. But for my goal it’s ok.

john01:04:45

Upgradable? What's that mean?

john01:04:38

I have an idea for a "static repl"

john01:04:55

You'd have to extern all the functions you want to make available though

john01:04:57

But it would be way lighter than a self hosted scenario

cgrand05:04:01

Upgradable means that from inside the repl you can take control over input and output.

cgrand05:04:04

Doing so you can "upgrade" the session to whatever you want.

cgrand05:04:16

Including another repl.

cgrand06:04:18

Last thing, the one that justifies this binding stuff, I want to support several session at the same time (socket repl).

john10:04:31

Yeah, it clicked after I started thinking about the method names. That's pretty meta.

john10:04:10

re: static repl... basically, cljs.reader/read-string, pr-str, some transforming of function calls into .call and .apply calls, and you might be able to create what looks like a repl, without the compiler. Just simple, runtime compilation of forms into .calls. Could be useful for, for instance, providing a DSL interface to some application without needing a whole self-hosted instance.

john11:04:51

I remember hearing a while ago that (.-someproperty js/some.object) should be preferred over js/some.object.someproperty by I see the latter in the wild more and more often. Is the former still preferred? and if so, why? Because of the method/property ambiguity?

darwin13:04:40

Unfortunately I just discovered that just requiring cljs.pprint (or cljs.stacktrace) without using anything from it ruins dead code elimination in :advanced mode. Additionally def-ing a static map with more than 8 keys causes a huge code bloat (goes from 5k to 300k bytes). Details here[1]. Any insights for solutions/work-arounds welcome. [1] https://github.com/binaryage/cljs-devtools/issues/37#issuecomment-293575471

devth13:04:35

how do you deref an atom in plain javascript? e.g. from chrome console

darwin13:04:51

cljs.core.deref.call(null,my.ns.my_atom)

darwin13:04:20

or cljs.core.deref(my.ns.my_atom) of course

darwin13:04:36

the former is what actually gets generated by cljs compiler

thheller14:04:09

@darwin I discovered a new neat feature in the Closure Compiler that allows stripping code before any actual optimizations happen

thheller14:04:14

> (.setStripTypePrefixes compiler-options #{"cljs.core.prn"}) .. strips every (prn ...) call when optimizing

thheller14:04:34

but easy to mess this up

thheller14:04:51

but to extend on your problem: there are a lot of constructs the CLJS compiler generates that cannot be removed by Closure without help

darwin14:04:51

@thheller thanks, that is definitely useful to know, but in this case I’m afraid it won’t help me, cljs-devtools is a library so I don’t really have control over compiler options, and I don’t want sniff for current settings and muck with user’s configuration in any way

thheller14:04:56

ie if you put your prefs object into a delay and deref it before use

thheller14:04:00

it can be removed

darwin14:04:24

that is basically what I did, but I cannot fix cljs.pprint or stacktrace this way

darwin14:04:37

one solution would be to fork both cljs.pprint and cljs.stacktrace and fix them for my use-case, but that seems dirty

darwin14:04:59

and I don’t know how to work around multi-methods (at this point)

darwin14:04:05

(if my theory is correct)

thheller14:04:19

you can't work around those the way they are implemented

thheller14:04:33

same is true for cljs.spec. none of it is removeable

thheller14:04:23

but I thought you switched to using :preloads for devtools which wouldn't include anything in user code in :advanced?

darwin14:04:12

that is correct, but “switched” is a strong statement 🙂 both methods are supported

darwin14:04:10

cljs-devtools could in theory work in advanced mode (if needed) and should be DCE-ed if required but not used

darwin14:04:37

it is a minor issue though, I got dragged into this because someone opened the issue on github

darwin14:04:28

unfortunately this experience makes me trust less DCE claimed by cljs+closure compilers. It is true that hello-world example compiles to few bytes, but when you include something non-trivial or use any “too-dynamic" core method, you are likely pull in whole cljs.core and bump the size significantly…

thheller14:04:30

the big part of cljs.core are the collections which any reasonable sized app will use

darwin14:04:07

indeed, and also the printing subsystem

thheller14:04:45

yes but overall cljs.core is safe. I worry more about any dependency I introduce, since most of them don't really account for DCE

thheller14:04:25

FWIW it is also why I think :main or :modules are so important ... code that isn't reachable by :main isn't included is the easiest path to ensure DCE

darwin14:04:04

I agree, but speaking about core I think at least cljs.core.PersistentHashMap.fromArrays might be worth looking into, reimplementing it with plain recur could eliminate that unexpected 8-keys threshold trigger.

thheller14:04:31

that also wouldn't be removed by Closure

thheller14:04:00

closure needs to identify something as pure, some calls to new arent't pure

thheller14:04:51

well hmm not really

darwin14:04:02

hmm, this does not seem to be supported by my observations

darwin14:04:13

devtools.defaults.known_features = new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [cljs.core.cst$kw$formatters,cljs.core.cst$kw$hints,cljs.core.cst$kw$async], null); seems to be just fine and does not bloat the output

thheller14:04:56

that is two-fold

thheller14:04:09

if devtools.defaults.known_features isn't removed the var is removed

thheller14:04:41

and after that the vector is broken down

darwin14:04:47

I don’t follow, btw. what about moving into #cljs-dev?

thheller14:04:11

before http://dev.clojure.org/jira/browse/CLJS-1879 {:foo "bar"} would leave a stray cljs.core.str("bar") call in your :advanced output

timgilbert15:04:02

I'm having some trouble with my non-advanced build throwing off errors Uncaught Error: Undefined nameToPath for cljsjs.react_dom

timgilbert15:04:49

...but I've got react-dom in my classpath and I can see the right stuff in its deps.cljs.

% lein deps :tree | grep react
 [cljsjs/react-dom-server "15.5.0-0"]
 [cljsjs/react-dom "15.5.0-0"]
 [cljsjs/react "15.5.0-0"]

juhoteperi15:04:00

@timgilbert cljsjs/react-dom provides cljsjs.react.dom, not cljsjs.react-dom

timgilbert15:04:38

Well, that's the confusing thing, I don't have any code referring to that namespace AFAICT

timgilbert15:04:20

....ah, it might be in a library I'm pulling in

timgilbert15:04:52

Thanks for the tip, will play around more. Mixing cljs with webpack/babel has proved to be an exceedingly bad experience so far

benbot15:04:48

so how is nodejs development with cljs?

timgilbert15:04:50

No idea, I'm just trying to get some ES2015 libraries to work in the browser

benbot15:04:24

babel them down to ESwhateveritisnow

timgilbert15:04:34

I don't necessarily blame clojurescript so much as the fact that the javascript tooling ecosystem is its own unique corner of hell

timgilbert15:04:06

Seriously, it's like "java logging framework" levels of bad

benbot15:04:13

oh I think react does some weird things that makes it not super easy to just drop into clojure

benbot15:04:18

i may be wrong

benbot15:04:32

i’m pretty new to cljs 😕 but I remember reading that

benbot15:04:44

have you tried om or reagent?

timgilbert15:04:18

If you stick to ClojureScript packages, react works really well with everything, it's interop with native JS libraries that's painful

timgilbert15:04:46

Yeah, working on integrating stuff with a large reagent codebase. The cljs bits work really well

benbot15:04:48

also, I think the clojure compiler translates names like foo-bar to foo_bar for require paths

benbot15:04:42

so if your react-dom path is not react_dom that might be it?

timgilbert15:04:09

Yeah, well the problem is it's a transitive dependency out of a native JS library

timgilbert15:04:52

Which itself is written in a thieves' cant of combined ES2015 import statements and commonjs module.exports bits

rinaldi15:04:56

I believe the main reason for that is no standard agreement on a module system

benbot15:04:24

because everything in js is a hack -_-

timgilbert15:04:34

The philosophy seems to be "whatever this mix of tooling will let through with enough tweaking"

benbot15:04:55

what are you trying to do?

timgilbert15:04:57

So a few of my manifold problems are that this code has its own react dependencies, and there's no actual built .js file to just download and package

timgilbert15:04:33

So I'm using webpack/babel to get it into a single ES5 .js file I can stick into a jar and require

benbot15:04:14

@timgilbert what version of react does it use?

timgilbert15:04:26

> Currently supported react version: 15.5.3 ( things break fast when you fly this close to the sun )

benbot15:04:15

try running lein clean or lein cljsbuild clean

timgilbert15:04:22

How true that is! But I'm just trying with 15.5.0, I assume the comment about flying close to the sun is just regular JS bragging

timgilbert15:04:41

Have been doing that, yeah

thheller15:04:49

@timgilbert you want to create a library for cljsjs or for yourself?

timgilbert15:04:20

Well, for myself although once I get it working I will gladly push it to cljsjs

thheller15:04:55

you can just not tell CLJS about the .js file you create, you do not need to import it

timgilbert15:04:04

Another complicating factor is that we need to PRs merged that aren't in the official branch, so I'm working on a private branch at the moment

thheller15:04:15

just include it in your page but make sure it exports js/React

thheller15:04:57

you only need the externs if you want :advanced

timgilbert15:04:34

Well, I do want :advanced, though I'm starting with :none for now just to prove it out

thheller15:04:36

then worry about the externs later ... 😉

benbot15:04:17

is the cljs->js interop story really that bad?

thheller15:04:51

no the JS story is that bad

timgilbert15:04:52

It's more that the module ecosystem in JS is immature

juhoteperi15:04:59

@benbot I'd say the interop is fine. Some libraries are harder to use with Cljs tooling as they are supposed to be used with webpack or such.

timgilbert15:04:21

I agree, yeah

juhoteperi15:04:51

But cljsjs should help and future features like Closure module processing will probably also help with this.

benbot15:04:56

makes sense

thheller15:04:43

just keep the JS stuff in webpack and do not tell the CLJS world about them, just provide some externs

timgilbert15:04:36

That's what I'm trying, yeah, but every build or tweak to my webpack config brings a new, unpleasant surprise

timgilbert15:04:10

Heh, sorry, thanks for letting me vent for moment, channel

thheller15:04:19

you probably need to exclude some dependencies from reagent & co

thheller15:04:30

so they don't pull in the conflicting cljsjs packages

timgilbert15:04:59

Yeah, I've got that part seemingly working at the moment, at least judging from lein deps :tree

thheller16:04:54

maybe that package helps, it does the webpack stuff as well

timgilbert16:04:31

Thanks, I'll take a look at it

johnj16:04:58

Is there someone working on leveraging typescript type definitions for cljs?

dnolen16:04:42

@lockdown- not that I’m aware of, but how would you leverage them?

dnolen16:04:52

it would probably make more sense to convert them to externs for Closure

johnj16:04:16

@dnolen yeah, converting them to externs for closure

juhoteperi16:04:38

@lockdown- I've been looking at it, nothing implemented yet but it seems easy eanough

juhoteperi16:04:19

If/when I get it implemented, it will be integrated into Cljsjs tooling and probably be the recommended way to provide externs for Cljsjs packages

devth17:04:46

does pprint mess up compilation? with :simple I get a runtime error $s$$.substring is not a function that includes pprint in the stacktrace

devth17:04:18

which is weird because with :advanced I get a completely different error Cannot read property 'style' of null

darwin17:04:55

@devth I had once problem with ordering of requires concatenations in :simple mode. My code worked fine under :none and :advanced but in :simple some a function was used before it appeared in the concatenated source file. But this is just an anecdotal experience.

devth17:04:28

ok, thanks.

devth17:04:38

removed all my pprints but the issue remains :thinking_face:

darwin17:04:13

Try to use :pseudo-names true in advanced mode and use devtools to pause on the first error, then inspect the call stack

devth17:04:35

i have it on. currently debugging :simple. i'll try pausing

devth17:04:50

or would fixing :advanced possibly fix simple too?

darwin17:04:33

IMO :advanced is pretty well tested, in :simple mode might be some rare bugs because not many people exercise this mode

devth17:04:47

the stacktrace originates in pprint at:

(def ^{:private true} pprint-array (formatter-out "~<[~;~@{~w~^, ~:_~}~;]~:>"))
btw

devth17:04:40

yeah i'll switch back to advanced and try to figure that out thisisfine

anmonteiro17:04:28

@devth I think I saw your problem before

anmonteiro17:04:36

do you have :pseudo-names true?

anmonteiro17:04:44

it’ll work

anmonteiro17:04:58

I think I opened a ticket at some point

anmonteiro17:04:36

to clarify, what I mean is: your pprint error is related to pseudo-names true

anmonteiro17:04:45

but your style error under advanced doesn’t seem related to it

devth17:04:56

ah, ok. thanks. trying that

benbot17:04:22

Is there something like brave clojure for cljs? I feel like there’s a bunch of things that cljs can do that I just don’t know about

benbot17:04:28

of course… I may just be wrong 🙂

mobileink18:04:33

hi, I’m loading clojurescript from an html import and getting Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened. this is apparently caused by the document.write(...) bits in the main.js generated from cljs (I’m using boot-cljs). the google tells me switching to direct DOM manipulation would work, i.e. getElementById, createElement(‘script’) etc. didn’t find much by searching on “load clojurescript asynchronously” etc. what’s the best way to do this?

dnolen18:04:18

@devth source mapping works OK under :advanced which might at least help you pinpoint the source of the problem - good odds this is an externs issue though

devth18:04:25

i have source maps enabled and confirmed they work for most issues but not my Cannot read property 'style' of null issue, which comes from grommet.js (only under advanced. none works fine).

juhoteperi18:04:42

@mobileink I'm not sure what is a HTML import, but probably the shim JS file generated by :main doesn't support those. You could add script tags the the HTML file manually, but you will need different tags for none optimizations and optimized build.

juhoteperi18:04:07

You might be able to skip over the shim JS file by loading the code in dev like this: https://github.com/clojure/clojurescript/blob/master/samples/hello/hello-dev.html

juhoteperi18:04:18

that is how dev Cljs builds were used before :main option

juhoteperi18:04:33

but this will be a bit hard, as Boot-cljs always enables :main

mobileink18:04:13

thanks. the old-fashioned way might be the way to go. still deciding whether boot-cljs is the way to go in this case.

juhoteperi18:04:52

Possibly not. Figwheel probably has better support "strange environments". But if you provide small example project with Boot-cljs and this problem I can take a look.

mobileink19:04:28

you're on, i'll have something later today.

dnolen18:04:06

@devth like I said externs issue, do you have externs for grommet.js?

dnolen18:04:22

are you sure they are accurate? 🙂

devth18:04:27

nope 🙂

mobileink18:04:43

from the error msg it sounds like its just a synch/asynch thing.

dnolen18:04:25

@devth ok I see grommet is a thing over React, sounds like some how you are passing null props

mobileink18:04:01

@juhoteperi sounds like i may have to just live with synch loading for now. thx.

dnolen18:04:21

@devth hopefully you’re not doing something like trying to pass some custom ClojureScript type to grommet

devth18:04:33

i'm wrapping every grommet component like:

(def anchor
  #?(:cljs (js/React.createFactory (.-Anchor js/grommet))
     :clj factory-shim))

devth18:04:49

then calling those from within om.next components

dnolen18:04:08

sure but what are you passing as props?

dnolen18:04:10

#js literals?

devth18:04:11

yeah, e.g. (box #js {:pad "medium" :flex "grow"} "foo")

dnolen18:04:05

are you ever passing the literal like so

dnolen18:04:16

(box some.top.level/js-value ...)

devth18:04:45

i don't think so but i'd have to audit the source to confirm

devth18:04:56

could pretty quickly reduce it down to a small size though

dnolen18:04:09

@devth well that pattern should be fine

dnolen18:04:37

the thing to look for cases of passing props where you haven’t inlined a literal

dnolen18:04:07

if you have examples of this then it might be possible to spot the issue

devth18:04:28

ok, thanks. i'll start the binary search to see if i can pinpoint something.

reefersleep19:04:09

I'm trying to mix css animation with Reagent. I'm having a particular problem where an element which is growing from 0% to 100% of its width is squishing the element next to it faster than it grows itself - it's pushing whitespace ahead of it, whitespace which disappears once it reaches its full width, for some reason.

reefersleep19:04:06

Anyhow, I wondered if there's a channel for visual or animation design with ClojureScript?

rinaldi01:04:10

Let me know about your findings on the subject? 👍

reefersleep16:04:41

hey @U4SKJCP3K , didn't get any replies re: visual or animation design with ClojureScript. Figured out how to fix my individual problem, though. Maybe we should start a channel? 🙂

rinaldi14:04:47

That would be cool! I just started looking at the possibilities there

reefersleep19:04:15

I find this stuff to be quite tricky.

john20:04:52

what does the symbol* convention usually mean? It usually seems to imply a prototype implementation of a function, right? Are there more specific semantics?

timgilbert20:04:59

@john, One common idiom is when you have (defmacro foo [] ...) it might wind up rewriting the calling code to use a function (defn foo* [] ...)

timgilbert20:04:11

Another one is that dynamic variables often use is as a suffix and prefix, (def ^:dynamic *my-var* ...)

john20:04:22

Yup, I've definitely seen that. And that.

timgilbert20:04:42

Sometime you'll also see the *foo* convention used for just global variables that aren't dynamic, too

john20:04:59

But sometimes the foo that falls foo* is not a macro.

john20:04:17

I believe I've seen that in the wild

Lone Ranger20:04:03

does anyone have any experience using react components with bootstrap here?

Lone Ranger20:04:15

react wrapper / cljs (hopefully obvious)

timgilbert20:04:22

I think I have too, my impression is that it's similar to how you might have a function a which calls another function a' in haskell, where the a' function has a less convenient interface or other implementation details

Lone Ranger20:04:16

writing what should be a fairly simple component

(defn panel [title]
  (html [:div {:id    "ticker-panel"
               :class "container"}
         [:button {:type "button"
                   :class "btn btn-info"
                   :data-toggle "collapse"
                   :data-target "#ticker"}
          title]
         [:div {:id "ticker"
                :class "collapse"}
          "test"]]))
works fine problem is that panel won't stay open

Lone Ranger20:04:40

closes a second after it's called

Lone Ranger20:04:44

it has something to do with whenever the dom re-renders in response to some other event the panel closes

Lone Ranger20:04:07

eh I suppose that's to be expected

john23:04:37

I'm trying to def a fn into a namespace at runtime, with a name from a string received elsewhere, so that other functions can call the function by the symbol name. I've tried (aset js/my.newfns (str newname) #(some-fn %)) which appears to work at the repl, but it doesn't appear to be taking effect during normal execution (outside the repl)

john23:04:34

I suppose I could specify on a string and implement Named?

john23:04:27

and then just do a def on the named string?

jr23:04:51

why def them in a namespace? you could store them in a map

john23:04:20

@jr it's a library for distributed objects and I'm trying to provide the illusion of locality for the user. Things are working, but getting the new objects into the namespace puts a bow on it.

john23:04:13

Figured it out. I had dashes in the string name.

john23:04:49

it's working!

john23:04:15

\/mad scientist cackle