Fork me on GitHub
#clojurescript
<
2019-08-07
>
andy.fingerhut06:08:19

OK, perhaps off-the-beaten-ClojureScript-path question here. I've done a lot of work with Clojure/Java, but hardly anything with ClojureScript except occasionally trying out a few things at a REPL using the following command I got probably quite a while back from Mike Fikes: clj -Sdeps "{:deps {org.clojure/clojurescript {:mvn/version \"1.10.439\"}}}" -m cljs.main --repl-env node. I first installed Node.js on my Mac before then, and it seems to do the job.

andy.fingerhut06:08:34

On the actual question: Is that a sufficient setup for running clojure.test style tests and trying things out at a REPL, for debugging and trying out fixes for a data structure library like core.rrb-vector? I actually don't want to do any web page application stuff at all right now.

andy.fingerhut06:08:25

I've been using Emacs with inf-clojure and a Socket REPL most recently, which I'd like to do with ClojureScript, too, if it isn't difficult to set up.

dpsutton06:08:07

I don't know about that. I was going to mention that core projects like core.async work perfectly with a node repl using CIDER

andy.fingerhut06:08:33

My needs are pretty basic, I believe. If I end up not knowing the difference between lumo, planck, etc. that is OK by me 🙂

dpsutton06:08:37

i see telnet instructions 🙂

dpsutton06:08:58

but in the spirit of what you're looking at, if you aren't opposed to repl nrepl, here's how simple it is to get a cljs repl up and running:

dpsutton06:08:51

and cider.piggieback is taking the place of cljs.main so its almost verbatim what the command line is. Start clojure, start a cljs repl with a passed repl env

dpsutton06:08:17

this has the benefit of full CIDER nav, completion, doc, apropos, etc. If you're interested

dpsutton06:08:18

the analyzer.jvm isn't required, that's just already there for core.async

andy.fingerhut06:08:29

Thx much for the recipe. I may try that out, but will poke around a bit with the resources I found above for a little while first. What is a good way to find out what namespaces are require'able when ClojureScript is started with Node.js with the command I showed above?

dpsutton06:08:22

I'm not sure i follow. With that command I assume everything in :paths will be requireable

andy.fingerhut06:08:24

OK, so I updated my ClojureScript version to the version 1.10.520 suggested on the latest Quick Start page here: https://clojurescript.org/guides/quick-start

andy.fingerhut06:08:16

Then I found this page: https://clojurescript.org/tools/emacs-inf (not realizing whether it is up to date, but trying it). Manually at the ClojureScript on Node.js REPL in a terminal, I try evaluating the Clojure forms mentioned there. (require 'cljs.repl) goes by without a problem. When I then try (require 'cljs.repl.node) it says No such namespace

andy.fingerhut07:08:19

