Fork me on GitHub
#beginners
<
2021-02-10
>
Micah Redding00:02:35

I’m trying to switch from Cegdown (a Clojure wrapper for Java Pegdown) to https://github.com/vsch/flexmark-java (the Java library recommended to replace it). The relevant Java import looks like this: import com.vladsch.flexmark.html.HtmlRenderer; I can only get Flexmark to load in my dependencies, if I include “flexmark-all” as such: :dependencies [[com.vladsch.flexmark/flexmark-all "0.62.2"]] But I cannot figure out how to require it successfully in the relevant contexts. Here’s what I’m trying: (:require [com.vladsch.flexmark.html.HtmlRenderer :as md2]) Here’s the error I get: Could not locate com/vladsch/flexmark/html/HtmlRenderer__init.class, com/vladsch/flexmark/html/HtmlRenderer.clj or com/vladsch/flexmark/html/HtmlRenderer.cljc on classpath. Obviously, I’m missing how something here fits together.

phronmophobic00:02:33

com.vladsch.flexmark.html.HtmlRenderer is a java class. your ns should have an import declaration: (:import com.vladsch.flexmark.html.HtmlRenderer)

phronmophobic00:02:21

If you're not familiar with java interop, you may want to check out https://clojure.org/reference/java_interop

❤️ 4
phronmophobic01:02:08

I've been using flexmark to render my blog posts. It's worked well for me. You can check out https://github.com/phronmophobic/blog/blob/master/src/blog/mdown.clj if you'd like to see an example of using flexmark from clojure. My code is not* well documented, but maybe you'll find the example useful.

❤️ 4
zackteo01:02:45

How do I best create a backend API call to return edn from a ring backend (back to a clojurescript webapp)? Can I just put edn in the `:body` of a route? That gives me some errors. Do I wrap it in a string like `"{:test [\"test\"]}"`

seancorfield01:02:51

@zackteo I searched for ring edn middleware and saw this: https://github.com/tailrecursion/ring-edn -- and in the examples it looks like they are just doing :body (pr-str data) (the library seems focused just on decoding EDN from the request body).

seancorfield01:02:28

And I guess just calling pr-str on Clojure would produce EDN so maybe it is just that simple.

zackteo01:02:31

Perhaps a silly question but is edn not the standard that is used for a clojure stack?

seancorfield01:02:55

