Fork me on GitHub
#clojurescript
<
2016-09-06
>
vikeri13:09:15

A question to anyone who has good insight in random numbers in javascript. I need a random 32-bit integer. Is there something wrong with the following function:

(defn random-32 [] 
  (Math/round (* (- (Math/pow 2 32) 1) (Math/random))))

dschlyter13:09:50

otherwise you seem to follow the recommended approach, but Math/floor should be more uniform

xcthulhu15:09:14

@vikeri : If you want cryptographic random numbers, you can use Isaac.js. Here's a copy I have where I've added all of the JSDoc annotation to make the Closure compiler happy - https://github.com/Sepia-Officinalis/secp256k1/blob/vendor-sjcl/src/js/secp256k1/math/random/Isaac.js

xcthulhu15:09:32

Chrome/Safari/FireFox all expose crypto.getRandomValues, which can fill in a UInt32Array, Int32Array, or the 8 bit equivalents with secure random values. IE 11 has a similar service msCrypto.getRandomValues

xcthulhu15:09:10

Here's a routine I have that tries these various ways of generating random number and falls back to Isaac.js if they aren't around -

xcthulhu15:09:16

@mfikes : As per our conversation in #planck, I think @vikeri is an example of a user who might want crypto.getRandomValues available 😉

vikeri15:09:51

@xcthulhu Great! Btw, could you explain why the method I mentioned would not be considered sufficiently random?

xcthulhu15:09:17

Well, so it sort of depends on how js/Math.random is implemented. This varies from platform to platform. If it's a linear congruential generator, then you'll see a lot of correlation in the lower order bits. You can see that Chrome's old V8 4.7 used to use such an RNG - https://v8project.blogspot.com/2015/12/theres-mathrandom-and-then-theres.html

xcthulhu15:09:51

If you care deeply about this, you can try the DieHard or DieHarder statistical test suites - http://www.phy.duke.edu/~rgb/General/dieharder.php

dimovich15:09:19

how to write in clojurescript: <Form inline>...</Form>?

dimovich15:09:30

trying to use react bootstrap in reagent

dimovich15:09:48

(def form (r/adapt-react-class (aget js/ReactBootstrap "Form")))

dimovich15:09:04

[form {:class "inline"}] doesn't work...

darwin15:09:41

from your example above “inline” is not a class, it is form element’s attribute, so you should write something like this: [:form {:inline true} …]

darwin15:09:40

not sure about that true part, I’m not that familiar with reagent, you might have better luck asking in the #reagent channel

dimovich15:09:31

@darwin yes it works. Thanks!

dimovich15:09:44

[:form {:inline true}]

vikeri15:09:53

@xcthulhu Alright, I’m actually using React Native, so that makes it JavaScriptCore

xcthulhu15:09:32

@vikeri No crypto.getRandomValues for you then 😞

xcthulhu15:09:37

What's your RNG for?

vikeri15:09:01

Some sort of UUID, so it’s not sensitive from a security perspective. But I’m still interested in the subject, since I’ll do more security sensitive things further ahead.

xcthulhu15:09:10

The library I linked is my attempt to wrap all of the JavaScript cryptostuff and provide fallbacks and polyfills when it's not around.

vikeri16:09:20

It looked great! A little sparse on the documentation side maybe 😉

xcthulhu16:09:54

I'm dealing with crypto.subtles Promise hell right now

vikeri16:09:14

I know, but its 128-bits right? What I’m using only accepts 32-bit integers...

xcthulhu16:09:43

Looking at that function, it calls rand-int

xcthulhu16:09:55

So do (rand-int 0x100000000)

vikeri16:09:41

Aha, great! And that implementation will be better than Math.random()?

vikeri16:09:12

🌟 for using hexadecimal btw

xcthulhu16:09:02

Nah, it's just wrapping Math.random.

vikeri16:09:59

Alright, will use that for now then. And migrate to your library in the future when I need more security sensitive values.

xcthulhu16:09:15