The fact that I can do (require 'cljs.repl) but then (doc cljs.repl/repl) gives no documentation, but (doc cljs.repl/ex-str) does, leads me to believe that maybe the instructions on this page might be out of date, since there seems to be no such function cljs.repl/repl ? https://clojurescript.org/tools/emacs-inf

andy.fingerhut07:08:57

OK, making some progress, now that I am actually following the instructions on that emacs-inf page more closely. I still need to figure out how to start that inf-clojure ClojureScript REPL with at least the core.rrb-vector namespaces available in a require'able place.

robert-stuttaford09:08:46

so @U04V15CAJ responded https://clj-kondo.michielborkent.nl on Twitter and now I think I'm sorted 😅

jeroenvandijk09:08:26

wow and it has a php backend. The power of Clojure with GraalVM i'm guessing

borkdude09:08:08

PHP was the most convenient proxy I could find. I tried to do it in nginx directly, but this was way easier.

jeroenvandijk10:08:03

sounds like a nice extra possibility for Clojure hosting

borkdude10:08:39

kinda like AWS lambda, but old school

metal 4
Ahmed Hassan11:08:11

How does it run on php back end?

dnolen10:08:11

@andy.fingerhut I don't believe you should have to do anything for inf-clojure to work with cljs.main, tubular also isn't necessary anymore far as I know - you should be able to pass socket REPL options via the CLI same as Clojure

dnolen10:08:54

as far knowing what's requireable - I'm not sure I understand the question - it's on the classpath or it's not - same as Clojure

dnolen10:08:36

other thing cjls.repl wasn't really meant to be .cljc so requiring it is not useful - all the other REPL namespaces similarly are not meant to be loaded in ClojureScript

dnolen10:08:00

it's not clear what you are intending to do so I can't offer more advice then: don't bother trying to load that stuff

andy.fingerhut11:08:29

Thanks. I'm just remembering what it feels like to be new at something again 🙂

alpox12:08:27

Is there a way to use js->clj and add exceptions with certain criteria? - In my case: I want to ignore react elements and prevent them from being transformed to persistent clojure datastructures

alpox12:08:36

I see that it is possible to extend IEncodeClojure but it doesn't help me with react elements as they don't have their own specific type. They only have lookup functions (ex. React.isElement(elem)) to determine that the data is a react element.

andy.fingerhut12:08:27

OK, another basic question: Clojure/Java vectors have vector-of in order to create vectors of the same Java primitive type. There is no notion of reference/boxed values vs. primitive values in JavaScript, and that is why there is no cljs vector-of ?

alpox12:08:21

@andy.fingerhut I don't know about the case of vector-of but there is a difference between primitive values and boxed values in JS although it about never makes a difference due to autoboxing.

dnolen13:08:29

@andy.fingerhut it couldn't serve any real purpose, JS is untyped - we could do it for compatibility of course

dnolen13:08:11

though it has come up before it might be useful for TypedArrays but it's pretty special purpose so it hasn't gone anywhere

dnolen13:08:57

I don't recall ever using or seeing vector-of personally in a real Clojure project

dnolen13:08:55

@andy.fingerhut circling back - the goal of cljs.main was to provide the Clojure affordances out of the box

dnolen13:08:05

you shouldn't need anything else for basic integrations

andy.fingerhut13:08:37

I'm not claiming it is high priority to add vector-of to ClojureScript. Just trying to see whether it makes 0 sense, or some sense. Sounds like it could make some sense, but is low priority, which is fine.

andy.fingerhut13:08:19

The main use case I can imagine for vector-of in Clojure/Java is saving memory for very large vectors, but likely people consider Java primitive arrays before Clojure primitive vectors if they get to that kind of use case.

dnolen13:08:29

@alpox to be honest I would just not do whatever it is you're trying to do - maybe explain why you need js->clj also if this just about convenience of interop, have you considered @mfikes cljs-bean? https://github.com/mfikes/cljs-bean

alpox14:08:27

@dnolen Thanks! cljs-bean might just be what I'm looking for. I could go without a js to clj transform but that would end up in rather mixed code (It would be hard to see where there are normal values and where there are js values) and a lot of single-transforms as parts of the data passed to me as js values have to be passed into reagent props again

alpox14:08:20

cljs-bean works like charm. Many thanks @dnolen

dnolen14:08:30

👍:skin-tone-4:

andy.fingerhut14:08:59

OK, I am rocking my first bug fix in a ClojureScript library (core.rrb-vector) with a similar deps.edn + Emacs + inf-clojure workflow I have recently been using for Clojure. Nice.

metal 4
👍 4
andy.fingerhut14:08:24

re-defn'ing functions live and all

dnolen14:08:47

the only way to code 🙂

andy.fingerhut14:08:10

Maybe quick question: Is this line (set-print-fn! js/print) giving me an error sound normal? https://github.com/clojure/core.rrb-vector/blob/master/src/test/cljs/clojure/core/rrb_vector_test.cljs#L7 It is in a test namespace for core.rrb-vector that is written in what looks unusual to me from someone used to Clojure + clojure.test, with no deftest/is/are, but only defn/assert. I don't know what it is intended to do -- the rest of the code is fine if I comment it out.

dnolen14:08:22

@andy.fingerhut probably shouldn't be in there

dnolen14:08:33

that ties to testing to specific JS environments

dnolen14:08:44

in this case probably nashorn / rhino

dnolen14:08:27

since you can establish printing before you run tests you should never do stuff like that

andy.fingerhut14:08:51

Thx. I will double-check with original author if they have time to comment on removing it.

dnolen14:08:03

sure but it's broken 100%

dnolen14:08:25

however they're testing needs to be fixed

andy.fingerhut14:08:34

ok, good to know.

dnolen14:08:59

assuming the JS environment unless it's specifically the browser is just awful

dnolen14:08:25

in generic libs anyways

alpox15:08:08

Is there a best-way to use react hooks with reagent or is it necessary to switch to something like hx when they are needed?

alpox15:08:52

Usecase: Material UI (And many newer react libraries) come with react hooks for usage. I wonder how to use them with reagent.

alpox15:08:16

Never mind, I found I can use [:> Component] to use my component like a normal functional react component in which hooks work

Olical16:08:29

Are there any rumblings of another ClojureScript release at the moment? Reeeeally want to use this patch 😄 https://clojure.atlassian.net/browse/CLJS-3096 Also, when a patch is "added to tender" does that mean it's next in line for application and release?

Olical16:08:22

I didn't know it existed! I want to use it!

mfikes21:08:19

Patch Tender is a place where candidate patches are soaked.

mfikes21:08:47

Ahh, I suppose the README explains it. 🙂

Olical21:08:03

Yep, made sense after a Google and a read 😄

dnolen17:08:39

@olical there's a couple of other major issues, but I'll add these to my queue to review on Friday

Olical17:08:15

Ah okay, I'm not in a massive rush and didn't want to be like "BUMP!" or bug you. Was just interested, no stress :)

