Fork me on GitHub
#clojurescript
<
2015-09-15
>
danielcompton05:09:54

In CLJS-324 dnolen said: "goog.string.format defies advanced optimization”. What does that mean specifically? Does it break under advanced optimization or is just not able to be optimized? http://dev.clojure.org/jira/browse/CLJS-324?focusedCommentId=31935&amp;page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-31935

estsauver05:09:24

Hey @grav, did you file that ticket?

grav06:09:46

@troyclevenger: Yup, that is the error. I did find that issue, so the error is resolved already. It was more a question about stopping the compilation on errors like that.

grav06:09:32

@estsauver: No I did not, it seemed I’m not the first having the issue, so I though a ticket had already been filed

grav06:09:00

Also I’m in doubt as to where the error actually is, whether it’s in omtools, the google closure compiler, or cljs

estsauver06:09:21

I think David Nolen was implying it was prismatic schema.

acron08:09:43

Has anyone experienced this error whilst trying to write macros for cljs? java.lang.IllegalArgumentException: No method in multimethod 'emit-constant' for dispatch value

acron08:09:55

My macro is just (defmacro my-macro! [] (cljs.core/fn [] "foo"))

acron08:09:41

Never mind - forgot the quote!

jrychter09:09:12

Hmm. That destructuring problem reported yesterday by @troyclevenger looks slightly similar to the problem reported here https://github.com/r0man/sablono/issues/67 — but just slightly. In both cases it's about map destructuring. @troyclevenger, when you wrote "If I change it to a let statement it works", did you mean destructuring in a let form inside defcomponent?

dominicm10:09:20

I think I might be using macroexpand-1 wrong, but I'm not sure...

dominicm10:09:54

http://stackoverflow.com/a/17495553/1481316 copy pasting this, into mier's browser repl, results in an error:

dominicm10:09:04

#error {:message "cljs.core.find_macros_ns.call(...) is null", :data {:tag :cljs/analysis-error}, :cause #object[TypeError TypeError: cljs.core.find_macros_ns.call(...) is null]}

dominicm10:09:20

And I have absolutely no idea what is going on.

dominicm10:09:44

I was trying to run it in a .cljs file, as opposed to a .clj file.

dominicm10:09:52

Is there anybody using garden on any projects they'd be happy for me to look at? Trying to find some good examples of how to compose my css.

dnolen11:09:01

@danielcompton: it cannot be optimized away. Google Closure doesn’t even recommend it’s usage.

danielcompton11:09:33

@dnolen: what’s the recommended alternative?

dnolen11:09:36

@danielcompton: I just wouldn’t bother. If you absolutely must you have cljs.pprint.

dnolen11:09:57

@danielcompton: also if you don’t care about DCE issue, then use goog.string.format

dnolen11:09:07

we’re just never going to supply it from cljs.core

dnolen11:09:13

Dead Code Elimination

danielcompton11:09:02

So (gstring/format "site: %s user: %s time: %s" site username time) should just be rewritten as (str "site: " site " user: " username " time: " time)?

dnolen11:09:14

@dominicm: you can’t invoke macroexpand from a cljs source file.

dnolen11:09:45

@danielcompton: that’s not what I said above.

dnolen11:09:58

use goog.string.format if it’s convenient

dominicm11:09:30

@dnolen: Yeah, I eventually figured it out. It was a combination of misunderstanding/not reading the docs, and thinking that I could define a macro in the same file, and all would be fine.

dominicm11:09:22

Thanks though, I always appreciate how active you are in here simple_smile

dnolen11:09:04

@dominicm: yeah ClojureScript has never supported inline macros, and that's unlikely to ever change due to code size issues (bootstrapped CLJS is 300K gzipped vs. 20K for a minimal CLJS app otherwise).

dnolen11:09:47

also there are portability issues we don’t want to create even in the bootstrapped case.

danielcompton11:09:44

@dnolen: gotcha, so it just has costs to usage, and is generally avoided? Thanks for the feedback.

dominicm11:09:49

@dnolen: Yeah, it's understandable. I eventually stumbled across that. This is my first ever venture with Cljs, coming from playing with lots of Clj, so still getting my bearings on what's different.

troyclevenger11:09:30

@jrychter I meant changing the loop to a let. There seemed to be something between the loop bindings and the reify bindings that ws causing the problem.

dnolen12:09:04

