Fork me on GitHub
#clojure-uk
<
2017-11-28
>
thomas08:11:19

moin moin morning

guy08:11:16

it can? what else could it be?

maleghast09:11:42

@guy - A Roman Salute (sic. Nazi Salute)

guy10:11:01

oh wow!! i didn’t even see that at all.

maleghast09:11:58

I’m with you @otfrom - it’s a genuine shame 😞

maleghast09:11:28

@otfrom we can always go with \o/ (not drowning)

maleghast09:11:37

Morning everyone.

maleghast09:11:09

So, gathered friends… I have managed to “do the thing” in development mode, but when I use advanced compilation my app chucks a gnomic JS error, and my GeoJSON polygons don’t render… They render fine locally in dev mode, but not remotely in prod mode… If you had this problem, where would you start, as I am stumped… (this app is my first serious foray into ClojureScript and if nothing else it has been fun, rewarding and also taught me how little I know about JavaScript)

danielneal09:11:30

I highly recommend cljs-oops. https://github.com/binaryage/cljs-oops. It's taken away all my externs woes

mccraigmccraig09:11:51

externs are the devil's work

thomas09:11:52

they are indeed @mccraigmccraig , but weren't some of the latest versions of cljs supposed to help out here?

danm09:11:11

@otfrom How about the Elite style salute? o7

danielneal09:11:23

I always forget about advanced compilation munging names, and every time something crops up it takes a few hours before I make the connection between "oh - this is only happening in staging/production and only staging/production use advanced compilation"

bronsa09:11:11

@danieleneal next time you have a complain here and we'll tell you it's advanced compilation's fault

danielneal09:11:21

@maleghast I would personally import cljs-oops and go through all the interop calls (.-init some-thing) and replace them with ocall/`oget`

danielneal09:11:22

@bronsa can you somehow 'detect' when I am having an advanced compilation problem and then at me. I might not think to ask for help

bronsa09:11:36

I'll make an effort but no guarantees

maleghast09:11:58

@danieleneal - Er, thanks… I have NO IDEA what you are talking about, but I am reasonably confident that I will once I’ve read the link(s) and had a think… 🙂

otfrom09:11:31

@carr0t I just wanted to wave

mccraigmccraig09:11:52

lack of guarantees - the eternal problem with dynlangs

maleghast09:11:48

@danieleneal - From a quick speed read, I am not getting a compile warning anywhere, just a JS error after compilation

danielneal09:11:07

@maleghast - yes, that sounds like an advanced optimizations issue

maleghast09:11:23

Oh 😞 That’s even worse…

maleghast09:11:20

I mean, I could__ turn off the optimisations in production - the app is going to be a non-public app, that will change rarely, so JS would be cached…

danielneal09:11:25

So - in advanced mode, the google closure minifies function names. However, it might minify name that are defined by third party libraries, so typically you provide "externs" to tell it not to minify those names

maleghast09:11:36

But clearly I want all the toys to work…

danielneal09:11:38

This is tedious work

maleghast09:11:06

Yeah, I looked into hand-rolling externs for something lately and I decided I’d rather write my own code.

maleghast09:11:08

(which I did)

maleghast09:11:40

Unfortunately this is on LeafletJS and I don’t want to re-write all of that…

bronsa09:11:55

cljs has externs inference now

maleghast09:11:05

I am expecting that the extern for L.geoJSON is not properly doing that…

maleghast09:11:22

(in that I have LeafletJS from CLJSJS and there are externs bundled with it)

danielneal10:11:18

Yeah - the problem with cljsjs is that the externs can be incomplete or unspecified

dominicm10:11:30

@maleghast You could make a PR to the cljsjs team to update their externs 🙂

maleghast10:11:47

I will have to dig into it…

maleghast10:11:18

In the short term I might actually turn off the advanced compilation - it’s really a nice-to-have for this use…

danielneal10:11:20