If you are doing digital signatures, it's best to just use RFC 6979 anyway, although the performance is horrible on Nitro and Nashorn.

xcthulhu16:09:32

...if you are rolling your own like I am.

vikeri16:09:57

Alright, it’ll be an interesting venture. There should be a #security channel for these matters...

pat16:09:35

@mfikes : I'm seeing that the latest figwheel won't build andare: Could not Analyze target/out/cljs/core/async.cljs ----> No such var: ioc/state-machine

pat16:09:12

presumably this is ns clashing

mfikes16:09:50

@pat Ahh, plz log a ticket. (It could be the case that Andare is not working properly with non-self-hosted ClojureScript.) (In any case, I’d suggest only using it with things like Planck and use the official core.async with JVM ClojureScript, if you can.)

pat16:09:09

@mfikes yes I'm trying to use fw to dev some bootstrap friendly libs. it was working fine until recently

dnolen16:09:25

@pat there’s a bug in the latest ClojureScript release that just got fixed, probably the same thing

pat16:09:13

@dnolen same problem on master. I think it's a change in fw somewhere after 0.5.4-7

dnolen16:09:29

@pat huh, ok - in anycase I just cut ClojureScript 1.9.229 with the js-dependency-index fix

dnolen16:09:05

@pat fwiw I had similar looking issues with CLJS+Figwheel until @anmonteiro’s patch and they are gone for me now

pseud18:09:49

Does anyone by chance use cursive with lein projects using checkout dependencies ?

mahinshaw18:09:58

@pseud I don’t directly, but my coworkers do. Whats the issue? I haven’t seen any differences with editor specific setup (they do what I do, and I use emacs).

pseud18:09:25

Well it's just that I'm unable to figure out what conjuring is required to the damned thing to play ball with a lein project which uses checkout dependencies (meaning the classical approach of running a script/repl.clj to load figwheel via sidecar seems out of the question)

mahinshaw18:09:21

One thing I would do is make sure you add your checkouts to src paths. For instance :source-paths [“checkouts/my-lib/src”] for clj and cljs builds. Also core namespace can be fiddly if you are calling set-refresh-dirs

pseud18:09:34

In fact. I think I'd be willing to drop some 200USD on some tool that could just work (tm) with regular lein projects. I really can't understand why the tooling is always this poor. Seems to me that lein has done a great job at abstracting all the insanity, how come then that all tools (cursive, cider) reintroduce all the problems ? What am I missing here?

mahinshaw18:09:19

I use checkouts fairly regularly, and those things work great for me

pseud18:09:20

Oh the cljsbuild stuff is easy enough, if I run "lein figwheel" from a terminal everything is peachy. checkout dependencies work, reloading works, everything works (tm).

pseud18:09:36

and how do you actually get going then ? I'm dropping figwheel, nrepl, piggieback, sidecar and god knows what into every project.clj I need to work with and I need to use a script like https://github.com/bhauman/lein-figwheel/wiki/Running-figwheel-in-a-Cursive-Clojure-REPL to get going - but once I do, I'm running a regular jvm process, not lein - and that means I'm hosed as far as checkout dependencies go

mahinshaw18:09:20

No, checkouts doesn’t care where the repl comes from. My coworkers don’t use lein repl.

mahinshaw18:09:45

So is the problem checkouts directly?

pseud18:09:09

The link above specifically mentions that it breaks checkouts. I haven't been able to run a say.. "lein figwheel" session from within cursive - I have to run a regular jvm process, load a script file as the guide indicates and that then triggers figwheel.

pseud18:09:31

Well, the problem, I guess, is that I'm just trying to write some code and I have (after some struggling) figured out how to make lein behave - but apparently it's a whole new thing getting cursive to work with these things. Seems like (from the run configurations dialog) that cursive wants an nrepl session - and I'm guessing that's where the misery starts

mahinshaw18:09:38

Yeah, the cursive part I am not as up to date on. But I use figwheel, and haven’t had a problem with checkouts

mahinshaw18:09:08

