Fork me on GitHub
#clojurescript
<
2020-09-26
>
lilactown00:09:40

@ozzloy_clojurians_net you need to dereference the atom inside a component

lilactown00:09:22

You’re derefing it inside the call to render which doesn’t setup the tracking correctly

victorb11:09:22

Is there any smaller implementation of pprint suitable for cljs usage? Including clojure.pprint to my application adds about 90KB to the final bundle size, which ends up being like 40% of my application size, but I'd love to be able to pprint in production env as well (currently excluding it for production builds)

skeuomorf12:09:40

Hey folks, I have been out of the loop with clojurescript for a while, are there any guides out there that list the recommended libraries (that are actively maintained) for the common frontend tasks? Also, do people use things like postcss or are there cljs alternatives? Do people use webpack to get access to all the plugins?

victorb13:09:33

Re recommendations, everything is pretty opinionated as far as I know. I know some groups "standarized" in just using re-frame + reagent, pulling in npm modules for smaller functionalities as needed. Some of them do inline styling in hiccup, others use a css file, others use styled-component. I haven't myself came across any (cljs) projects using webpack, shadow-cljs/figwheel/figwheel-main handles pretty much every common frontend workflow as far as I know

skeuomorf14:09:50

Looks like it hasn’t changed much then! Thanks.

Niclas13:09:14

Looking for a bit of help from somebody with more knowledge of the inner workings of ClojureScript here, any help appreciated! I’m attempting to enumerate over fn defintions in an ns and fetching each fn’s metadata, however I’m running out of ideas on how to accomplish this. This is as far as I’ve gotten. Is it even possible to do what I’m trying to do?

