Fork me on GitHub
#beginners
<
2022-07-21
>
dumrat03:07:56

Hi, I heard that logging is messy in Clojure and there's different libraries. I don't wanna spend much time on it and just want something to work with minimal effort. What should I look at?

bocaj03:07:24

Yes, eventually java libraries will log in a way you need to handle. This was helpful for me: https://lambdaisland.com/blog/2020-06-12-logging-in-clojure-making-sense-of-the-mess

👍 2
1
manas_marthi07:07:48

In my opinion, logging is a chore and keep it as familiar as possible to new comers from Java. I use log4j2 with log4j2.xml to give config. There is no point in trying to have idiomatic clojure config. Log configuration is a one time activity. Keep it in a familiar xml format

Pagoda 5B07:07:31

OTOH java logging’s legacy’s such a pain. Not to say that today’s apps would better be served by something which combines logging/tracing more than traditional logging, which came from another development landscape, made of closed-walls enterprise systems

seancorfield16:07:35

We like log4j2 + clojure.tools.logging (as noted briefly in that article) because you can avoid XML for configuration and easily provide dev/test overrides via env vars and system properties. It can also watch and reload the config when it changes (we use this in dev but not production). One day I swear I'll write this up in a blog post, building on the Lambda Island post! 🙂

lambda-prompt 2
1
manas_marthi07:07:42

1) Is next jdbc available on maven central?

manas_marthi07:07:59

2)Is there any library to compare 2 collections? I need to compare 2 lists of maps and report the mismatches?

Ben Sless09:07:46

There's clojure.data/diff built in

Julien Dubois12:07:35

Hello, I often hear that repl clojure is excellent, but what is better than the others?

teodorlu12:07:20

• Anything you can do in a file, you can do in a REPL • The whole language is designed to make the REPL great.

teodorlu12:07:43

The first page of the official REPL guide explains things better than I can :) https://clojure.org/guides/repl/introduction

teodorlu12:07:05

For me, the most important effect of the clojure REPL on my workflow is the ability to get instant feedback on basically anything. That makes my learning loop faster than in other languages.

kennytilton12:07:28

What "others" are you thinking of, specifically?

Ed13:07:55

Plus one to "the whole language is designed to make the REPL great". This includes the way namespaces and vars work, to the focus on data and pure functions. The further you get from data + fns the more painful everything gets. This, to me, includes things that are irreplaceable in other languages, like dependency injection containers - if you feel like you need one, you may have strayed too far from the way of the REPL (end of controversial opinion ;) )

cyppan16:07:59

I was discussing about this with you previously and I think that the main difference is that Clojure makes it easy to reload parts of your codebase, including single vars (you have to delete the module cache in nodejs for instance when you reload a module). That being said, I tend to prefer the compile + watch + restart whole app workflow that usual node tools tend to propose (comparing with node js/ts here). When the transpiling / app init is fast it is more convenient IMO (you cant forget reloading things on your repl)

teodorlu17:07:32

@U030H8RLWUU did that answer your question?

Julien Dubois07:07:51

Yes, it did thank you

👍 1
Julien Dubois07:07:56

@U0PUGPSFR I especially thought about Python or NodeJS ones

👍 1
Muhammad Hamza Chippa15:07:32

I am trying to use material UI in the shadow-cljs. How can I replicate the same component using clojurescript ?

const StyledTableCell = styled(TableCell)(({ theme }) => ({
  [`&.${tableCellClasses.head}`]: {
    backgroundColor: theme.palette.common.black,
    color: theme.palette.common.white,
  },
  [`&.${tableCellClasses.body}`]: {
    fontSize: 14,
  },
}));

Drew Verlee02:07:34

Check the shadow docs for how to import js code. From there it depends on what cljs react wrapper you're using.

Chase18:07:50

How are folks deploying their full stack web apps these days? I was using Heroku but am looking for alternatives. I'm not seeing java support, let alone Clojure/script support, on any of the newer options like , , or . I'm thinking those may still be an option by using a dockerfile but was curious if you folks have any experience here. Or are folks doing it all on their own with like Digital Ocean droplets and such?

ahungry19:07:00

I use rsync to linode vps for my personal stuff

Ed19:07:34

AWS CDK

athomasoriginal19:07:13

Dokku on Digital Ocean and I even have a setup where I run everything outside of containers as well.

athomasoriginal19:07:36

Dokku is primarily helpful for managing the lifecycle of your app in prod.

athomasoriginal19:07:57

http://fly.io also supports deploying a Dockerfile (which you mentioned) and that is straightforward to setup.

Jacob O'Bryant20:07:37