not bad for a Lisp that compiles to JavaScript, ClojureScript broke 5000 Github stars https://github.com/clojure/clojurescript

rauh12:09:21

Congratulations to all involved!

martintrojer12:09:50

should with-redefs on a fn in a library I use work as expected in CLJS? (used during tests)

dnolen12:09:18

@martintrojer: it depends on what you mean by “work as expected"

dnolen12:09:24

ClojureScript doesn’t have vars

martintrojer12:09:50

well then, I guess that answers the question simple_smile I’m trying to stub out cljs-http during test runs.

martintrojer12:09:02

I guess I have to write wrappers myself?

dnolen12:09:34

I suspect your tests are async?

dnolen12:09:46

JS has no threads, and ClojureScript has no bound-fn

martintrojer12:09:41

well, I mean, cljs-http is all core.async-ed up. But I guess wrapper-fn’s and a dynamic var would solve my problem

dnolen12:09:49

@martintrojer: core.async doesn’t solve the no threads no bound-fn issue

dnolen12:09:05

if you’re using cljs.test you can use the async test support and enforced serial execution to ensure that your with-redefs hold for the tests you care about

martintrojer12:09:06

yeah, the single-threaded-ness is a bit of a mind bender here since all the backed up go blocks doesn’t run until after the tests.

martintrojer12:09:18

(where the http access actually happens)

dnolen13:09:23

@martintrojer: I dog-fooded cljs.test on core.async so there are OK examples there

dnolen13:09:43

fixtures support async test setup / tear down

martintrojer13:09:18

cool, I’ve got something working over here so I’m quite happy simple_smile

martintrojer13:09:37

OMG, the penny finally dropped on the cljs.test async stuff. That’s is just what I needed! Thanks @dnolen!

dnolen13:09:00

@martintrojer: heh that’s what I was saying simple_smile

martintrojer13:09:05

sorry, I’m slow

dnolen13:09:38

well clojure.test doesn’t have this stuff, it’s novel to cljs.test

danielgrosse14:09:49

Im actually struggling with loading an svg and rendering it with reagent completely in clojurescript. Is this possible at all?

danielgrosse14:09:10

I want to recreate the svg as a reagant structure, so I could change it in the browser.

martintrojer15:09:33

@dnolen phantomJS seems to crash when the (async done …) is the last value in a deftest (like the docs says).

martintrojer15:09:39

Its fine in chrome

martintrojer15:09:19

Making the (async done …) block not the last value in deftest makes phantom happy, but the any (is …) assertions is ignored

dnolen15:09:39

@martintrojer: don't know or want to know anything about phantomjs sorry.

dnolen15:09:05

@martintrojer: have you tried slimerjs?

dnolen15:09:22

my uninformed impression is that it’s just better than phantomjs

dnolen16:09:18

works best in Chrome

shaunlebron16:09:55

@dnolen: simple_smile, was fun building a game again!

shaunlebron16:09:29

@dominicm: @dnolen: I might be misinterpreting what you guys are saying, but (macroexpand ‘(cond :else :foo)) works fine in a cljs source file

shaunlebron16:09:36

you might be referring to limitations mfikes talked about here: http://blog.fikesfarm.com/posts/2015-09-05-runtime-macroexpand.html

dnolen16:09:59

@shaunlebron: right but it’s not the macroexpand that people expect from Clojure, not a function

dnolen16:09:56

it exists primarily as a simple REPL convenience, little else

shaunlebron16:09:35

@dnolen: I’ll make note of that in the docs, thanks

dnolen16:09:21

@shaunlebron: it’s possible for bootstrapped ClojureScript to do real macroexpand but the details would need to be sorted out, @mfikes wrote about this a bit

curtosis17:09:25

I swear this came up in conversation a while back, but cant' find it ... I can't seem to get a repeatable build out of lein ring ubwerar. Sometimes it's grabbing the prod cljs, sometimes it's getting the dev (which looks for a missing goog). Sound familiar to anyone?

bensu17:09:32

@martintrojer: can you post the script that is running the tests? It is not trivial to get it right.

martintrojer18:09:23

@bensu: https://gist.github.com/martintrojer/9a8e78126063705fabdb Please note that this setup is fine (running on circleci) for everything but the cljs.test.async macro which crashes it.

martintrojer18:09:11

the cljs.test.async stuff works perfectly in Chrome (via figwheel)

dnolen18:09:11