(I've only ever dealt with sending/receiving JSON since I have a Clojure backend but our frontend is JS)

seancorfield01:02:11

@zackteo Clojure has clojure.edn/read-string but there's no (`clojure.edn`) print-string because (`clojure.core`) pr-str does the job. I don't know what folks do for a MIME type when send EDN back to the browser?

zackteo01:02:16

I see I see! Yeap looks like it really is that simple read-string and pr-str

phronmophobic01:02:24

I've used edn for communication between front end and back end, but I used https://github.com/cognitect/transit-clj for serialization since that's what it's purpose is

phronmophobic01:02:44

It probably doesn't matter too much if you're not exchanging a lot of data

zackteo01:02:56

When will you use transit tho? I know people also use https://github.com/dakrone/cheshire . But won't this only be used if say the frontend needs to receive JSON? :thinking_face:

phronmophobic01:02:21

I haven't used chesire. here's the rationale for transit: https://cognitect.com/blog/2014/7/22/transit

zackteo01:02:59

Thanks! But wow seems like a lot to take in

phronmophobic01:02:20

read-string and pr-str work well too. It can be something to look into if you'd like to improve the edn serialization.

Enrico Teterra01:02:16

i have a list of lists [["bob" 17]..] and a record (defrecord person [name age]), question: how do i convert all items in the list to the record? map ->person ,,, doesn't seem to do it since it passes the whole list as an arg

seancorfield01:02:33

(apply ->person data) will convert an individual vector.

seancorfield01:02:05

so (map #(apply ->person %) list-of-lists) should do what you need @enrico.teterra

seancorfield01:02:26

user=> (defrecord person [name age])
user.person
user=> (def list-of-lists [["Bob" 17] ["Sean" 58] ["Jay" 60]])
#'user/list-of-lists
user=> (map #(apply ->person %) list-of-lists)
(#user.person{:name "Bob", :age 17} #user.person{:name "Sean", :age 58} #user.person{:name "Jay", :age 60})
user=> 

👏 4
Enrico Teterra01:02:09

ahh i knew there was a simple way =) thanks Sean

Zaymon02:02:05

Working with hugsql in Calva, and CLJ-Kondo keeps giving me this error even though the docs for the function prove it wrong, has anyone encountered this and know how to fix it?

Zaymon02:02:04

Resolved. I just deleted the .clj-kondo folder containing it’s cache and it seems to be fine now

andy.fingerhut02:02:29

FYI this is a perfectly reasonable channel to ask such questions, but if in future you have questions that might be specific to clj-kondo there is also a #clj-kondo channel that is likely to hit active users (and even its developer).

👀 4
Zaymon03:02:24

Thanks for that 🙂

borkdude07:02:12

@U01D4A7PJG7 the reason clj-kondo doesn’t know about this var is that is generated by some macro it doesn’t understand. You can configure clj-kondo to ignore these vars. If you delete the entire .clj-kondo dir with also the config in it you will get less information from it

4
Zaymon07:02:18

I didn’t delete the config. Although the issue only happened with one specific var generated from the macro and not all of them, which was why I was confused.

Zaymon07:02:28

After clearing the cache it worked and didn’t complain any more

borkdude07:02:30

Ok, I think it will start to complain again though after you have visited the hugsql related namespace since kondo thinks it knows all about the vars in that namespace. See this conversation on how to ignore this ns. https://clojurians.slack.com/archives/CHY97NXE2/p1612389637097500

sova-soars-the-sora04:02:28

...so I want to turn a website that mainly serves html and also serves javascript... into a phone app. What's the state of the art in the clojureSphere for native apps?

raspasov08:02:47

React Native

raspasov08:02:40

But that would not be as simple as “turning html+javascript into a phone app”… to use React Native you pretty much have to start from scratch

raspasov08:02:12

If you do start with React Native, there’s react-native-web, which can allow you to serve/create a website from the same codebase https://github.com/necolas/react-native-web (I haven’t used it myself)

sova-soars-the-sora20:02:23

yes that would be the ideal ... one source code folder to rule them all

sova-soars-the-sora20:02:43

it's like we just didn't see multiple screen sizing coming xD

Marcus09:02:30

Is it possible somehow to access the previous element in the map function (I guess I could use map-indexed and get)

phronmophobic09:02:52

one trick is to utilize map 's extra args:

(let [xs (range 5)]
  (map (fn [a b]
         [a b])
       xs (next xs)))
;; ([0 1] [1 2] [2 3] [3 4]) 

👍 15
Marcus09:02:06

Ah.. yes because fn receives one element from each collection. neat.

afry14:02:05

Good morning everyone! I'll be livestreaming another coding challenge at 9:45 AM EST today if you'd like to join. Today's challenge comes from another Eric Normand newsletter, you can find it at the bottom of this blog post: https://purelyfunctional.tv/issues/purelyfunctional-tv-newsletter-409-3-stakeholders-model/ And here is the link to the livestream: https://www.twitch.tv/a_fry_ Have a nice Wednesday 🙂

clj 6
Chase17:02:50

I'm just finishing up a Reagent tutorial and we use Chrome's lighthouse to check performance. The tutorial shows him getting an 88% but I'm getting a 69% and it is saying it is because I haven't removed unused js. But we use Shadow CLJS and the tutorial says the release command compiles it using Google Closure to do DCE and tree shaking for us. The tutorial's lighthouse assessment doesn't give that "unused js" warning so not sure why I didn't get the performance benefit.

nmkip18:02:21

What tutorial are you doing?

Chase18:02:44

Jacek Schae's Reagent Pro course. It's been great. I'm excited to move on to his other one's now too.

sova-soars-the-sora20:02:47

lighthouse to check performance... interesting... don't know what that is -- thanks for the keywerd

sova-soars-the-sora20:02:48

I have noticed that compiling into cljs has some "sweet spots" where sometimes everything lines up perfectly under the little surgical switchblades of the compiler and it: compiles very fast, and the size is very small. then you add one character or one variable and suddenly it takes the standard time and the file size is bigger by a lot... which is usually not a problem because it's still lightning fast, but yeah, it's weird that there are resonant nodes in the compile process but also not that weird.

Chase22:02:06

Yeah Lighthouse is part of Chrome dev tools. Just right click on any webpage, click inspect, and it's the last tab. Pretty cool. The reagent site had great Accessibility, "Best Practices", and SEO score btw. Pretty cool as it doesn't seem we did anything purposely to get those good scores.

Chase22:02:28

I'm just bummed at the bad performance rating even though tbh, I don't notice anything while I'm actually using the site.

sova-soars-the-sora23:02:46

try it on the slowest device you have

ej20:02:22

Not sure if this is the place to ask, but I'm doing a little bit of research in order to ... not have to write a SPA, and I came across this: https://hotwire.dev/ Is there anything stopping me from using that with a Clojure back end producing HTML? Does anyone here have any experience with it?

clyfe21:02:25

You can use it with any backend.

sova-soars-the-sora23:02:31

That's an interesting tool...

borkdude23:02:47

I've seen some people experiment with this. I think one of them was @U050RCD9L. @U11SJ6Q0K also did related work to this.

tatut05:02:23

yeah, I have made ripley https://github.com/tatut/ripley which tries to be a similar experience to writing reagent but on the backend

Mno08:02:18

Theres a couple of libraries wrapping turbo and stimulus made by @UG9U7TPDZ, dunno how ready they are yet, haven't had time to check

Kevin08:02:58

I'm using them currently but I still need to write some more documentation. https://github.com/kwrooijen/clj-stimulus https://github.com/kwrooijen/clj-turbo

Kevin08:02:06

Which will probably be my weekend project 🙂

Kevin08:02:52

Also working on a project to wrap this all together (kind of like Hotwire) to make it easy to use in Clojure

Kevin08:02:59

Which is this: https://github.com/kwrooijen/gram But it has no documentation at all and I'm probably going to change a lot in the near future.

tatut08:02:46

cool, I didn’t know about liveview-clj

tatut08:02:24

seems most clj solutions are in various stages of alpha

borkdude08:02:19

comparable to the beginning of React times where we had several competitors: Quiescent, Rum, Reagent, Om, ...

tatut08:02:27

ripley is also a side project, but I’m hoping to use it in actual work someday (hopefully soonish)

delaguardo08:02:52

liveview-clj not even in alpha stage. it was build as a 1-day prototype/POC

Kevin08:02:53

I'll be happy if we can just get out of SPA hell 😄

tatut08:02:59

yes, it’s good to have multiple different solutions and people exploring the solution space in different ways

tatut09:02:42

I also have a great aversion to the JS/npm ecosystem born through pain that I’d like to get away from

tatut09:02:38

that said, React is a mature and feature rich piece of software that can’t be trivially replaced

Kevin09:02:40

It's very hard to avoid javascript in frontend development though

borkdude09:02:43

Usually when I need a bit of JavaScript, the desire for React grows after 10 loc....

Kevin09:02:04

Yeah writing raw JS is terrible. And react / reagent has made it easier. I do think Hotwire has done a good job in solving this in a SSR manner. So I'm looking forward to properly releasing these projects 🙂

delaguardo10:02:27

btw, liveview-clj is using this library for writing lisp-like javascript expressions - https://github.com/nilern/scriptjure

Kevin10:02:06

What's the purpose of using this? So that the JS isn't bloated? (like it would be with CLJS)

borkdude10:02:59

Maybe a convenient way of writing JS instead of sending those raw JS forms by hand?

borkdude10:02:10

just a syntactical convenience probably

delaguardo10:02:01

my use case: • need a way to generate and inject small portion of javascript code on server side • should not be expressed as string manipulation function • must be possible to parameterize outcome • ideally but optional, code should be maintainable scriptjure fit really well into those constraints

borkdude10:02:08

maybe you can also send some CLJS to the client and interpret using sci... this will add more bloat to your bundle size (~ 120kb gzipped) and will be less performant, but it's a fun idea ;)

borkdude10:02:13

but I guess the idea of this liveview setup is to not need any CLJS / JS tooling at all anymore right

borkdude10:02:35

I find it an interesting old/new approach

delaguardo10:02:54

idea of liveview is to manage the state on backend side by managing web-socket connection everything on top (like “generating html on backend and send it to client” or “remove js from frontend”) are an extension to that model

borkdude10:02:50

it sounds cool, but it also sounds like it can get complicated, like the server has to manage the state of all connected clients. what if it gets out of sync? that can get really messy I assume

delaguardo10:02:04

there is enough control to prevent it getting out of sync + the state is implemented as an abstraction, it is always possible to keep the data somewhere else like DB. but as I said this lib is nothing more than just a POC

delaguardo10:02:50

forgot to mention — under “enough control” I mean there is a way to use CRDT to manage state changes on backend side, I’m working on that in my fork

clyfe11:02:01

That talk is gold.

clyfe11:02:17

The microservices part is interesting-funny, how Rails did it back in ~2008 and saw how bad it goes and removed it (https://github.com/rails/activeresource) and then the whole industry jumped on them.

ej16:02:00

I went to bed after writing this, and I was really surprised to see all of these different projects. This is very interesting! Thanks :)

sova-soars-the-sora21:02:01

So it looks like we are stuck with the DOM -- browsers love the dom, i don't know of any alternatives. Then, we need a dynamic way to intercept user events, modify the css of the dom, and connect with a server.... I am surprised there is not something cleaner than JS to serve this purpose yet. But again, we have the DOM... if there were a more generalistic way to make applications that could be mobile/desktop/tablet that would be great, but i suppose a lot of mobile manufacturers (android, apple) would probably not want unrestricted access to interception of events... a new standard would be hard to get adopted, but i wonder if there is a better way.