; in my.ns
  (defn a {:x :a} [])
  (defn b {:x :b} [])
  (:x (meta (var a))) => :a
  (:x (meta (var b))) => :b
  (doseq [f (keys (ns-publics 'my.ns))]
    (meta (var f))) => Unable to resolve var: f in this context...

kingcode13:09:30

@looveh You can use (ns-publics ’my-namespace) to get back a map of symbols to var expressions

kingcode13:09:40

I am trying to find out if there is a way to prevent the modularization step of compilation. Specifically, what are all the ways cljs.closure/src-file->goog-require is invoked? I can see there is an invocation within src/main/clojure/cljs.repl.cljc’s load-file at line 622, but how about the cases where we just want to make a build, no repl? Thanks for any comment.

schmee18:09:51

hello everyone, I could use some advice to get back into the cljs ecosystem after a long hiatus

schmee18:09:16

2-3 years ago I built some stuff using “reagent + figwheel + cljsjs”, is that still a viable setup?

johanatan18:09:11

sub figwheel-main and you're good to go.

schmee18:09:01

ahh, I did not know there was a new version out, and the Reagent lein template still uses lein-figwheel. Looks like I can use https://github.com/bhauman/figwheel-main-template instead. thanks for the pointer! 🙏

johanatan19:09:52

oh yea. you'll want deps.edn rather than lein for sure. much better experience

victorb20:09:21

I'm not sure deps.edn rather than leiningen is a "for sure" yet. I haven't found a feature of deps.edn that isn't already supported by leiningen. Only thing I can think of is that deps.edn is more "blessed" by the core clojure team

johanatan20:09:43

It’s far less noisy / more concise. Plug-in system is far simpler / less buggy.

johanatan20:09:01

Built-in support for git sha refs

johanatan20:09:16

In general it “just works”

johanatan20:09:31

And that most definitely isn’t the case for the complicated leiningen

victorb20:09:39

yeah, generally (in my experience, not doing anything too fancy), leiningen "just works" too. Hence the uncertainty around you using "for sure". I don't mind what you use, but plenty of the ecosystem still uses leiningen, for what's it worth

johanatan20:09:18

I’m just giving my opinion. I’ve used both heavily and there’s just no comparison. Feel free to disagree

👍 3
schmee18:09:22

I’ve poked around a bit and now there is shadow-cljs, :foreign-libs and tons of other new stuff, so I’m worried I’m doing something completely outdated

Jeff Evans18:09:32

#figwheel and #reagent are definitely still active

schmee18:09:23

good to hear! if I’m using those two, what would be the “go-to” way to import libraries such as Semantic-UI-react?

schmee18:09:45

it used to be cljsjs but from what I gather there’s been a lot of change in that space recently

johanatan18:09:34

cljsjs is still the first resort if there is one available

johanatan18:09:45

the only thing that has changed is npm module consumption

schmee18:09:35

right! I have very limited knowledge of the broader JS ecosystem (I’m a primarily a Clojure/Java guy), so safe to say I should stick to cljsjs then :thumbsup:

dpsutton18:09:20

Honestly I would go with shadow cljs. It makes npm interop so much easier

johanatan18:09:56

is that true with the recent cljs npm interop changes though? my understanding is that shadow is outmoded by the cljs way

dpsutton19:09:03

Yes it’s still true in my opinion.

dpsutton19:09:48

The other way requires setting up bundlers and I’m not sure the best way to do that. With shadow it’s a simple npm install and shadow does everything for you

johanatan19:09:15

yes the whole point of the cljs changes is to use webpack like the rest of the JS ecosystem does

johanatan19:09:25

there are tonnes of tutorials on how to set it up

johanatan19:09:40

but if i were starting a new project at this moment in time, i'd go that route for sure

Lone Ranger14:09:52

I will say that I am a simple dev and cljs+figwheel+reagent has gotten me very far, even with all the fancy features you mentioned. Here is a little self-inflated demo project that incorporates all of those things: https://github.com/jjtolton/rocinante That being said ... for anything MORE complex than the features I have here... I've been checking out the shadow docs and shadow is killin' it with features.

👍 3
johanatan18:09:44

does anyone know if it is possible to dynamically construct "qualified keywords" at reader / compile time ? ideally taking the form :ns/class/field

johanatan18:09:50

(i've tried both a macro and a tagged literal but neither will get evaluated prior to clojure spec's macro expansion time)

johanatan18:09:34

here is my reader implementation for details on what i'm trying to accomplish:

(defn read-ns-grouped-keyword [s]
  `(let [[group# kwd#] (clojure.string/split ~s #"/")]
    (keyword (clojure.string/join "/" [~(str *ns*) group#]) kwd#)))

johanatan18:09:11

used like so: #myns/ns-grouped-keyword "event/type"

johanatan18:09:55

cljs.user=> #myns/ns-grouped-keyword "event/type"
:cljs.user/event/type

thheller18:09:23

@johanatan :cljs.user/event/type is not a valid keyword, otherwise just ::event.type will be :current.ns/event.type?

johanatan18:09:49

it's valid. try it if you doubt me. that's an actual live repl session.

johanatan18:09:21

i have two requirements here: (name kw) must produce exactly type and it must be qualified by namespace and the word "event"

johanatan18:09:42

so: :cljs.user_event/type would also satisfy that

johanatan18:09:48

but aesthetically slash looks better

johanatan18:09:00

regardless whether you use underscore or slash though, the problem is the same

thheller18:09:49

I don't understand the problem statement. I looks to me like the slash is the only problem.

thheller18:09:16

::event.type will be fine while ::event/type will look for the event alias which probably doens't exist

thheller18:09:54

cljs.user=> ::event.type
:cljs.user/event.type

johanatan18:09:18

(name ::event.type) not= "type"

johanatan18:09:22

that does not satisfy my requirement

johanatan18:09:46

these are intended for use with :req-un and :opt-un of spec

johanatan18:09:55

and spec uses name to get the "name" portion of the kwd

johanatan18:09:27

the problem statement is that this needs to happen at reader expansion time or macro expansion time (prior to spec's own macro expansion time)

johanatan19:09:04

cljs.user=> (name ::event.type)
"event.type"
^^ that needs to say just: "type" rather than: "event.type"

johanatan19:09:51

e.g.,

cljs.user=> (name #myns/ns-grouped-keyword "event/type")
"type"

thheller19:09:39

why does it "need to say that"?

johanatan19:09:57

it's a requirement

johanatan19:09:12

my codebase has a bunch of existing data structures that i'm not keen on changing

johanatan19:09:25

the word "type" is used across many namespaces

johanatan19:09:53

i'm trying to retrofit clojure spec to an existing non-optimal (for spec) data model

thheller19:09:10

so the (namespace ::event.type) isn't actually a namespace?

johanatan19:09:24

correct, it's a "qualification"

johanatan19:09:34

which is a concatenation of an actual namespace and a "group"

thheller19:09:55

yeah don't think there is a built-in way to make that happen

johanatan19:09:22

of course there isn't. hence the question. i wouldn't be exploring macros and tagged literals if there were a built in way

thheller19:09:44

well maybe you should explore a custom spec impl 😛

johanatan19:09:58

the multi-spec section of this page uses a "non-namespace, qualified keyword": https://clojure.org/guides/spec

johanatan19:09:13

i.e., :event/type is a non-namespaced, qualified keywor

thheller19:09:09

I wrote an impl a long time ago that works on "unqualified maps" directly and not via spec :req-un

thheller19:09:58

definitely do not use that implementation but maybe something in that direction works better for your usecase?

johanatan19:09:38

i'm afraid i'd have to reimplement a lot. it'd be basically the whole "multi-spec" section of that clojure guide

thheller19:09:24

mutli-spec works just fine with this?

johanatan19:09:07

works just fine with what?

thheller19:09:59

/ has special meaning in symbols. It can be used once only in the middle of a symbol to separate the prefix (often a namespace) from the name

johanatan19:09:13

i'm not using edn and this isn't really a symbol

johanatan19:09:17

it's a qualified keyword

johanatan19:09:29

but once again if you really quibble over the "/", it can be a "_"

johanatan19:09:34

no harm no foul

johanatan19:09:32

spec doesn't care about the difference between: :event/type and :my-ns_event/type

johanatan19:09:48

the latter is to prevent collisions between namespaces

thheller19:09:59

I'm not trying to quibble over anything. I'm pointing out that you are actively trying to fight the system and namespace and names. nothing in clojure will let you do that easily. of course you can do so but I would still warn you strongly against doing so since it will most likely need to more trouble in the future somewhere

johanatan19:09:18

ok, so then "_" it is

johanatan19:09:21

no fight, yes?

johanatan19:09:31

now you can join me where I'm at without objection

johanatan19:09:13

there is "no fighting the system". there is only "dynamically creating qualified keywords at reader/compile time"

johanatan19:09:21

which is precisely what my original question pertained to

thheller19:09:27

I thought you solved that with the reader fn?

johanatan19:09:35

no, the problem is that it works in the repl

johanatan19:09:44

but in source code, it just gets expanded

johanatan19:09:54

and then spec complains that it received a "form"

johanatan19:09:57

rather than a keyword

johanatan19:09:08

and the fact that cljs has no "eval"

johanatan19:09:17

prevents me from actively "evaluating" it myself

thheller19:09:31

reader fns are eval'd at read-time not at runtime?

johanatan19:09:48

that's not what i'm seeing in practice. looks like they are merely expanded

thheller19:09:01

you are returning a form in your reader fn

thheller19:09:08

skip the leading backtick 😛

thheller19:09:16

just return the keyword instance

johanatan19:09:22

hmm, i thought that would work but i got a weird crash when i tried that

johanatan19:09:30

let me try again

johanatan19:09:27

(that was how all examples I've seen do it so I figured it must be part of the contract)

johanatan19:09:45

i.e., all examples return forms not instances

thheller19:09:03

well yeah but the keyword is the form you want?

johanatan19:09:15

hmm, looks like you may be right

johanatan19:09:19

i think it's working!

johanatan19:09:46

yep, it's definitely working

johanatan19:09:59

thanks for your help!

johanatan19:09:17

my repl must have been in some weird state or some other problem was interfering when I tried this yesterday

johanatan19:09:33

2nd time's a charm apparently

johanatan19:09:36

one other weird thing though. the compiler actually complains about my data_readers.cljc. about both "no such namespace" and "undeclared var". seems spurious as the actual code works fine at runtime