Fork me on GitHub
#clojurescript
<
2020-05-11
>
clayton01:05:57

Can anyone point me to an up-to-date guide on javascript interop syntax? I've been getting started with clojurescript this weekend (I've been writing clojure for a few months now), and the interop syntax seems inconsistent to me. I have read posts like https://www.verypossible.com/blog/clojurescript-and-javascript-interoperability-a-comprehensive-guide that explain the most bare-bones approach (the dot operator) which is consistent with Java's interop

(. some-js-object -aproperty)
and similarly you can also shortand "method" calls by doing
(.toUpperCase "hello, world")
and there is further shorthand syntax for accessing properties
(.-property js-object)
After feeling at ease learning this interop syntax, I started seeing examples online where none of this syntax is used, and instead the code looks identical to plain javascript accessors. For example,
(js/console.log "hello, clojurescript") ;; instead of (.log js/console "hello, clojurescript")

(def o #js{:property "value"})
o.property                      ;; instead of (.-property o)
I'm just confused now with all the options. If js/console.log works fine, why would I reach for (.log js/console "...") ? Is there a preferred syntax by the general community?

👍 4
krzyz06:05:34

I favor the more obvious js/console.log. Use what you are comfortable with. Remember that you aren’t always working with something static, like js/console or js/Math, so the alternative method access is useful. Also, sometimes you are actually not trying to access anything, but simply need to ensure that your argument is a JavaScript object. That’s what the #js reader macro is for. I think in reality all those individual forms are useful (except maybe the standalone dot, that’s just the base form that we sugar over with the others) Some people might use them in ways that are strange to you. Ignore that and use what feels right. I bet 99% of the time, that’s what everyone else is using. Oh btw, the Java interop page is good review. It’s not different for JavaScript: https://clojure.org/reference/java_interop

👍 4
Roman Liutikov06:05:40

Note: js/console.log is not technically a correct syntax, it's just here accidentally

dvingo12:05:25

You may also want to check these libs out: https://github.com/binaryage/cljs-oops https://github.com/appliedsciencestudio/js-interop I don't know why the docs (http://clojurescript.org) don't mention the var renaming issue with advanced compilation when doing interop.

dvingo12:05:49

it's hidden here https://clojurescript.org/reference/dependencies under using string names..

clayton12:05:12

Thanks for the help everyone!

clayton13:05:32

@U0FR82FU1 You mentioned that the syntax was here accidentally. Do you have any further information about how it was accidentally supported? I'm curious.

Roman Liutikov13:05:46

No info, just remember that it's an incorrect syntax, but now it's to late to remove it from cljs since it will break lots of users

krzyz14:05:24

Interesting, guess I’m learning something too. I assumed it was normal since it mirrors the Java interop. I’ll have to look into it too.

Roman Liutikov14:05:39

I don't think you can do (Class/a.b) in Clojure JVM?

Roman Liutikov14:05:06

ah but (java.awt.Point. 1 2) is valid

Roman Liutikov14:05:45

better ask @U050B88UR, I might be wrong here

clayton01:05:05

@U0FR82FU1 I think that example is a little different since java.awt.Point is technically the full class name. So, it seems this is unique to clojurescript. Regardless, question answered 🎉 thanks for the responses!

rickmoynihan10:05:13

Does anyone know of any compression algorithms, available to clojurescript for use in the browser? Ideally something like gzip.

thheller11:05:03

to compress what? there are a few gzip libs on npm that work in the browser

rickmoynihan12:05:40

It’s a bit of a weird one; but I’m investigating compressing query params in GET requests. And yes I realise this is normally a bad idea 🙂, but none of the other options are particularly appealing either. I’m currently drawing up options (including various other more nuanced encoding schemes — each with drawbacks too). The goal is that ideally these parameters will be permalinkable or copy/pastable; but I really don’t want to store any state on the server, or build a URL shortener. In the worst possible real world case I can think of there will be 35k parameters. Which I’ve tested will compress from about 2.5mb to 148kb gzipped and base64 encoded. Which is certainly still on the very large side; but practically I suspect it will still just about work in most modern browsers - and this is a rare edge case. Currently in a pretty common case just 100 of these parameters will blow jetty’s default max request size limit (8kb). With compression I could support 99.99% of cases in 32 or 64kb and probably 100% of cases in 256kb; and thats before looking at combining gzipping with custom encoding.

👀 8
Matt Jacobus12:05:34

Hi, are the chrome devtools expected to work properly with cljs? The bindings aren’t associated with the right values and there are duplicates. I love the experience writing code, but debugging it is difficult without tools. Is there any information you can point me to about this?

Matt Jacobus12:05:29

I also tried using debux, which is helpful, but I sometimes getting nullpointerexceptions during macro expansion.

chrismatheson13:05:39

Hi all, i was hoping someone might be able to help me move forward a little with some pointers for thigns to read or whatever…. im trying to add cljs.spec.alpha as a requirement to my project (shadow-cljs) and i get > The required namespace “cljs.spec.alpha” is not available, it was required by “test/app_spec.cljs”.

(ns test.app-spec
  (:require [cljs.test :refer (deftest is)]
            [cljs.spec.alpha :as s]
            [app.lib :as lib]))
EDIT: ingore me, the cardboard programmer stuff works, it was a typo!

dnolen14:05:40

@clayton.marshall12 js/console.log is fine, it's always going to work

dnolen14:05:13

however there are some things in near future for ClojureScript to clean up working with globals so people can deprecate that pattern over time as they see fit

dnolen14:05:27

that pattern has worked since the initial release of ClojureScript - it's not going to go away - we'll just provide something better

👍 8
Logan Powell17:05:49

👋 it's been a while since I've been here. I missed you guys! I am updating a library I wrote in cljs a year or so ago. I updated to the latest version of Clojurescript and for some reason now I can't eval functions with docstrings or macros... does anyone have an idea what's going on?

dpsutton17:05:25

are you using figwheel by any chance?

Logan Powell17:05:40

I'm using shadow-cljs

Logan Powell17:05:46

maybe I should ask in that channel?

dpsutton17:05:53

how did you upgrade clojurescript?

dpsutton17:05:02

but yeah there's a channel dedicated to shadow at #shadow-cljs

Logan Powell17:05:11

let me try that. Thank you

rgm20:05:40

I uh… this seems weird. I’m trying to bring ml.dmlc/xgboost4j into a project and it brings down my adoptopendjdk 11LTS jvm with a core dump when I try to start a REPL. If I disable rebel-readline/rebel-readline-cljs 0.1.4 I can start a REPL. I wouldn’t have thought they’d interact. Anyone have any idea what the mechanism for this would even be?

rgm22:05:24

what the what … including ml.dmlc/xgboost4j also kills figwheel’s websocket reloader O_o

rgm23:05:49

ok well, guess the workaround is to use deps aliases to keep the conflicting deps separated and use 2 JVMs for dev (since xgboost is server-only).

lilactown23:05:27

you can see where your conflicts might be using clojure -Stree

🙏 4
lilactown23:05:55

likely what’s happening is xgboost4j is bringing in a different version of a dependency shared with rebel-readline/figwheel