I just make sure I point the source paths in to look at checkouts

pseud18:09:29

lein, figwheel - all the cli tools are perfect, once you finally get them configured - it's just cursive, which I'm trying out after repeated issues with cider... x_x

mahinshaw18:09:40

I think there is a setting in the cursive repl to tell it to not use lein.

pseud18:09:20

There is, almost nothing but. It's lein support is abysmal. You can't even run a task. if you select lein, all you can do is specify the profile(s) to run...

mahinshaw18:09:56

yeah, I just got cider figured out, and haven’t spent a whole lot of time with cursive

pseud18:09:30

I think I'll just grab a break. This is infuriating me and I don't think I'll get anything constructive done - as evident by my whining. But man, the IDE <-> clojure interplay is stoneage compared to Racket...

pseud18:09:52

Thanks though, hopefully I'll figure it out once I'm more relaxed again 😛

kenny18:09:25

@pseud I use boot so I don't know how to solve your issue with lein. Have you checked out the Leiningen tab? If you go to Leiningen projects > your project name > Tasks you can select a task and run it.

pseud18:09:50

I have - the lein tab is really just a prepopulated list of standard lein tasks - meaning if you install any plugin like cljsbuild or figwheel they won't show up there (nor will things like 'repl'). 😞

kenny18:09:59

Plug for boot.. boot's checkouts work nicely with Cursive (really you just run in the command line). You add :checkouts to your environment and boot will automatically pick up changes from all projects added. Not sure why extra tooling is needed for this to work in lein.

pseud18:09:06

Well I'm forced to work with my colleagues so as nice as boot might be, it's not an option. Also, I'd expect a tool which someone actually wants to charge money for could help to make popular use-cases work, at least provide some damned documentation if automation is out of the picture. But oh well.

kenny18:09:21

All I do is run my boot task in the command line (e.g. boot web-dev) and it just works. You can't do this with lein?

kenny18:09:11

You can also add that command to IntelliJ's external tools so all you have to do is go to Tools > External tools > boot web-dev and click and it auto runs that command.

kenny18:09:33

Could even set up a key binding for that if you wanted

shaun-mahood19:09:24

You could also run figwheel from the command line and connect to the remote nrepl port from Cursive. I've used it quite a bit and it works well.

pseud19:09:55