@curtosis your description of the issue is a bit unclear, do you mean production js? You don’t generally deploy cljs to production.

afhammad18:09:25

@curtosis, @dnolen: i’m assuming you mean prod env folder cljs (similar to chestnut env setup)?

curtosis18:09:48

@afhammad, @dnolen : yes, I mean the prod env folder profile (e.g., :advancedoptimizations)

dnolen18:09:06

ah, k can’t offer any more info about that myself

mitchelkuijpers18:09:38

@curtosis: Alwasy do a clean before running the uberwar task should fix it

curtosis18:09:44

what seems to be happening is that the uberjar profile isn't being properly invoked.

curtosis18:09:28

What does seem to work so far is to run lein uberjar first, then lein ring uberwar

curtosis18:09:23

which, apart from being extra (probably-duplicative) work, hints that something's not right in the uberwar task.

bensu18:09:27

@martintrojer: I replied directly on the gist to reference the code, I hope it helps.

bensu19:09:29

@curtosis: not sure but maybe try lein with-profile +uberjar ring uberwar

curtosis19:09:28

It looks ok (the WAR doesn't include the js/goog/ directory like the dev profile does)

curtosis19:09:28

though the ubjerjar task gives a nice "compiling app.js from (src-cljs/app.cljs env/prod.cljs)" message

curtosis19:09:42

(guessing on the message, it was a while back) but it doesn’t appear in the with-profile version of ring uberwar.

curtosis19:09:50

otoh, that may just be a difference in how the cljsbuild step is called by uberjar vs ring uberwar.

jaen19:09:52

Hmm... I'm stumped with my module thing. A non-require lib using React like reagent works, yet react devtools don't seem to : | And it's a kinda broken trade to get modules working sacrificing debugability in the process : X

jaen19:09:00

Anyone ever tried debugging react devtools?

bensu19:09:23

@curtosis: I'm sorry but I didn't understood you response simple_smile Did it work or is there still a problem?

bensu19:09:25

@jaen: what doesn't work? What I've found about react dev tools is that if your dependency tree brings in both dev tools and sans dev tools, google closure uses both and there is an externs clash ("ERROR: externs duplicated"). Is that the problem?

jaen19:09:42

@bensu: hm, not sure how the dependency tree can bring in react dev tools, since they are a chrome extension not a jar; and besides right now I'm wgetting all dependencies by hand, so it can't be that - you can't really bring in unwanted dependencies if there's no dependecy resolution going on ; d

bensu19:09:05

@jaen: sorry! I misunderstood, react-addons vs react-devtools

jaen19:09:41

No problem ; d

curtosis19:09:28

@bensu I believe the with-profile option worked.

curtosis19:09:48

(I'm hesitant to push a new war to the server while I have people testing my previous successful build)

bensu19:09:53

@curtosis: cool. let us know if there are any problems when you push it.

jaen19:09:12

Hahahah. What the actuall hell. It turns out React devtools are now available for Firefox. So I install them, open my test project and lo and behold, the devtools work o_0

bensu19:09:17

@jaen do you have the beta version of the devtools for Chrome? (there was breakage at some point which might be related)

jaen19:09:41

Both are the new React-based version

jaen19:09:09

Let's see if some way to dig up the old extension to check

jaen19:09:46

That said React' or Reagent's websites don't have that problem, just my test project

jaen19:09:58

So it might be me doing something wrong

curtosis19:09:23

@bensu thanks, will do!

jaen19:09:30

I'll be angry if it turns out that's because of file:// URL '

jaen19:09:42

It was xD

jaen19:09:51

Sorry for the noise

bensu19:09:08

@jaen hahaha I was about to recommend python -m SimpleHTTPServer 8000

jaen19:09:26

Yeah, that's exactly what I've done just now ; d

jaen19:09:10

I thought that maybe my module rewriting shenanigans are messing something up, but no it turned out to be simpler xD

curtosis20:09:46

@bensu: turns out I had to redeploy anyway, after the jvm crashed and forced a reboot. looks good! thanks again

bhauman21:09:13

@venantius: you mentioned middleware and the cljs-repl. Just wanted to let you know that you can add functionality through the ClojureScript repl :special-fns option which is much more direct. of course you have to invoke your own REPL.

bhauman21:09:37

wow I could have said that better

mfikes21:09:45

@dnolen Cool. We need a savvy Android dev to get JSC going with a REPL. simple_smile

dnolen21:09:21

@mfikes: ah right nobody did the Ambly bit yet, just the bootstrap bit simple_smile

mfikes21:09:46

@dnolen: Yeah… my pinball wizardy falls short on that platform. 💋

mfikes21:09:00

hrm… odd icon typo

bhauman21:09:22

There has been a steady uptick in the number of times my ClojureScript videos are being watched. I'd like to conclude that interest in CLJS is growing. Don't want to speak too early but its an interesting phenomena.

bhauman21:09:58

It's more of a tide and doesn't seem to be attached to any single event

bensu21:09:29

@mfikes: if I didn't have a startup/life-consuming-job I would offer as the andriod dev 😞 very excited about this.

mfikes21:09:29

@bensu: yeah. :) one nice thing is JavaScriptCore is very easy to build on Ubuntu. Makes me think Android is within reach.

jaen22:09:28

@dnolen: if I understand correctly goog.provide('some.namespace') creating a global object named some.namespace is part of how GClosure modules function and it's neither possible nor desirable to disable that, yes?

dnolen22:09:51

@jaen: that’s exactly right

jaen22:09:48

Hah, then I need to figure how to deal with that - since if I have goog.provide('React') that's gonna conflict with Reagent expecting js/React to be well... React, not GClosure namespace object.

jaen22:09:02

I guess I could fork reagent and change that...

dnolen22:09:15

@jaen: brining in React twice would create lot of problems anyway

dnolen22:09:43

and yes should this new way work in the future, people will want to change how they load/interact with React

bensu22:09:03

@dnolen: @jaen: I'm curious, doesn't the var React = goog.provide('React') contain both goog's properties and all of React's properties?

jaen22:09:10

I don't think goog.provide returns anything

jaen22:09:22

GClosure module loading seems fully side-effectful

jaen22:09:39

But then again I only dabble in that for a couple of days

bensu22:09:51

@jaen, I mean the object that is left by goog.provide('React').

jaen22:09:02

So, I named the react/react.js module React, react/lib/ReactElement.js - React/ReactElement and I end up with a skeleton of GClosure module namespaces (that is, properties are there, but are empty) and nothing that comes from React

jaen22:09:06

At least as far as I can see

jaen22:09:16

So it gets overwritten it seems

jaen22:09:48

And if I'm looking at goog.exportPath_ correctly then it seems it doesn't merge what's already there, just overwrites with {}

dnolen22:09:17

@bensu not true for how provide works

dnolen22:09:23

provide doesn’t return anything

dnolen22:09:57

require and provide are just a fiction, for runtime dev they aren’t even really used, you must provide deps.js for this reason

dnolen22:09:12

at compile time they are used to put everything in dep order

bensu22:09:17

@dnolen: yeah, that is what @jaen said. I didn't know it wasn't used during dev. so it's only a hint to the compiler then?

dnolen22:09:22

@jaen: as I said, for runtime load you must provide deps.js which has all the necessary goog.addDependency calls

dnolen22:09:13

this is the reason :none is so weird w/o :main. Because you need a script tag that calls goog.require before you do anything

dnolen22:09:34

this uses deps.js to load everything in order synchronously in the browser via document.write

bensu22:09:29

@dnolen: I feel like you've explained this before and I forgot about it 😞

jaen22:09:07

Right. Though this is all in Clojurescript's domain; I should not be mucking with that if I can just provide it with sensible module names.

jaen22:09:11

(at least, I assume so)

dnolen22:09:57

@jaen Google Closure won't clobber existing namespaces

dnolen22:09:12

if foo.bar exists and you load foo.bar.baz, foo.bar will be left alone

dnolen22:09:22

except that it will have a new property baz

dnolen22:09:28

that could potentially be clobbered

bensu22:09:10

@jaen: looking at the generated file out/lib/react/React.js it seems like the big React object is being held under React$$module$react$lib$React

bensu22:09:20

line 8 in the file

jaen22:09:17

Hm, then that's interesting, because when I did what I described (that is named a module React) it didn't exactly merge (reagent couldn't find createClass for example). Unless I'm misunderstanding what I've done.

jaen22:09:22

@bensu: yeah, GClosure renames all vars to that dollar-y casing because as far as I understand all vars in GClosure are effectively global.

bensu22:09:29

@jaen and then assigned to react.lib.React in line 13, the last line

jaen22:09:33

And the rewrite then assigns ...

jaen22:09:38

Yes, wanted to say exatly that

jaen22:09:00

As far as I udnerstand that's the desired behaviour of what GClosure guys implemented for CommonJS translation

dnolen22:09:16

@jaen well Reagent is introducing yet another variable, I would remove that, unless you already sure it works w/o it and you’re just trying to solve why Reagent breaks in this scenario

jaen22:09:33

And it didn't clash for them because they also mangled module names with dollars

dnolen22:09:47

and yes Reagent will break if it assumes it can read global libs

dnolen22:09:23

but also React may do something weird like write a global if it’s loaded into a browser

jaen22:09:50

But then you have to require them with same names and I don't think people will fancy doing (:require module$react$addons) so I changed it to translate module name into (:require react.addons) instead (more or less)

venantius22:09:59

@bhauman: I’ll take a look at that

jaen22:09:03

I don't think React does that, that is writing a global

jaen22:09:16

You had to write one on your own for devtools at some point

dnolen22:09:28

@jaen so I wouldn’t mess with that part of it yet. I would stick w/ mangled names for now.

dnolen22:09:38

easy to add compiler support to make it more sensible

dnolen22:09:54

(:require [module$react$addons :as ReactAddons])

jaen22:09:12

That already worked so I wanted to make it nicer

jaen22:09:39

But I'm too dumb to hack on the compiler so I did it by having dotted module names

jaen22:09:51

But I suppose if this could get some compiler support

jaen22:09:55

Then it would be way easier

dnolen22:09:19

yeah how to make :requires nice is a finishing touch IMO simple_smile

bensu22:09:41

@jaen nobody is too dumb to hack on the compiler. specially with @dnolen's patience

jaen22:09:55

Honestly? I wanted to try doing it in the compiler but I couldn't exactly grok how to put it inside, hence how I did it.

jaen22:09:56

It's one big ugly hack, but at least it has the positive effect of possibly motivating people who can actually code that ; d

bensu22:09:13

how are you adding the reagent jar to the path?

bensu22:09:21

with lein?

jaen22:09:11

No lein, no boot, just one big bash script

jaen22:09:15

so I basically do

jaen22:09:24

java -cp deps/* clojure.main build.clj

jaen22:09:27

and run with it.

jaen22:09:49

(okay, modulo actually joining deps/* with colons)

bensu22:09:56

ok, so you added the reagent.jar to deps

bensu22:09:22

(I ask since I'm reading https://github.com/jaen/custom-module-loaders where I can't find reagent)

jaen22:09:28

Ah, right

jaen22:09:38

I didn't push that yet

bensu22:09:52

did you also add cljsjs.react to deps?

jaen22:09:03

Nope, I just added a stub empty ns

bensu22:09:06

Interesting. when you are ready, push it and leave a comment with the empty react problem. I'd love to try again tomorrow

bensu22:09:33

It's late in my timezone

jaen22:09:32

Sure, no problem

jaen22:09:11

To be honest it's 0100 hours here, so I should be sleeping and not hacking on that

jaen22:09:12

But oh well

bensu22:09:10

hahaha we are on the same timezone then. you should be definitely hacking on that. I just have a meeting in the morning. bye!

jaen23:09:38

@dnolen: yeah, I'm starting to wonder if being able to do React.ReactElement is too much of a convenience in a wrong place. The interactions with goog.provide get vexing. I suppose it would make sense to keep generating module names like module$react$lib$ReactElement for starters and when that's done and in compiler, only then start figuring out how to make the requires nicer looking.

jaen23:09:30

It could just be a desugaring pass then - if no React.ReactElement namespace is found then it desugars into module$react$lib$ReactElement (there would have to be some way to have it keep track of how dotted names correspond to dolar names) and tries again and if that does not succeed as well, then it's a require error.

jaen23:09:54

But I'm afraid I wouldn't know my way around the compiler well enough to be able to write something like that.

jaen23:09:56

@bensu: feel free to take a look at it tomorrow if you want - https://github.com/jaen/custom-module-loaders/tree/react-simple - but as per what I said to dnolen just now I start realising this is probably a dead end and retaining mangled module names and then adding some desugaring to the ns macro and/or compiler on top of that would be a more sensible way to go. Not sure if I'll be up to par to implement that though (probably not). But none the less this exploration was a good use of time it at least uncovered some issues such translation will inevitably face and how to not solve them ; d