Fork me on GitHub
#clojurescript
<
2017-04-11
>
souenzzo12:04:17

can I get my closure-define from system environment?

souenzzo12:04:33

I will use boot. 🙂

cgrand07:04:34

Hi! #js {:foo 1} produces {"foo": (1)}, is there any way to emit {foo: (1)} (to allow Closure renaming) instead or should I use deftype?

john07:04:57

I don't quite get that in the repl. Is that what gets dumped to file? What about (js-obj "foo" 1)?

thheller07:04:48

@cgrand #js is exactly for the purpose of preventing renames, yes use deftype

cgrand07:04:48

@thheller but but but naming is hard (and I suck at it), I just wanted some local anonymous state 😢

thheller07:04:13

(deftype MyLocalState [foo]) 😉

cgrand08:04:20

beware, down this road you get a Gosling (sic) point 🙂

thheller08:04:18

if you want to keep your sanity use a volatile!

cgrand08:04:17

Does cljs keywords get renamed?

cgrand08:04:32

(stupid question scratch that)

cgrand08:04:41

(doto #js {} ; no I won't use a deftype, I'm nomatophobic
                (-> .-s (set! ""))
                (-> .-exhausted (set! true))
                (-> .-idx (set! -1))
                (-> .-cbs (set! #js []))
                (-> .-sentinel (set! nil)))

thheller07:04:58

@john what you see in the REPL is the printed representation after evaling the source, it is not the source

thedavidmeister08:04:28

@thheller for putting environment variables into cljs from clj

thheller08:04:28

ah right, totally forgot to mention that. that should be the first option always.

alex_lynch10:04:31

is there a problem with figwheel? I tried starting a new project with it with lein new figwheel proj -- --om, and get a ton of errors in the console and the repl doesn't connect

alex_lynch10:04:27

oh so I just cleared chrome browser cache and now it all works...

imetallica11:04:14

@alex_lynch there is an option on chrome dev tools to do not save caches while devtools are open. I usually do that, saves me tons of time figuring out problems. :)

devth13:04:40

trying inferred externs. during advanced compilation I get:

WARNING: out/inferred_externs.js:14 WARNING - name goog is not defined in the externs.
that line of externs has:
goog.string;
goog.string.StringBuffer;
goog.string.StringBuffer.prototype.append;
how do I coax it into inferring var goog;?

thheller13:04:31

@devth you do not need externs for anything goog, thats a bug if the infer emits that

devth13:04:12

ah. Thanks

bunkers13:04:44

Hi, anyone got time for what I think is probably a bit of a dumb question? I’m doing a bit of work with P5.js. I instantiate with (js/p5. (fn[_])) and set the setup function on the object with set!. The setup function gets called but that in turn calls other functions which use things like map. The problem is that these cljs.core functions aren’t found. I know it’s got something to do with closures and namespaces, but any clues as to why that is?

darwin14:04:15

@bunkers you are compiling your clojurescript with :none optimizations, right?

bunkers14:04:00

sorry just thought I’d better check that!

darwin14:04:05

in devtools console you should be able to check if the cljs.core namespace is present and it has expected methods/members there

darwin14:04:30

if not, then your html page is probably including cljs files inproperly

bunkers14:04:34

it is as far as I can tell, it’s just that the functions are not available from within this function. Could it be something to do with a javascript function calling this ClojureScript one?

darwin14:04:04

not likely

darwin14:04:58

show us some code

bunkers14:04:46

ok, this could be a bit of a mess! ` (defn create-sketch [options] (let [^js/p5 sketch (js/p5. (fn [_]))] (set! (.-setup sketch) (:setup options) ) (set! (.-draw sketch) (with-sketch sketch (fn [] (:draw options)))) sketch ) )

bunkers14:04:17

So I’m playing about with stuff there, but this is the function that creates the p5 object

bunkers14:04:08

(p/create-sketch { :setup setup :draw draw-state })

bunkers14:04:16

that’s how it gets called

bunkers14:04:55

the setup function starts with:

bunkers14:04:31

` (defn setup [] (let [ world-objs (create-world the-world)

bunkers14:04:43

I’ll get my formatting right in a minute!

darwin14:04:01

at first glance the code looks ok to me

bunkers14:04:10

and in create-world we have

bunkers14:04:12

(defn create-world [w] (let [bodies (map create-body (:bodies w)) bodies-map (#(zipmap (map :id %) %) bodies) get-by-id (fn [id] (get-in bodies-map [id :body])) ] {

bunkers14:04:30

and it’s the calls to map and zipmap that are coming back as undefined

darwin14:04:36

why don’t you test some minimal repro case? e.g. in create-sketch replace setup with #(js/console.log (map inc [0 1 2]))

darwin14:04:14

does map there work?

bunkers14:04:00

yeah good idea, I’ll try that out

bunkers14:04:55

ah, it is!

darwin14:04:55

your problem might be in this (#(zipmap (map :id %) %) bodies) but I don’t understand it, so I cannot comment

bunkers14:04:13

it could be. The idea is to take an array and produce a map where the key is based on 🆔

darwin14:04:19

to me it looks like (zipmap (map :id bodies) bodies)

bunkers14:04:13

yes I think that is the same

bunkers14:04:31

in fact it definitely is

bunkers14:04:45

that has worked previously though

darwin14:04:54

ok, it should work, it was just hard for me to read

darwin14:04:17

I usually don’t create anonymous fn and invoke it in-place

bunkers14:04:21

that probably does keep things cleaner! As you might have guessed I’m still fairly new to this

darwin14:04:56

I think at this point you should identify exact first place where your map (or similar) call does not work

darwin14:04:05

and show us the code from there

darwin14:04:34

we can reject that it is a general problem of your html-file setup

darwin14:04:05

my guess: it is likely some wrong code you wrote and expected it to work

bunkers14:04:03

yeah I think you’re right. I’m debugging more and I’m starting to think it’s not that map isn’t defined but something that’s undefined as map is called.

bunkers14:04:17

thanks for you help, I’ll keep debugging and see where I get to

acgt15:04:00

hi - wondering if anyone has experience with clojurescript + react native... in particular, interested in how you managed to set up unit tests. There doesn't seem to be a straightforward way of accomplishing this.

pesterhazy15:04:39

@acgt, check out #cljsrn for react-native specific discussion

acgt15:04:03

@pesterhazy ah, thanks - didn't see that there.

bunkers15:04:41

@darwin turns out it was bad argument to concat deep in the code. It caused something to be nil and just created a very confusing error! Thanks again for you help. It was useful talking it through and you got me out the dead end I was in

pesterhazy15:04:07

looking at concat is always a good idea when looking for bugs

pesterhazy15:04:01

for some reason bugs are drawn to concat like moths to the flame

benbot17:04:34

where has this been all my life

tech_hutch18:04:14

The style guide at https://github.com/bbatsov/clojure-style-guide recommends using alter-var-root to change the values of vars, but CLJS doesn't seem to have that. What is the idiomatic way to do this in CLJS?

anmonteiro18:04:59

@tech_hutch it’s just JavaScript so (set! my-ns/my-var 42) works

tech_hutch18:04:46

And it's in the same ns, so I would assume I could omit that.

noisesmith19:04:46

I wonder why it mentions alter-var-root as something to use instead of def at runtime, but no mention of intern? moot here as cljs has no intern

noisesmith19:04:35

or maybe using intern is as bad as def

noisesmith19:04:49

if I had written the style guide it would have something like “any alteration of vars at runtime that isn’t done by a dev-only tool is a code smell”

tech_hutch19:04:09

Clojure core has vars that are designed to be rebound at runtime, though.

tech_hutch19:04:24

That's what the "earmuffs" notation is for.

noisesmith19:04:19

that's not for redefining the var, that's for local binding - in fact if you used binding and someone else used def it could easily break your code

timgilbert19:04:57

Say, if I have a constructor (js/Foo.), can I apply it like (let [args [0 1 2]] (apply js/Foo. args)) ? I seem to be getting undefined back, not sure if there's some interop syntax I'm missing

jr19:04:34

(let [ctor (js/Function.prototype.bind.apply js/Date #js [nil 2014 1])] (ctor.))
#inst "2014-02-01T07:00:00.000-00:00"

jr19:04:36

whoops you need nil as the first arg in the vector

timgilbert19:04:02

I almost think it would be more legible just to manually get the positions out of my vector and pass them to the constructor (js/Foo. (nth args 0) (nth args 1) (nth args 2))

jr19:04:16

(defn construct [cls args]
  ....)

tech_hutch19:04:31

js/Date is a function, though, so it has the Function .apply method on it.

tech_hutch19:04:46

so you could shorten js/Function.prototype.bind.apply to .apply.

tech_hutch19:04:23

wouldn't that be js/Function.prototype.apply? Why .bind.apply?

pedroteixeira19:04:48

hi, are there any vanilla js light wrappers around clojure data structures? say, one passes clojurescript data to a react component, I was looking for something similar to immutable js API to access clojure immutable data from js.. would mori serve as a API wrapper for this use case? (not sure if slack is the place for this sort of question..)

rgdelato19:04:49

it's because he's using it as a constructor. Not Date(), but new Date()

timgilbert19:04:57

More concretely, this is what I'm trying to instantiate with a my vector of three constructor args: https://github.com/mrdoob/three.js/blob/master/src/math/Euler.js

tech_hutch19:04:19

You can't use .apply with new, I forgot.

tech_hutch19:04:12

If I'm not mistaken, you can use the Clojure apply with JS functions, although I don't know if it works with constructors.

timgilbert19:04:49

Yeah, I've used it with functions before. The constructor case seems to be different though

rgdelato19:04:33

it can be done succinctly in ES6 with the spread operator new Date(...args), but my CLJS-foo still isn't quite there yet

tech_hutch19:04:37

I could be wrong, but I believe Clojure has a spread operator. (Different syntax, though.)

timgilbert19:04:28

Well, regular Clojure I would probably use (apply) or maybe use destructuring. But I can't figure out how to get the constructor as a fn to pass to apply. Actually, for this specific thing I can (let [get-rot (fn [[x y z]] (js/THREE.Euler. x y z))] (get-rot [0 1 2])) which works ok

timgilbert19:04:46

....and there's also a fromArray() method in that specific code. Still curious if there's an (apply) that works with constructors though

tech_hutch19:04:26

How would that work in ES3 code, which CLJS outputs, though? I believe there's a way, but I don't remember it.

jr19:04:53

(new js/Date #js [2010 10])
#inst "2010-10-01T06:00:00.000-00:00"

jr19:04:42

not sure if that's just a date quirk

rgdelato19:04:13

yes, Date can also take an array. We're just using Date as an example; the original question was about using apply on js/Foo.

pesterhazy20:04:25

It's a known problem that you can't .apply a constructor in ES5 I think

pesterhazy20:04:55

Kind of a bug in the language

timgilbert20:04:19

Hmm, interesting

john21:04:00

anyone seen where defonce fails to prevent execution of its body on reload?

thheller21:04:52

@john when its value is nil i believe

thheller21:04:30

(defonce foo (prn :foo))

john21:04:33

Oh, I need to return something

john22:04:50

strangely now calling the defonceed var from the figwheel repl throws a Use of undeclared Var my.ns/my-var error. It still returns the correct value though. It's just a spurious warning.

john22:04:03

other vars are working properly though.

john22:04:20

Finally got multiple figwheel repls up on concurrent webworkers. Much better workflow.

john22:04:03

I'll have to put together a blog post to explain it some time.

Oliver George22:04:23

Just wanted to encourage some upvotes on an annoying quirk of keyword parsing and reading. There's a better error waiting at the end of it which will leave you with more time for your family and friends. The error thrown when cljs.reader/read-keyword encounters an invalid symbol (say one starting with a number) is not very helpful. It's particularly difficult to know where the reader failed when dealing with a big data structure. For example, this command

(cljs.reader/read-string (str (keyword "3asdf")))
Returns this error
TypeError: Cannot read property '0' of null
The null is easily detected to return a more meaningful error like:
Error: Can't create keyword from :3asdf

noisesmith22:04:27

I'm conflicted about the fact that the cljs reader errors on this - the docs specify this should be an error, so actually throwing an error is legit. And it bugs the hell out of me that people working on my app have set up code that creates such keywords. But then again we do create such keywords (thanks to mongo not supporting numbers as keys, and everyone loving keywords so much that they cast all keys coming back from mongo to keywords) so this would break my app.

Oliver George23:04:55

There a few related JIRA tickets.

john04:04:40

just hit this one. And it is even less helpful that sometimes you can create keywords with just numbers.

john04:04:22

well, I guess you always can...

Oliver George22:04:34

This is the ticket

Drew Verlee22:04:28

do :pre and :post work in clojurescript?

Drew Verlee23:04:17

K. I must have something else going on. Sadly not worth the effort to ferret out 😕