The other options are 1) use the new externs inference - I don't have any experience with this but @bronsa might know more 2) use cljs-oops -which is a macro which somehow expands to a call that will work safely under advanced optimizations - I do have experience with this and it works like a charm

dominicm10:11:15

cljs-oops doesn't allow things to be optimized away, to my understanding. Which is why I've avoided it.

maleghast10:11:51

OK, well I will turn off advanced compilation, for now, and I will start my investigation(s) with the externs for LeafletJS that I am currently using. If that does not help me out then I’ll start thinking about the other options… It does seem likely that there is something missing from the externs that CLJSJS are bundling with LeafletJS.

bronsa11:11:35

@danieleneal it's advanced compilation's fault

minimal12:11:24

@maleghast I had to add some more methods to the leaflet externs when I was getting adv comp working

maleghast12:11:32

@minimal - Thanks, that’s good to know… In that I may have to do the same 😉

thomas12:11:44

if I remember correctly there was a website that helps you create externs.

thomas12:11:02

and check in the #cljsjs channel as well.

maleghast12:11:49

@thomas - There is, yes… I am using the cljsjs package for LeafletJS and the externs look to me (but I don’t really know what I am looking for) to be correct vis à vis the bit of Leaflet that I had not used before that seems to be failing in advanced compilation.

maleghast12:11:00

I am VERY confused about the whole thing, quite frankly.

thomas12:11:20

I tried to get the Paho JS package into cljsjs two years ago... and one of the CLJSJS experts had a look at it in the end and came to the conclusion that it was impossible to use the optimised Paho JS build. (so it worked with advanced CLJS compilation, just not with the optimised JS package)

thomas12:11:34

and yes, it is very confusing

mccraigmccraig12:11:00

@maleghast try cljs-oops. externs might be better than they used to be, but cljs-oops is simple and - most importantly - local. i.e you don't have to change something in some far-flung file or files to fix your invocation

maleghast12:11:38

@thomas - Thanks, I am glad it’s not just me… 😉

maleghast12:11:53

@mccraigmccraig - OK, will do… Do I have to integrate it with EVERYTHING I do or can I start by using it to wrap up the thing I am pretty sure is the problem (everything else I am doing with Leaflet works seamlessly in advanced compilation, it’s just drawing country boundaries with GeoJSON)

mccraigmccraig12:11:55

you can just use it for the problematic things

maleghast12:11:42

OK, I will have a delve - thanks 🙂

maleghast13:11:31

Or I willk have a delve when I’ve finished doing minor updates to the completed work and adding in functionality that was previously not required for this iteration… 😞

maleghast16:11:10

@mccraigmccraig - OK, so I got back from the school run, answered a bunch of emails and then I tried to read the cljs-oops README.md… I have no idea how to use this… I KNOW that I am being dumb and / or that my general ignorance of JavaScript (4 years since I really did ANY, and even then I was a very light user) is in play here, but honestly the README reads, to me, like stereo instructions… Do you or indeed does anyone else have an example of wrapping up a call to a well-established JS library with this, as the examples seem to be about accessing data in data structures?

mccraigmccraig16:11:50

@maleghast (ocall <js-obj> "method-name" arg1 arg2 arg3)

maleghast16:11:25

where <js-obj> == L.geoJSON (for example) ?

maleghast17:11:44

