beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
Micah Redding 2021-02-10T00:53:35.377600Z

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.

phronmophobic 2021-02-10T00:56:33.378600Z

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

phronmophobic 2021-02-10T00:57:21.379100Z

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

❤️ 1
phronmophobic 2021-02-10T01:00:08.380600Z

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.

❤️ 1
zackteo 2021-02-10T01:25:45.381900Z

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\"]}"`

seancorfield 2021-02-10T01:31:51.383400Z

@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).

seancorfield 2021-02-10T01:32:28.384200Z

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

zackteo 2021-02-10T01:33:31.385300Z

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

seancorfield 2021-02-10T01:33:55.385800Z

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

seancorfield 2021-02-10T01:35:11.388600Z

@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?

zackteo 2021-02-10T01:35:16.389Z

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

2021-02-10T01:38:16.393100Z

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

seancorfield 2021-02-10T01:42:33.394100Z

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

seancorfield 2021-02-10T01:43:05.394800Z

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

phronmophobic 2021-02-10T01:43:24.394900Z

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

phronmophobic 2021-02-10T01:43:44.395200Z

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

seancorfield 2021-02-10T01:44:26.395600Z

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=> 

👏 1
zackteo 2021-02-10T01:45:56.395700Z

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:

phronmophobic 2021-02-10T01:48:21.396Z

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

zackteo 2021-02-10T01:54:59.396300Z

Thanks! But wow seems like a lot to take in

2021-02-10T01:57:09.396700Z

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

phronmophobic 2021-02-10T01:57:20.396800Z

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

Zaymon 2021-02-10T02:19:05.398100Z

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?

Zaymon 2021-02-10T02:21:04.398200Z

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

2021-02-10T02:55:29.398400Z

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).

👀 1
Zaymon 2021-02-10T03:09:24.398900Z

Thanks for that 🙂

Yang Xu 2021-02-10T03:20:59.399300Z

The example code is the same as the previous question, I defined Inner class defmethod like this:

(defmethod j/from-java QueryReq$Aggregation [agg]
  (println "ac:"))
But "ac:" don't print, so that makes me feel that my defined function don't be called.

sova-soars-the-sora 2021-02-10T04:31:28.400700Z

...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?

raspasov 2021-02-10T08:48:47.408600Z

React Native

raspasov 2021-02-10T08:49:40.408800Z

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

raspasov 2021-02-10T08:56:12.409Z

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-sora 2021-02-10T20:23:23.416800Z

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

sova-soars-the-sora 2021-02-10T20:23:43.417Z

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

borkdude 2021-02-10T07:17:12.404900Z

@zaymon.a.fc 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

✅ 1
Zaymon 2021-02-10T07:18:18.405100Z

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.

Zaymon 2021-02-10T07:18:28.405300Z

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

borkdude 2021-02-10T07:21:30.408100Z

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

Marcus 2021-02-10T09:14:30.410100Z

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

phronmophobic 2021-02-10T09:26:52.410300Z

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]) 

👍 5
Marcus 2021-02-10T09:45:06.410700Z

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

Marcus 2021-02-10T09:45:09.410900Z

thanks

2021-02-10T14:19:05.413200Z

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 🙂

2
Chase 2021-02-10T17:40:50.413800Z

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.

nmkip 2021-02-10T18:04:21.413900Z

What tutorial are you doing?

Chase 2021-02-10T18:10:44.414100Z

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-sora 2021-02-10T20:28:47.417500Z

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

sova-soars-the-sora 2021-02-10T20:33:48.417700Z

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.

ej 2021-02-10T20:54:22.420Z

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?

2021-02-11T08:00:12.450200Z

https://github.com/prepor/liveview-clj Another prototype

👍 1
Mno 2021-02-11T08:10:18.450500Z

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

kwrooijen 2021-02-11T08:11:58.450700Z

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

kwrooijen 2021-02-11T08:12:06.451100Z

Which will probably be my weekend project 🙂

kwrooijen 2021-02-11T08:12:52.451400Z

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

kwrooijen 2021-02-11T08:15:59.451700Z

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.

tatut 2021-02-11T08:56:46.452200Z

cool, I didn’t know about liveview-clj

tatut 2021-02-11T08:58:24.452400Z

seems most clj solutions are in various stages of alpha

borkdude 2021-02-11T08:59:19.452600Z

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

tatut 2021-02-11T08:59:27.452800Z

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

2021-02-11T08:59:52.453Z

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

kwrooijen 2021-02-11T08:59:53.453200Z

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

tatut 2021-02-11T08:59:59.453400Z

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

tatut 2021-02-11T09:01:42.453600Z

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

tatut 2021-02-11T09:02:38.453800Z

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

kwrooijen 2021-02-11T09:02:40.454Z

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

borkdude 2021-02-11T09:41:43.454200Z

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

kwrooijen 2021-02-11T09:55:04.454400Z

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 🙂

2021-02-11T10:04:27.454800Z

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

kwrooijen 2021-02-11T10:11:06.458300Z

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

borkdude 2021-02-11T10:11:59.458500Z

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

borkdude 2021-02-11T10:12:10.458700Z

just a syntactical convenience probably

2021-02-11T10:18:01.458900Z

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

borkdude 2021-02-11T10:20:08.459200Z

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 ;)

borkdude 2021-02-11T10:21:13.459600Z

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

borkdude 2021-02-11T10:21:35.459800Z

I find it an interesting old/new approach

2021-02-11T10:23:54.460Z

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

borkdude 2021-02-11T10:25:50.460200Z

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

2021-02-11T10:30:04.460400Z

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

2021-02-11T10:44:50.460600Z

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

clyfe 2021-02-11T10:57:38.463Z

less complicated than SPWA https://youtu.be/OltCr8AWpWw?t=462

clyfe 2021-02-11T11:02:01.463200Z

That talk is gold.

clyfe 2021-02-11T11:05:17.463400Z

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.

ej 2021-02-11T16:54:00.489200Z

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-sora 2021-02-11T21:26:01.005200Z

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.

clyfe 2021-02-10T21:36:25.422100Z

You can use it with any backend.

Chase 2021-02-10T22:57:06.426800Z

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.

Chase 2021-02-10T22:57:28.427Z

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-sora 2021-02-10T23:04:46.427200Z

try it on the slowest device you have

sova-soars-the-sora 2021-02-10T23:09:31.427400Z

That's an interesting tool...

borkdude 2021-02-10T23:17:47.427600Z

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

borkdude 2021-02-10T23:20:02.428500Z

another conversation here: https://twitter.com/martensytema/status/1346364415034224641