dnolen17:08:55

there's definitely one coming in the near future

Olical19:08:53

I've been starting a prepl with my accept function set to cljs.server.node/prepl then I've been trying to start a foreground stdio REPL using the repl-env from the node one with cljs.cli/main but I'm struggling to find the repl-env and when I do I can't seem to get anything to accept it. Some want the repl-env to implement IFn which the NodeEnv definitely doesn't. I know I'm completely wrong here but I'm not sure where, anyone have any tips? Like, should I use the plain cljs io-prepl then configure it myself with my own repl-env then give that to the main function?

Olical19:08:20

Not sure if anyone's done this before anyway, like start a prepl then attach stdio to it. Maybe there's some easy thing I'm missing.

Olical19:08:14

Worked it out! So I used the cljs.server.node/prepl accept fn, then to kick off the stdio REPL I used (cljs.repl/repl (first (cljs.server.node/get-envs nil))). Not great, but it works. Really I should add some unique key to a map where that nil is so I can identify my env (since get-envs uses that first arg map as a key). Then I just have to do it for all other kinds of CLJS prepl 😬

Olical19:08:41

Writing a tool that wraps up every kind of prepl I can think of in a zero config CLI. Including bridging to figwheel and regular JVM ones.

andy.fingerhut23:08:33

So this is probably all old hat to anyone who has used ClojureScript for even a day, but new to me yesterday, and wanted to double-check my understanding. I'll put a bunch of text in a thread after this message, since it gets into some details many people might not care about.

andy.fingerhut23:08:53

There are (at least) two ways, without a browser involved, to create a ClojureScript REPL based on Node.js.

andy.fingerhut23:08:03

(a) clj -m cljs.main --repl-env node first starts a JVM process with ClojureScript JAR and a bunch of others on the classpath, which then very soon afterwards starts a node process that gives a cljs.user=> prompt to the user from the node process, reading ClojureScript forms and evaluating them. (require 'cljs.repl.node) doesn't find any namespace there, because that namespace doesn't exist for ClojureScript.

andy.fingerhut23:08:15

(b) clj "-J-Dclojure.server.repl={:port 40404 :accept cljs.server.node/repl}" starts up a JVM with a classpath same/similar to (a), giving you a user=> prompt from Clojure/Java, but does not start a node process until and unless some other process tries to connect to it on TCP port 40404, at which point then it tries to start node with appropriate options, and the TCP client process then gets a cljs.user=> prompt, and ClojureScript forms it sends are passed through the JVM process to node, which evaluates, returns results through the JVM process, back to the TCP client.

andy.fingerhut23:08:18

My confusion yesterday was not realizing this basic distinction, and trying to get (require 'cljs.repl.node) to work when using method (a).

andy.fingerhut23:08:09

And a probably significant piece I left out of the above, is that the JVM process is involved in compiling every ClojureScript form, as they are read, into JavaScript, and that is what is actually sent to the node process?

andy.fingerhut23:08:29

Cool. Is this the kind of thing that beginners ask all of the time, and quickly get straightened out on? I'm not promising anything yet, but if there were some kind of guide article explaining this, plus a little bit of what happens under the covers for some other common development scenarios, any guesses whether it might save folks time answering questions to point people at it?

👍 4
💯 4
dnolen23:08:53

not really

dnolen23:08:59

a lot of people use Figwheel

dnolen23:08:07

if they use Emacs they're used to the pain far as I can tell

dnolen23:08:14

if they use Cursive there's no questions really

dnolen23:08:03

(or they just asked in the #cursive channel and get sorted out quickly)

andy.fingerhut23:08:05

There's a tag line: Emacs - you get used to the pain ...

dnolen23:08:57

socket REPL isn't a hugely popular thing yet - it's not really needed

dnolen23:08:19

cljs.main largely mimics clojure.main thus provides enough for the most common scenarios

dnolen23:08:45

one place pREPL is useful is REBL