OK, that helps, thanks! (I may email the maintainer and suggest that he puts something like that into the README.md - that makes perfect sense to me, but barely word-one of that README did… (all comments about that being my deficiency notwithstanding)

mccraigmccraig17:11:22

yeah, it should have some ocall and oapply examples as well as the oget and oset! examples

mccraigmccraig17:11:56

you can get him on slack though @maleghast, no need for email

maleghast17:11:41

Cheers, might well - I want to see if I can get it working first so that I am saying “Love your library, really helped me get this thing done, but…“, rather than the alternative… 😉

mccraigmccraig17:11:17

i just moved a bunch of stuff which was giving me advanced-compilation gyp to cljs-oops @maleghast - all went very smoothly

maleghast17:11:54

That’s good to hear 🙂

maleghast17:11:34

I need to do some tinkering, clearly, as I’ve just wrapped up the call that I am 90% certain that was the problem and it stopped working in dev mode and I have errors…

maleghast17:11:57

Ooh, hold on, I have a #js literal as one of the params that I am trying to plug into ocall… That’s not going to work, right?

maleghast17:11:56

Pulling it out didn’t really help…

mccraigmccraig17:11:04

@maleghast a #js literal is probably fine as a param to a js fn, as long as it's the right sort of #js literal

maleghast17:11:04

Got it working! (in dev mode)

maleghast17:11:45

needed to be:

(ocall js/L "geoJSON" {geoJSON here} {styles here})

maleghast17:11:05

Now to see if it works in prod with advanced compilation 🙂

dominicm17:11:05

What are the costs of cljs-oops?

mccraigmccraig17:11:39

it's a macro which assembles an advanced-compilation safe deref of a js object reference, using goog.object/get @dominicm

dominicm17:11:43

@mccraigmccraig I don't understand how that works? Does it mean that Google closure can't trim out unnecessary parts of the js?

dominicm17:11:51

Dead code elimination

maleghast17:11:10

I am glad that @dominicm doesn’t understand, ’cos I am bloody mystified! 😉

mccraigmccraig17:11:27

it's for calling libs outside of closure's purview

maleghast17:11:08

Well, that counts as an EPIC FAIL

mccraigmccraig17:11:26

it doesn't affect closure's operation, it just prevents closure from bollocking up your code by munging names you don't want munged

maleghast17:11:46

Failed to load resource: the server responded with a status of 404 (Not Found)
base.js:1357 Uncaught Error: Undefined nameToPath for goog.string
    at visitNode (base.js:1357)
    at visitNode (base.js:1355)
    at Object.goog.writeScripts_ (base.js:1369)
    at Object.goog.require (base.js:706)
    at dashboard:23
base.js:1357 Uncaught Error: Undefined nameToPath for goog.string
    at visitNode (base.js:1357)
    at visitNode (base.js:1355)
    at visitNode (base.js:1355)
    at visitNode (base.js:1355)
    at visitNode (base.js:1355)
    at visitNode (base.js:1355)
    at Object.goog.writeScripts_ (base.js:1369)
    at Object.goog.require (base.js:706)
    at dashboard:23

maleghast17:11:10

This is what happened when I tried to run the same code having done advanced compilation.

maleghast17:11:33

(I have no idea what ANY of that ^^ means)

maleghast17:11:51

(oh yeah, and the app just completely fails to load, clearly)

maleghast17:11:48

@mccraigmccraig - If I understand what you are saying, it’s like making an extern exception for things that you call, but doing it inside your own code?

dominicm17:11:07

@mccraigmccraig but I'm not sure that's the full situation. React is managed by closure, but it creates window.React. In this case, I'm not sure how @maleghast is bringing in L on this case, but oops is discussed as an alternative to externs in their entirety.

maleghast17:11:12

instead of for the entire library, and not in a separate externs file

mccraigmccraig17:11:11

right, it looks up object properties by their string name, which sidesteps advanced compilation munging

mccraigmccraig17:11:41

@dominicm there is no problem mixing oops and externs... oops doesn't affect closure or externs

maleghast17:11:20

@mccraigmccraig - does that mean I am missing a vital component / library, as that error says something about “Undefined nameToPath for goog.string” or does it mean that google Closure can’t find “geoJSON” as a method of “L”? I mean, even though it worked in dev-mode have I perhaps misunderstood how I need to refer to the various bits of the call inside the (ocall …) form in my code..?

maleghast17:11:59

I am doing this:

(ocall
            js/L
            "geoJSON"
            (clj->js (get-in borders [bordername :coords]))
            #js {:style (get-border-style (get-in borders [bordername :color]))})

maleghast17:11:39

it occurs to me that I might be wanting just “L”, rather than “js/L” or I might be needing something else entirely as the js/L thing is all wrapped up in the cljsjs bundle / package that I am using for all the other Leaflet calls and perhaps I need to use something else..?

mccraigmccraig17:11:50

that call looks reasonable... try replacing js/L with (oget js/window "L") and see where that gets you

maleghast17:11:02

Right-oh, one sec…

maleghast18:11:16

It works on dev-mode, so trying it on Prod now…

maleghast18:11:45

Splendid! That works VERY well 🙂

maleghast18:11:11

Thx very much 🙂

maleghast18:11:34

That last suggestion makes a lot of sense in hindsight, but I really don’t think that I would have got there on my own.

maleghast18:11:35

I am definitely going to reach out to the maintainer about an addition to the README.md to explain how to do this kind of thing.

maleghast18:11:12

(which I can__ now couch in “Your library is awesomes, but…“, rather than “I can’t make your library work” 😉 )

mccraigmccraig19:11:15

@maleghast you should generally bet on advanced compilation munging all symbols apart from well-known things like js/window and js/document and things declared in extern files... so js/L will get munged like any other symbol

maleghast19:11:22

@mccraigmccraig - Yeah, I’m starting to see that... The externs for LeafletJS are, as far as I can tell, comprehensive so I am not going to retro fit cljs-oops to everything that is already working. Having said that, I am going to bear it in mind going forward!

maleghast19:11:39

Yeah, I thought so too, but it was definitely not working...

mccraigmccraig19:11:58

the extern is wrong

mccraigmccraig19:11:04

it should be L.geoJSON

maleghast19:11:27

Ah Yeah, that’s a valid “thing” in LeafletJS if you want to create a custom object

maleghast19:11:52

You use L.GeoJSON with “new” and “extend”

mccraigmccraig19:11:22

ah, yeah, ok - in which case there is a missing extern for L.geoJSON

maleghast19:11:29

I think it’s more that there is no extern for the convenience function “geoJSON”

maleghast19:11:20

Still my code works!

mccraigmccraig19:11:44

it's been a while since i did any leaflet - it was fun

maleghast19:11:45

I will open an issue on CLJSJS after my kids are in bed to let the package maintainer know

maleghast19:11:06

Interesting definition of “fun” you have...

maleghast19:11:37

I mean, satisfying once I got it working, but I did not get a great deal other than pain out of the journey ;-)

mccraigmccraig19:11:07

i did this - http://techmap.london/ and this http://www.startuphubs.eu/ - i definitely remember having fun along the way 😬

mccraigmccraig19:11:16

stuff like producing the o/s boundary paths at different resolutions and dynamically loading and displaying appropriate resolution paths as you pan and zoom was definitely fun

maleghast19:11:52

Well, I am glad that it was fun - I might__ have been going for comedy ^^ I have enjoyed my dalliance with leaflet so far… 😉

maleghast19:11:30

Those are some cool maps, @mccraigmccraig - Is that Clojure / Clojurescript underneath?

mccraigmccraig19:11:44

yep, clojurescript, clojure, elasticsearch & postGIS

maleghast20:11:07

Ah, these were the projects that got you doing PostGIS to LeafletJS projection transformations..?

maleghast20:11:52

I was explaining that to my CEO - he glazed over rather…

yogidevbear20:11:58

So in mumble mumble years of living on this rock we call home, I have never walked into a glass sliding door. That is until today when I managed to do it in spectacular fashion with my laptop in my hands. It hurt like hell. I'm still not sure if I've permanently damaged my toe.

dominicm20:11:23

My dog did it once.

dominicm20:11:35

He turned around and walked out of the house.

maleghast21:11:24

@yogidevbear - Hope your toe is ok, but how’s the laptop!??!?!

yogidevbear21:11:30

Well I'm on the laptop now so I think it came off better than I did

maleghast23:11:38

Glad to hear it - blimey there’s a big delay on my trips to Slack tonight, eh?

maleghast23:11:50

I must have been working or something… 😉