Fork me on GitHub
#clojurescript
<
2018-09-23
>
stephenmhopper01:09:36

Hi everybody, I have a fairly simple question that I can’t seem to find the answer to. I have a project.clj file. My cljsbuild section looks something like this:

:cljsbuild {:builds [
                       {:id           "dev"
                        :source-paths ["src/cljs" "src/cljc"]

                        ;; The presence of a :figwheel configuration here
                        ;; will cause figwheel to inject the figwheel client
                        ;; into your build
                        :figwheel     {:on-jsload "app.core/on-js-reload"
                                       ;; :open-urls will pop open your application
                                       ;; in the default browser once Figwheel has
                                       ;; started and compiled your application.
                                       ;; Comment this out once it no longer serves you.
                                       ;:open-urls [""]
                                       }

                        :compiler     {:main                 app.core
                                       :asset-path           "js/compiled/out"
                                       :output-to            "resources/public/js/compiled/app.js"
                                       :output-dir           "resources/public/js/compiled/out"
                                       :source-map-timestamp true
                                       ;; To console.log CLJS data-structures make sure you enable devtools in Chrome
                                       ;; 
                                       :preloads             [devtools.preload]}}

                       ;; This next build is a compressed minified build for
                       ;; production. You can build this with:
                       ;; lein cljsbuild once min
                       {:id           "min"
                        :source-paths ["src/cljs" "src/cljc"]
                        :compiler     {:output-to     "resources/public/js/compiled/app.js"
                                       :main          app
                                       :optimizations :advanced
                                       :pretty-print  false}}
                       ]
              }

stephenmhopper01:09:50

I’m trying to get the :min build to fire when I run lein uberjar. What do I need to put in my :profiles -> :uberjar section to make this work? I’ve tried a few different things and they haven’t worked.

stephenmhopper02:09:23

I think I figured it out. I added :prep-tasks ["compile" ["cljsbuild" "once" "min"]] to the :uberjar profile and removed the cljsbuild hooks.

kulminaator09:09:06

is it a design feature that clojurescript has the same number precision issue as javascript ?

kulminaator09:09:26

meaning once you pass the 53 bit accuracy you're on your own with your problems

kulminaator09:09:09

just tried this out on http://clojurescript.io

cljs.user=> (apply * (repeat 54 2))
18014398509481984
cljs.user=> (+ 1 (apply * (repeat 54 2)))
18014398509481984
cljs.user=> (+ 8 (apply * (repeat 54 2)))
18014398509481990
sure does look like javascript's own math issues once numbers get really big and their floatiness kicks in 😞

kulminaator09:09:27

checked the documentation .... yes it's intended .. a bit sad though 😞

pesterhazy09:09:20

Cljs embraces the host

mfikes12:09:12

Maybe someday we'll have arbitrary precision integers and can use the N suffix for that. https://twitter.com/mfikes/status/1036707072816148486

pesterhazy12:09:32

I'm assuming chrome is implementing https://github.com/tc39/proposal-bigint ?

pesterhazy12:09:46

Is there a polyfill for Bigint?

pesterhazy12:09:20

Ah so the bigint proposal will make it work with infix operators like +

pesterhazy12:09:45

So I guess it can't be polyfilled (or even transpiled?)

mfikes12:09:56

Yeah. One challenge for ClojureScript (when compared to Clojure), is that you can see for efficiency that (+ 17 18N) wouldn't work because JavaScript itself disallows it.

mfikes12:09:21

