Fork me on GitHub
#clojurescript
<
2021-07-27
>
zimablue06:07:40

hey, is cljs.spec.alpha the right thing to be importing to use spec in clojure and does it work?

p-himik07:07:54

Yes and yes.

Jovanni09:07:41

Hi I have been having a problem with configuring the clojure project. Anyone who help me would be appreciated. Thanks!

p-himik09:07:05

Please don't cross-post across multiple channels within a short time frame.

pinkfrog12:07:42

Hi. I am following this simple quick start:https://clojurescript.org/guides/quick-start. I wonder, when I type, e.g.,

(println "asdf")
inside the cljs repl. What gonna happen under the hood? How is the code compiled to js, and how is the browser got updated for the function and accordingly how is it executed.

Otto Nascarella12:07:49

hi 👋 the browser and the repl are communicating under the hood via websockets. so when you type on the repl, code is compiled, sent via websockets and then executed probably someone else can go into more detail if you want/need

darwin12:07:23

1. open devtools in your browser session backing your CLJS REPL 2. run (do (println "asdf") (js-debugger)) from your REPL 3. investigate callstack in your browser, also see how the code was compiled into js

pinkfrog13:07:28

Thanks. the js-debugger is awesome.

Pepijn de Vos14:07:41

Kinda forgot if there is a neat way to update a bunch of keys in a map. The ones I can think of are (into m (map (fn [[k v]] [k (+ v 1)]) {:a 1 :c 2})) or maybe (reduce (fn [m [k v]] (assoc m k (+ v 1)) m {:a 1 :c 2}) or something like that but both seem a bit yucky.

Pepijn de Vos14:07:43

Maybe not clear from these snipets, I don't want to map across the values specifically, but I have a sequence of keys that I want to update.

Pepijn de Vos14:07:17

Another sneaky option... (apply assoc m (mapcat (fn [[k v]] [k (+ v 1)]) {:a 1 :c 2})

p-himik14:07:55

You have basically outlined it yourself. map-vals does not exist in clojure.core, and people usually implement it themselves using similar ways.

p-himik14:07:15

Two ways to improve your first example: • Use a transducer • Update the value directly

(into {} (map #(update % 1 inc)) {:a 1 :b 2})

Pepijn de Vos14:07:49

Ohhhh transducer!! I'm too oldschool for that haha but not making a bunch of intermediate values is great.

dnolen14:07:37

I think I would prefer reduce-kv in this case - seems clearest w/ respect to intent

🙌 2
dnolen14:07:35

to improve readability, I would combine reduce-kv with letfn

dnolen14:07:01

then reduce-kv becomes a one-liner, you don't embed the reducer creating clutter

mauricio.szabo14:07:16

Folks, I've been struggling with async tests in ClojureScript for a while, and I decided to make a library to make these things easier. I've been using it for a long time on my projects, and it works perfectly. Now, what I want to know is if more people also struggle with these problems, and if I can get some feedback/pain points to see if I'm on the right track... maybe discuss on #testing channel to not overflow this one? 🙂

Derek19:07:14

I’m curious, for sure

athomasoriginal14:07:25

I’m interested 🙂

Pepijn de Vos14:07:20

I need to dust off clojure quiz I think...

dnolen14:07:11

I see a lot of reducer embedding - so it's not like people are cleaning up their code consistently in this regard

dnolen14:07:36

I also see reducer lifting - when it can't really be used elsewhere

2
dnolen14:07:04

also k v naming which is obtuse if there is a domain of concern

borkdude14:07:28

Hey, I've made a thing: https://github.com/borkdude/tbd I'm not ready to officially announce it, but feel free to try it out and provide some feedback =)

valtteri18:07:30

This is cool! Tried out a couple of things

valtteri18:07:49

(prn "hello")

(-> (.resolve js/Promise "Hello async")
    (.then prn))

(def fs (js/require "fs"))
(.readFile fs "./test.json" (fn [err res] (prn (js/JSON.parse res))))

(def fsp (js/require "fs/promises"))
(-> (.readFile fsp "./test.json")
    (.then js/JSON.parse)
    (.then prn))

valtteri18:07:54

All this works as expected

valtteri18:07:10

On node I can also require a JSON file like this

> m = require('./test.json')
{ key1: 'val1', key2: true }
But requiring JSON fails with > #error {:message \“Cannot find module ‘./test.json’\\nRequire stack:\\n

valtteri18:07:17

Dunno if this is expected to work. 🙂 Probably not.

borkdude19:07:10

Ah, yes, I can fix that

borkdude20:07:21

Should be fixed now

valtteri06:07:54

Wow, that was quick 😎

valtteri06:07:12

Works like a charm now

borkdude14:07:48

that I don't even know

borkdude14:07:51

maybe I should name it dont

dnolen14:07:35

also I'm guilty of all the above - but whenever I come back to code that's written this way - ugh

dgb2315:07:46

so when I understand correctly: reducer embedding = inlining the closure in the reduce call reducer lifting = declaring a function with defn at the top level even though it is needed only in the reduce body letfn = naming the reducer in the scope where it is needed The only tradeoff is that one has to think of a name for the reducer. But I think I like this suggestion generally.

borkdude15:07:37

Does someone has experience with nexe here? I wanted to try it out. But it says "Error: python ./configure.py --dest-cpu=x64 exited with code: 1"

dnolen15:07:19

@denis.baudinot there's nearly always a good name, especially if you are doing something in your domain

👍 2
dnolen15:07:35

to me the rule of thumb - is if you're not writing some kind of higher order functional helper

dnolen15:07:59

you should not use Standard ML style mathematical naming conventions

dnolen15:07:10

(it might very well be an old Lisp-ism - but I've seen it more often in the ML derived FP literature)

dgb2316:07:38

ty! I guess the exception is when the whole function is essentially a call to reduce with a bit of stuff around it.

Richard Bowen16:07:43

Hey, I would like to install cljfmt locally such that I don't have to include it as a project dependency, how do I do that with leiningen?

lilactown17:07:45

it doesn't exactly answer your question, but there's a similar project to cljfmt called https://github.com/greglook/cljstyle which provides a native-compiled binary

lilactown17:07:49

it can be useful to include it as a project dependency (e.g. in a :dev profile) so that it allows you and your collaborators to use the same formatting tool. if you want to stick with cljfmt and not include it in your project dependencies, you can set it in your user profile: https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md#default-profiles

Ben Hammond20:07:07

what is state-of-the-art for Cljs/React/Material-UI ? I'm tinkering with Reagent/Reframe, but finding it a pain to interop with MaterialUI components ...

p-himik20:07:36

What causes the pain?

Ben Hammond20:07:36

well, my own ignorance, no doubt... eg I would like to add an AppBar, but I'm not getting traction on

(defn app-bar
  []
  [:div
   [:h2 "AppBar"]
   [(reagent.core/adapt-react-class AppBar) {:position "static"}
...
]
returns a
react.development.js:221 Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.

Check the render method of `simple.core.app_bar`.

Ben Hammond20:07:20

do I really have to wrap every component in adapt-react-coass?

Ben Hammond20:07:55

and... any ideas on what the error message means

p-himik20:07:08

No. You can instead write [:> AppBar ...]. And the error above seems like you might be importing AppBar incorrectly. What's the :require?

Ben Hammond20:07:36

["@material-ui/core/AppBar" :as AppBar]

p-himik20:07:54

Try replacing :as with :default.

p-himik20:07:27

Personally, I don't like [:> ...], so I just have my own proj.material-ui namespace where I call adapt-react-class for every component that I use, just once.

👍 2
Ben Hammond20:07:42

ooh that worked. Thankyou very much

Ben Hammond20:07:03

do you trip over the function components/hooks thing very much?

p-himik20:07:13

But if you get really lazy, you can use https://github.com/arttuka/reagent-material-ui - it's the only library that I know of that doesn't bulk import all MUI components and instead imports them in corresponding namespaces, making it possible to reduce the build size. Also, definitely take a look at how that library implements text-field - it's a tricky component.

👍 2
p-himik20:07:44

> do you trip over the function components/hooks thing very much? No, not really.

Ben Hammond20:07:03

Ok will do. Its reassuring to hear that this is a reasonable stack to be attempting

p-himik20:07:32

Ah, once - while trying to help someone with such a problem. :) It ended up being some bizarre issue with React being included twice.

Ben Hammond20:07:31

I vaguely remember having issure with MaterialUI styles using hooks for storage which insist upon functional components which were incompatible with the frame I was using before

p-himik20:07:07

It'd be fun to tinker around with if you can create a minimal reproducible example.

Ben Hammond20:07:30

I'll bear that in mind if I ever remember the details

Rupert (All Street)13:07:48

@U793EL04V - have you tried Material UI with https://github.com/roman01la/uix + ShadowCljs? I expect Material UI + most react libraries should work natively (reasonably seamless interop) with this setup without without any clojure wrappers required.

Ben Hammond15:07:35

yes, I did have a dabble with uix last year I liked it, but I was seduced by re-frame's higher commit rate (and better documentation...) I am using Shadow Cljs; I am tollowing the material-ui Tab example https://material-ui.com/components/tabs/#SimpleTabs.js which uses a React State Hook to manage which tab is currently visible... From ReFrame perspective; would this be entirely tooled as a dispatch/subscribe? Or is there a place for State Hooks when they are tightly coupled with a component?

javi18:07:30

if other parts of your app need to know about the state of the tabs, use reframe subscribe/dispatch and store the state in the app-db. if not, which for tabs most of the time will be the case, you can use a local reagent atom.

leif22:07:07

Is there any way to turn on *read-eval* in self-hosted clojurescript?

leif22:07:27

(It seems to be removed from cljs.tools.reader altogether. Which makes sense in non-self-hosted clojurescript.

Ben Hammond15:07:35

yes, I did have a dabble with uix last year I liked it, but I was seduced by re-frame's higher commit rate (and better documentation...) I am using Shadow Cljs; I am tollowing the material-ui Tab example https://material-ui.com/components/tabs/#SimpleTabs.js which uses a React State Hook to manage which tab is currently visible... From ReFrame perspective; would this be entirely tooled as a dispatch/subscribe? Or is there a place for State Hooks when they are tightly coupled with a component?