Fork me on GitHub
#beginners
<
2023-04-27
>
pppaul04:04:44

are any clojure libraries popular? vvvvvalvalval makes some nice tools. if you find that it does what you want, and you think the code looks ok, why would it matter if it's popular?

pppaul04:04:22

this library is specifically for development. probably shouldn't be part of your project, but part of your clojure/deps.edn (personal deps)

👍 2
James Amberger12:04:06

Does a tree make a sound when it fallss?

Luke Johnson15:04:31

I’ve never heard of this library, but it seems very useful to keep in my toolbox. I’ll be adding it to my clojure/deps.edn!

pppaul17:04:54

@U032EFN0T33 i personally supervise all falling trees to make sure they do indeed make sounds, and when they try to avoid doing so i report them to the physics enforcement police

Sam09:04:41

I'm trying out nicer destructuring with Compojure, when getting json by a post request. Right now I have this, which works

(defn example-handler
  "
  [{body :body}]
  body)

(comp/defroutes app-routes
  (comp/POST "/example" []  example-handler))

(def app
  (-> app-routes
      (rjson/wrap-json-body)
      (rjson/wrap-json-response))
However, I would like to destructure the body in the defroutes call, something like this
(comp/defroutes app-routes
  (comp/POST "/example" [body]  (-> body walk/keywordize-keys example-handler)))
However that doesn't work, and it's not clear to me from the docs how to do it. Any suggestions? 🙂

Ed09:04:26

If you have a map with strings as keys you can skip the keywordize-keys step by using :strs in the destructuring : https://clojure.org/guides/destructuring#_associative_destructuring or you could move the keywordize-keys into the middleware?

Sam09:04:07

Cool, that's convenient! How do I get the body from the request in the compojure line? This does not work:

(comp/POST "/example" [body] ...
That was my primary concern, but I realize that wasn't clear.

kennytilton10:04:07

ChatGPT suggests:

(defroutes app
  (POST "/my-endpoint" request
    (let [body (:body request)]
      ...your code here...)))
🤷 I'll go look again for examples....

kennytilton10:04:33

Found this:

(compojure/POST "/echo" {body :body} (slurp body))

Sam11:04:17

That worked! As simple as one could ever hope 🙂

kennytilton11:04:47

Heh-heh, I hate these "magic" libraries with their magic syntax!!! Pretty slick once we get over the learning bump. Ah, I belatedly found this doc (looked at the API doc first): https://github.com/weavejester/compojure/wiki/Destructuring-Syntax

Sam11:04:31

I was reading that page as well, trying things like

(GET "/user" {{:keys [user-id]} :session}
  (str "The current user is " user-id))
but never found the right thing.

kennytilton11:04:30

One thing I like to do once I see an example without syntax sugar, such as:

(GET "/" request
  (str request))
...is try printing (keys request), just to fight my way into what I want, no sugar involved. Once I see the request internals, I might go back and try the sugar. The next issue then is sorting out the Ring middleware, because that ^^^ probing may not find nice Clojure structure all the way down. But ince we see a JSON string we can still convert that using some Clojure hack or other. https://github.com/weavejester/compojure/wiki/Middleware

❤️ 2
Ed13:04:33

If you (macroexpand '(comp/POST "/example" [body] (-> body walk/keywordize-keys example-handler))) you can see that the form [body] is used as a destructuring assignment for the request.

(compojure.core/make-route :post #clout.core.CompiledRoute{:source "/example", :re #"/example", :keys [], :absolute? false} (clojure.core/fn [request__2386__auto__] (compojure.core/let-request [[body] request__2386__auto__] (-> body walk/keywordize-keys example-handler))))
So anything that extracts the :body key will work.

Sam13:04:01

Thanks to you both! I will remember macroexpand for the future. I've heard about it, I just never considered using it 🙂

Hendrik09:04:59

I am struggeling with a simple cljc file:

(ns foobar
  (:require #?(:clj [some.thing :as xt] :cljs [some.other.thing]))

#?(:clj (def foo ::xt/bar))
If i try to compile this as clojurescript, then it will fail on the statement #?(:clj (def foo ::xt/bar)) . It complains Invalid keyword: ::xt/bar Why is this the case? Is ::xt resolved at readtime? Or am I missing something here?

Ed09:04:04

Yes ::xt/bar is expanded at read time to be a fully qualified name.

Clojure 1.11.1
user=> (read-string "::test")
:user/test

Hendrik09:04:50

Ok. Thanks 🙂 .

genenakagaki10:04:36

Hello, I am having trouble running classes generated by Clojure in Java. I have this in my clojure file

;;; myapp/core.clj
(ns myapp.core
  (:require [myapp.flow :refer :all]
            [myapp.schema :refer :all]
            [myapp.validation :refer :all]
            [clojure.pprint :refer [pprint]]
            [malli.core :as m]
            [malli.generator :as mg]
            [myapp.interop])
  (:gen-class
   :name myapp.core.MyClient
   :prefix "client-"
   :methods [^{:static true} [startFlow [myapp.interop.MyRepository Long] String]
             ^{:static true} [registerFlowStepResult [myapp.interop.MyRepository
                                                      Long
                                                      String]
                              String]])
  )
  
;;; myapp/interop.clj
(ns myapp.interop)

(gen-interface
 :name myapp.interop.MyRepository
 :methods [[isPenaltyMember [Long] Boolean]])
I use lein so I ran lein uberjar and put it under the Java classpath using gradle. In Java, I'm doing this.
package com.myapp.service;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import myapp.interop.MyRepository;
import myapp.core.MyClient;

@Service
@RequiredArgsConstructor
public class MyAppServiceImpl implements MyAppService {

    private final MyRepository myRepository;

    @Override
    public String startFlow() {
        return MyClient.startFlow(myRepository, 1L);
    }
}
Any help would be very appreciated!

genenakagaki10:04:51

I get this error when I invoke the function. Unable to resolve symbol: a-if in this context a-if is one of the symbols I defined with defn in another file

Tommi Martin10:04:14

Hello everyone. Would anyone happen to have some experience with ring-dev (https://github.com/mtkp/ring-dev)? I've encountered an issue where combining that server with magnars/stasis and magnars/optimus causes svg files to not load properly. In short when loaded with a direct url. The svg works. But when embedded into html from stasis under <img src="[url_to_svg_file]" the svg is not loaded in chrome browser. I suspect this is because of chrome browser receiving invalid headers from the ring-dev server but i'm not yet certain of it (img attached). Would anyone have any configuration tips for this server to get the svgs working as intended before I deep dive into debugging this problem? Thank you for your help.

Karl Xaver11:04:30

Hello Clojurians, I'm trying to use Clojure as local dependency to play around with its codebase. *The following approach worked for org.clojure/clojurescript, but I guess Clojure is special? - cloned https://github.com/clojure/clojure to [project-root]/lib/clojure/ - deps.edn = {:deps {org.clojure/clojure {:local/root "lib/clojure/"}}} - running clojure throws:

Error: Could not find or load main class clojure.main
Caused by: java.lang.ClassNotFoundException: clojure.main
The clojure -Spath seems ok to me and lib/clojure/src/clj/clojure/main.clj exists. Though it is grabbing specs from .m2:
<home>/<project-root>/lib/clojure/src/main/java
<home>/<project-root>/lib/clojure/src/main/clojure
<home>/<project-root>/lib/clojure/src/resources
<home>/<project-root>/lib/clojure/src/clj
<home>/.m2/repository/org/clojure/core.specs.alpha/0.2.62/core.specs.alpha-0.2.62.jar
<home>/.m2/repository/org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218.jar
Any hints appreciated!

Alex Miller (Clojure team)11:04:35

it depends on those libs so that's correct (via the pom.xml)

Alex Miller (Clojure team)12:04:02

but Clojure is half Java, which needs to be compiled and on the path

Alex Miller (Clojure team)12:04:12

so this won't work without some additional steps, exactly what you would do depends on what "playing around" you plan to do :)

Karl Xaver12:04:04

Thanks for the quick answer! I'm mostly after introspection while creating toy apps and not going to move stuff around much. With the source living in .jar files, editor tooling felt a bit limited and I had a nicer experience moving the clojurescript source to :local/root, so I tried that with clojure as well. So it's not really an important problem, just one of these things I couldn't solve after some trials and thought: If I really want to grow, I need to break my habit of wasting hours and hours by trying to figure out everything by myself and start asking questions instead 🙂

rickheere15:04:17

I assume this has nothing to do with the library but I'm at a loss on where to search for the problem. I use dvlopt/kafka {:mvn/version "1.3.1"} I tested it out a while back and it worked, the I continued working on something else in the same project and now it's time to continue working on the kafka stuff, I try to add a topic, as in the docs but I get an error.

(with-open [admin (K.admin/admin)]
    (K.admin/create-topics admin
                           {"my-topic" {::K.admin/number-of-partitions 4
                                        ::K.admin/replication-factor   3
                                        ::K.admin/configuration        {"cleanup.policy" "compact"}}})
    (println "Existing topics : " (keys @(K.admin/topics admin
                                                         {::K/internal? false}))))

; Execution error (IllegalArgumentException) at dvlopt.kafka.-interop.java/new-topic (java.clj:625).
; No matching ctor found for class org.apache.kafka.clients.admin.NewTopic
To exclude the problem is with the library I made a new project, just imported the library and over there it works
clj꞉test.test꞉> 
Existing topics :  (my-topic)
nil
How do I debug this?

delaguardo15:04:58

looks like the problem is inside of the library. You could check if the version of kafka-admin dependency wasn't updated by any other dependency. It should be [org.apache.kafka/kafka-clients "2.1.0"]

rickheere15:04:38

Aah you're right. If I disable com.xtdb/xtdb-kafka {:mvn/version "1.23.1"} it works again!

rickheere15:04:02

Any advice on how to use both the libraties?

rickheere15:04:09

Without conflict

delaguardo15:04:51

I would use java interop instead of some wrapper. It seems much safer to me. But you could try to search for another library that abstract away kafka java internals

delaguardo15:04:34

also you can try to find a version of xtdb that depends on 2.1.0 kafka-clients

delaguardo15:04:53

not sure if there is any because 2.1.0 is from 2018

rickheere15:04:31

Alright, thanks a bunch!