(So BigInt doesn't really feel so much like it is part of the tower, but is a separate island.)

pesterhazy12:09:36

It's interesting - JS enhancements come in (at least) 3 groups 1. libraries, which can be polyfilled (Promises, Array methods) 2. syntax enhancements, which can be transpiled (generator functions, classes) 3. runtime enhancements, which can be neither polyfilled or transpiled (Proxy objects?) Group 1 is easy to use from CLJS. The 2nd group is not as relevant for CLJS because we have macros. But 3 might be a challenge

mfikes12:09:42

Fortunately, it is fairly easy to play with this new BigInt thing. Through the magic of using ClojureScript as a git dep:

clj -Sdeps '{:deps {org.clojure/clojurescript {:git/url "" :sha "ec78503abada584d2de5d779433fd2d8de967c94"}}}' -m cljs.main -ro '{:launch-browser false}' -r
and then point Chrome at http://localhost:9000/ and you should be able to do this
cljs.user=> (+ 3312545466734532653465365N 414578429875420942442535454757253N)
414578433187966409177068108222618N

pesterhazy12:09:21

Yeah that's really cool

mfikes12:09:27

You can even start to see interesting bits of Clojure leaking into it: Since the reader is Clojure, if you leave off the N suffixes in the above, it still works.

mfikes12:09:24

The efficiency challenge is that this cannot be easily made to work

cljs.user=> (+ 1 2N)
TypeError: Cannot mix BigInt and other types, use explicit conversions

john15:09:42

So, to integrate it into the tower, what, we'd need overflow checks that auto-coerce when necessary? Probably cost prohibitive?

john16:09:42

I guess then there's also the issue of that tower working with JS libs? Could the tower work in a host-interopy way?

mfikes16:09:58

Yeah, ClojureScript doesn't performed checked arithmetic at all. I don't know the rationale or history behind that.

mfikes16:09:31

The most challenging problem I see is the simple change of making 2N read as as a BigInt instead of as a number. This alone feels like it forks the language in a breaking way.

mfikes16:09:22

A concrete example: Consider if someone copied this code from Clojure to ClojureScript

(defn foo [x] 
  (int (+ 3N x)))
This works today: (foo 2) evaluates to 5, but if 3N is changed to be read as a BitInt we have a lot of challenging work to do.

idiomancy17:09:00

anyone here ever worked with the web3-clj stuff?

Nolan19:09:42

little bit, definitely not any sort of expert. whats up?

idiomancy19:09:00

ah, I guess there's plenty, honestly. Where do you usually go for support on that library?

Nolan19:09:14

i really only use the essential functionality—creating/sending raw transactions—so https://web3j.readthedocs.io/en/stable/index.html has been plenty for me

Nolan19:09:25

i found that using the java and js libs directly worked with a little less friction, but my use case is pretty scoped

idiomancy19:09:18

yeah, makes sense. Honestly I think most of my trouble has been coming from ganache-cli. what do you use for local dev?

Nolan19:09:55

had never seen ganache. i just run a local node and access geth over http. ipc is pretty simple as well. i would say if you dont need anything specific from ganache to work directly with geth or parity, hasnt put up much of a fight for me

idiomancy19:09:34

makes sense to me,

idiomancy19:09:43

I'll give geth a go

4
Nolan19:09:16

good luck! its also an easy transition to other setups. i started with a local data directory (tmp garbagechain), then moved to rinkeby, then rinkeby using infura, etc..

idiomancy19:09:03

nice! okay, sounds good! (also +1 for the Mass Effect emoji joke)

kulminaator17:09:20

the way my team from 8 years ago landed on that bomb was this (in native js of course, but you get the point)

cljs.user=> (js/JSON.parse "{\"surprise\": 18014398509481991}")
#js {:surprise 18014398509481990}
.... we sent the "surprise" back to the server as "we are editing that entry" and backend machine said how about no

lilactown21:09:21

I asked a similar question in #beginners but I’ll try here, since I’m having trouble finding a good way of doing this that doesn’t involve writing my own parser or printer: I have a CLJS document containing data e.g.

"{:foo \"bar\"
 :baz 123}"
and I want to find the line number + position of the value at the path [:baz]

lilactown21:09:40

are there any tools in CLJS to do this kind of code analysis?

mfikes21:09:14

The analyzer includes some meta, like

:form ^{:line 1, :column 1, :end-line 2, :end-column 10} {:foo "bar", :baz 123}

mfikes21:09:10

(set! *print-meta* true)
(cljs.js/analyze-str cljs.env/*compiler* "{:foo \"bar\"\n:baz 123}" nil {} prn)
in Lumo or Planck produces some interesting output

lilactown22:09:10

if I’m running code in a bootstrapped CLJS env already, can I access the analyzer data in that environment somehow?

mfikes22:09:31

Yeah, I would imagine you can call analyze-str as above

stephenmhopper22:09:22

I’m trying to build my CLJS project as a JAR and install it locally. I have some tasks that need to run before that happens though, so in my :profiles section of my project.clj, I have something like this:

:install {                                     ;:omit-source true
                   :prep-tasks [["sass4clj" "once"]
                                ["minify-assets"]
                                ["cljsbuild" "once" "min"]]
                       }
However, it’s not running those prep-tasks at all. What am I missing?