Not that I know of. But it seems that I can either bombard each lein project with third-party deps and special clj files to auto-run such that booting a nrepl (lein repl) session and then starting figwheel might work - that way I can connect via cursive to the remote nrepl (at least Cursive can't ruin that). Its just.. not elegant. So I'm looking into whether I can move all dependencies to ~/.lein/profile.clj but then I'm back to not having any easy-to-run function to start figwheel and dump me in a cljs-repl...

pseud19:09:53

shaun-mahood: yea, exactly my thought 😛 Have you somehow abstracted away all the dependencies, auto-start scripts and whatnot such that you're not including a modified user.clj/repl.clj (whatever you call it) and a bunch of dev-time deps for each project ?

darwin19:09:59

@pseud I think you could use lein run to run your own clj with classpath populated from project.clj setting, that would be analogous to running your standalone scripts/repl.clj

dnolen19:09:18

@pseud there’s also a #cursive channel, I’m sure people have run into this before. FWIW, I don’t bother with Lein here, a REPL launched via the clojure.main option works just fine

pseud19:09:19

@darwin yea I'm pursuing that avenue just now 🙂

pseud19:09:03

If anyone know how to achieve something like this: https://gist.github.com/jwdevantier/ae6ffe64e212cae2556974c087a5d48a then I'd be golden

darwin19:09:25

I would create a separate lein profile myprofile with all deps/setup needed for that, then do lein with-profile +myprofile run -m myproject.mynamespace and there define -main function which would call (figwheel)

darwin19:09:54

isolating stuff into a profile is a good habit

pseud19:09:01

OK, interesting, I guess that's a good approach, better than what I had considered, even

darwin19:09:01

as an inspiration for you, this is pretty fresh code I still have in my head: https://github.com/binaryage/cljs-oops/blob/master/scripts/run-circus-tests.sh#L14 https://github.com/binaryage/cljs-oops/blob/master/project.clj#L33-L36 https://github.com/binaryage/cljs-oops/blob/master/test/src/circus/oops/circus.clj#L219 once you get -main launched you should have checkout dependencies on your classpath and from there you can call figwheel (or do whatever)

kenny19:09:44

@darwin Ooo. That lib looks useful. I have also ran into the problem with externs being slightly out of date causing exceptions in prod. Any ETA docs?

darwin19:09:58

@kenny I’m sorry, won’t promise anything at this point 🙂 first I want to convert all my libraries/projects to use it, to battle test it, then I will maybe spend some time on the docs

kenny19:09:14

Cool. Will keep an eye on it 🙂

pseud19:09:50

is there a way to get a cljs repl from within clojure w/o using figwheel ? I have some library projects too where I really just want a repl of some sort and right now I seem to have some troubles with figwheel in those projects. Can I just get a cljs repl to use for evaluating forms and the like ?

pseud21:09:45

Yea, writing a custom .lein/profile.clj with an accompanying .lein/figboot.clj which I ensured got loaded (via :repl-options) didn't work either, when it finally boots the checkout dependencies aren't observed so any changes in the parent project are not reflected until I restart the repl... Not surprisingly, it's the same if I start a repl by letting cursive start a regular java process and load some file which spawns a figwheel repl. 5 hours of no progress... 😞

slester21:09:10

Is there a nice way of loading in a JSON data file to clojurescript on load? Basically I have a bunch of data I want to search over, but I don't want it to have to make an API call, and I don't want a long loading time on the user's end.

sihingkk21:09:44

if you have a lot of JSON data, perhaps https://stedolan.github.io/jq/ would be the right tool 😃

slester21:09:32

I'm not sure how that tool is going to preload JSON into cljs for me...

sihingkk21:09:05

it should help you search data without using cljs at all

slester21:09:26

I'm making a webapp.

sihingkk21:09:46

ok, in such case JQ is bad idea 🙂

martinklepsch21:09:45

@slester not sure if that's what you're asking but you could inline the JSON or an edn representation of it using a macro

martinklepsch21:09:03

you could also just put it into the HTML file that loads your application

slester21:09:30

@martinklepsch sounds more helpful! in what format should I do that, though? just load the json into a variable, then use js/varname within the clojurescript? is there an order I need to do it in?

martinklepsch21:09:45

if you put it into the html you'd define a global that you access via js/varname, yes

martinklepsch21:09:15

you can just put the JSON into a <script> tag, not sure what other format you're asking about?

martinklepsch21:09:17

As for order it would make sense to put the JSON first if your app isn't useful without it. You can probably do it either way depending on your application code.

slester21:09:42

@martinklepsch I just wanted to read it in from a file instead of plopping it directly into the HTML

martinklepsch21:09:12

@slester you could generate the HTML, inlining the JSON? all that said simplest is very likely just loading it via an ajax call

hlolli21:09:54

@slester You could parse the json from another cljs file. In the end the user has to download the data one way or another into his memory. Or just parse the json to edn map during development if the data is static.

slester21:09:37

@hlolli hmm, interesting; could I read it into a variable from a static file on compilation?

hlolli21:09:10

you could have an immutable map and to (get map :key) or (:key map), just like you had any other clojure map.

slester21:09:50

@martinklepsch maybe this belongs in #beginners but could you point me in the right direction on how to import it via macro?

hlolli21:09:31

https://github.com/clojure/data.json there are some json->edn parsers here.

hlolli21:09:09

oops this it clj not cljs... I personally use transit so im rarely working directly with json. This data.json will not do the trick for you.

hlolli21:09:33

(defn json-parse
  "Returns ClojureScript data for the given JSON string."
  [line]
  (js->clj (JSON/parse line)))

cljs.user=> (json-parse "{\"a\" : 2}")
{"a" 2}