Yeah pretty sure you can use Clojure an any of those platforms via Dockerfile. I looked at all three of those (and digitalocean's app platform) but ended up just sticking with droplets. I have a https://github.com/jacobobryant/biff/blob/master/example/setup.sh that I copy into all my projects, which (among other things) sets up git push-to-deploy. Easy enough once you get the script how you like it 🤷 @U6GNVEWQG I'm curious if you're able to connect to your production app via nrepl? I spent a day trying out dokku but could never get it to work, IIRC because dokku by default only allows HTTP connections to the container.

athomasoriginal01:07:51

I haven't tried yet. Will let you know!

👌 1
chucklehead01:07:39

Deploying a Kit project to http://fly.io right now using the Dockerfile option. I've also deployed to fly using Jibbit to build an image and push it to their private registry.

Chase01:07:40

I'm still unfamiliar with Docker and haven't liked using it on my own system. But in this case, are you literally just creating a Dockerfile in your repo and http://fly.io uses it internally? So I technically wouldn't need to use Docker during development, just create the file for to recognize and use?

Chase01:07:15

It looks like 's free tier only gives you 256 mb of RAM. Is that enough to test out a hobby project? I guess it's only $6/month for 1gb of RAM but just curious. 's free tier is 512 mb (they were great when I used with rust apps) and they also accept Dockerfiles but their 1gb is $15/month

Chase01:07:22

If you folks could share your dockerfiles I would greatly appreciate it but no worries if not

athomasoriginal02:07:13

Yeah, I don't dev in Docker. I just deploy with it and that's only because it's "easiest".

chucklehead02:07:00

I don't have a public repo I can share right now, but this is the template Dockerfile that Kit uses for new projects, which is basically what I'm using right now. You could adapt it for something else by replacing the RUN command with whatever you use to build an uberjar, and updating the COPY and ENTRYPOINT paths to reference the right jar file name/paths.

# syntax = docker/dockerfile:1.2
FROM clojure:openjdk-17 AS build

WORKDIR /
COPY . /

RUN clj -Sforce -T:build all

FROM azul/zulu-openjdk-alpine:17

COPY --from=build /target/<<name>>-standalone.jar /<<name>>/<<name>>-standalone.jar

EXPOSE $PORT

ENTRYPOINT exec java $JAVA_OPTS -jar /<<name>>/<<name>>-standalone.jar
With this Dockerfile in the project root I was able to generate a new Fly app with flyctl launch and can deploy with flyctl deploy. The only change I had to make was adding a PORT environment variable to the fly.toml file to set the container's HTTP listening port to 8080 to match Fly's default.

Chase16:07:15

Great info here, thanks so much everyone

🙂 1
Jacob O'Bryant23:07:22

Hey, apparently Railway supports Clojure without a Dockerfile as of today: https://railway.app/changelog/2022-07-22#clojure-langauge-support

Chase19:07:08

Just to follow up, I was able to get a full stack clj/cljs app deployed on using a Dockerfile so it should be usable on all the other platforms we were discussing. It also has tailwind w/ hot code reloading too if others have been wanting to figure out how to do that. https://github.com/Chase-Lambert/clojure-app-template

Chase20:07:19

Please note I don't know how to create an official template so I still have to manually edit all the TODO occurrences to match the name of the desired app/repo so if you know how to automate that, I'm all ears.

Fra19:07:02

Hi, I am using ring-mock to test a ring api, as soon as I introduced muuntaja my test is failing for this reason

actual: (not (= {:status 200, :headers {"Content-type" "text/json", "Content-Type" "application/json; charset=utf-8"}, :body #object[java.io.ByteArrayInputStream 0x7213ff15 "java.io.ByteArrayInputStream@7213ff15"]} {:status 200, :headers {"Content-type" "text/json"}, :body {:text "Something", :listId 1}})
Do you generally tend to use ring-mock or you test the apis using http (more like an integration test)? I'd like to have both the kind of tests but I don't know how to work around the issue caused introducing muuntaja.

seancorfield20:07:03

I tend to test the code my handlers call (and make an effort to keep the handlers "simple") and I test the API directly, using an HTTP client library (so I unit test the business logic and do end-to-end testing on the API itself).

seancorfield20:07:46

I have a few tests directly against handler functions, but I don't use ring-mock for those -- I just pass in a hash map with the appropriate data.

Ben Lieberman22:07:45

If I'm processing strings, would it be an appropriate usage of defmulti as a way to dispatch on different regex patterns? Or is there a simpler way to do that?

dpsutton22:07:58

can you sketch out what you’re thinking?

Ben Lieberman22:07:14

I want a function that takes strings, splits on a generic regex pattern, and processes the substrings according to arbitrary logic. I was thinking the most idiomatic way to do that would be recursively, i.e. input is the contents of the Moby-Dick ebook, I split on \n, do some work, split on \s , do some more work, etc

Ben Lieberman22:07:02

But then I was thinking defmulti might also be an option?

dpsutton22:07:08

Defmulti takes a single dispatch function. So is this a regex that matches a word and you have implementations for different words? Or do you envision running several regexes and then doing something on the first one that matches?

Ben Lieberman22:07:30

the former case

dpsutton22:07:40

makes sense. I often find it helpful to run a bit of analysis over things to make a bit more structured data on top of strings

dpsutton22:07:27

then you can dispatch on some token in your structured data and gives you a bit more chance to put more logic there rather than only dispatching on what a regex can do with a string

Ben Lieberman22:07:14

this is definitely just a toy project while I take a "tour" of clojure (which is a really cool language so far it seems) but that is essentially the idea. The ultimate project idea is to do ELisp-y text processing macros for editing, ie something like a macro that could remove repetitive word usages