Fork me on GitHub
#clojure
<
2022-03-01
>
pez11:03:29

I found it surprisingly hard to translate a Leiningen deps vector to a tools-deps map. Specifically ran into troubles with getting too much help with printing name-spaced maps. (I think my tooling might play a role here, but anyway. Since this strange hack did the job for me, I let it. But I also can't stop figuring about what a proper way would be...

(into {}
      (->> lein-deps
           (map (fn [[d v]]
                  [(if (re-find #"/" (str d))
                     d
                     (symbol (str d "/" d)))
                   v]))
           (sort-by first)
           (map (fn [[d v]]
                  (binding [*print-namespace-maps* false]
                    (prn d {:mvn/version v}))))))
Some of the Leiningen deps tuples have :scope which I don't really know what it is about so I'll try with just skipping that. 😃

Alex Miller (Clojure team)12:03:44

Deps doesn't support scopes (I would encourage you instead to make aliases corresponding to different classpath scenarios)

Alex Miller (Clojure team)12:03:33

In Maven, scopes are modifiers that say whether a dep should be included in different classpath scenarios (compile time, run time, test time, and dep publishing time, roughly)

Alex Miller (Clojure team)12:03:00

I would have to look at that code for a long while to understand it but it doesn't seem to understand how deps deals with classifiers either

pez13:03:42

Thanks! There were no classifiers in the vector I was converting.

Cora (she/her)14:03:26

@U0ETXRFEW I'm not sure if you've looked yet but clj-new can convert leiningen templates to deps.edn and it might have an already fleshed out version of this https://github.com/seancorfield/clj-new

pez14:03:19

The project is created with clj-new, from a Leiningen template, but I didn't see an option to convert it.

Cora (she/her)15:03:00

I thought it automatically converted it

pez15:03:32

It is quite hard to do, given all the things that can be going on in a Leiningen project.

jmckitrick13:03:17

I have some questions about java inter-op, specifically with ‘builders’. I’m working with the java SDK for a well known business application. In some cases, this works fine:

jmckitrick13:03:41

(builder/to-java MyJavaObject {:quantity 1})

jmckitrick13:03:55

But in others, I get errors like this:

jmckitrick13:03:36

Caused by java.lang.NoSuchMethodException com.foo.MyJavaObject$Builder.<init>()

jmckitrick13:03:42

And then I switch to:

jmckitrick13:03:04

(.build (MyJavaObject$Builder. 1))

jmckitrick13:03:06

and it works fine.

jmckitrick13:03:50

I jump into the jar and poke around, and the Builder looks fine to me (I’m not a Java guy at all) and the whole SDK seems autogenerated, so the Builder classes all look very similar.

jmckitrick13:03:52

I would prefer to use just one approach, preferably the most flexible. Along with that, I’d like to understand what’s going on to cause this error.

jumar13:03:17

@jmckitrick What is build/to-java ? And please consider making a thread, instead of posting many messages into the main channel 🙂.

jmckitrick13:03:51

Sorry, poor Slack etiquette, lol.

jmckitrick13:03:57

I didn’t know that also applied to the OP.

jmckitrick14:03:38

clojure.java.data.builder

p-himik14:03:25

> I would prefer to use just one approach, preferably the most flexible You should stick to interop then, it's the most flexible one. java.data has a bunch of assumptions that must hold true for it to work on a particular builder class. In the case of the error above it assumes that there's a no-arg constructor of the nested class Builder. And seems like it's not the case since you get NoSuchMethodException com.foo.MyJavaObject$Builder.<init>().

seancorfield19:03:21

@jmckitrick Per the java.data README: > :builder-props -- properties used to construct and initialize an instance of the builder class; defaults to an empty hash map; may have :clojure.java.data/constructor as metadata to provide constructor arguments for the builder instance,

👍 1
jmckitrick20:03:21

Oh wow… I might give that a try.

seancorfield20:03:52

LMK if you have problems with it (I'm the maintainer). The :builder-props stuff could do with more extensive tests. The :clojure.java.data/constructor metadata approach has more tests around it.

jmckitrick22:03:09

I’ve not done much with metadata… so I need to attach metadata to the :builder-props map?

seancorfield22:03:44

:builder-props (with-meta {} {:clojure.java.data/constructor [the ctr args]}) is what I think it's suggesting. It's been a while since I last messed with builders.

seancorfield22:03:45

The value -- the hash map -- lists the properties to be added to the builder (once it is created). The metadata provides a vector of values that are passed to the builder's constructor.

seancorfield22:03:43

I remember having a hard time finding good examples of builders with constructors in the Java standard library to write tests based on! 🙂

😂 1
jmckitrick22:03:17

I’m glad I asked… I was going to start with the ^ operator/special char/whatever lol

seancorfield23:03:02

:builder-props ^{:clojure.java.data/constructor [the ctr args]} {} would work too. I just find with-meta a bit easier to read for constructing values at runtime.

jmckitrick23:03:04

It looks like I need an instance now, so is it safe to say TheClass$Builder is what I need?

jmckitrick23:03:25

Given that’s the pattern I’m seeing throughout the SDK, of course.

jmckitrick23:03:16

I think that worked!~

jmckitrick23:03:58

And no, I did not need a builder. Now I have to make sure I got back what I expect 😉

seancorfield23:03:31

Are this SDK's docs publicly accessible?

seancorfield23:03:35

If the pattern is always an inner class Builder then you specify the outer class and let b/to-java figure it out (modulo constructor args above).

seancorfield23:03:48

See https://github.com/clojure/java.data/blob/master/src/test/clojure/clojure/java/data/builder_test.clj#L16 -- it can figure out things for java.util.Locale without any options (first test), if you want to construct the builder object yourself and pass that in that's like test #3 (again, no options). Then tests #2 and #4 are for those two cases but with the options specified explicitly (they just happen to be the defaults).

seancorfield23:03:59

Hope that clarifies things @jmckitrick?

jmckitrick23:03:07

My code is about half and half right now… some pure java interop, the rest using to-java with a builder successfully.

jmckitrick23:03:24

And yes, thanks for the help! I’ll tinker around with both approaches and pick one

seancorfield03:03:44

Oh that is one nasty, nasty Java class -- yikes!

jmckitrick12:03:13

Glad I’m not the only one that feels that way, lol.

BorisKourt16:03:01

I am currently getting 3D models from a repository (via git-lfs) through a combination of GitHub’s APIs. I would like to temporarily cache these on the backend (max a couple of days), for frontend and other uses. Have been surveying the landscape for options but it’s been pretty hard to decide on a strategy. I would like to do this on hardware I own rather than use something like AWS. Does anyone have any suggestions for some Clojure-centric strategies to look at? This would be tool-centric and low traffic usecase, I mostly want to avoid having to wait for GitHub API responses.

Ben Sless17:03:16

You can run minio on your own hardware and use the s3 api with cognitect's aws api

p-himik17:03:38

And if you already have an endpoint and a function that returns you the models by making a GitHub API request, you can just wrap it with an LRU or any other cache with a TTL (assuming you don't restart your server often).

BorisKourt12:03:52

@UK0810AQ2 Thanks for the recommendation any suggestions on something with a smaller footprint?

BorisKourt12:03:52

@U2FRKM4TW Thanks! Do you know a good way to store 80 - 300 megabyte responses with this strategy? It would have to be on disk I think, as RAM is quite limited at the moment.

p-himik13:03:21

There's https://github.com/shriphani/fort-knox but I haven't used it myself. There can be other libraries like that - your web search is as good as mine. ;)

BorisKourt14:03:05

Thanks! I have been searching around quite a bit the past week. A lot of resources use some very outdated tools and dependencies, making it harder to evaluate. And sadly I don’t have the capacity to take over and maintain. Mostly wondering if someone has had some explicit opinions about this by chance.

p-himik15:03:09

> very outdated tools and dependencies How do you determine whether something is outdated?

BorisKourt16:03:07

I’m sorry but that feels like a needlessly loaded question, not sure if that was your intent.

p-himik17:03:34

People often say that something is outdated because that something hasn't been updated in years. In the Clojure world, that often means that the library is stable and perfectly covers its scope - there's simply no more work to be done. That may or may not be the case with fort-knox that I linked above.

BorisKourt10:03:39

I totally understand. Have been using Clojure for eight years : ) Developed a little bit of an eye for figuring out which projects are in what category.

BorisKourt10:03:48

Thanks for your suggestions

Ivan Fedorov17:03:56

Anyone knows projects similar to AirBnB in Clojure? I’m in a project that wants to organise housing for the Ukrainian refugees

4
Leon18:03:59

Oh great

Leon18:03:02

I am ukrainian

Leon18:03:10

How can I help you?

Ivan Fedorov19:03:35

thanks! are you on github?

seancorfield19:03:15

Might be worth gathering folks in #clojure-ukraine for this? I don't know if that channel is intended to be multi-lingual (some geo channels here try hard to remain native language only).

mll19:03:59

Dear Clojurians. I have a question on stackoverflow pertaining reading-off (and then setting back) variables inside of a macro. The question relates to core.async implementation and possibly also to the "fn" form implementation (as they both do tricks with context). If somebody has any insigthys into those areas, I would really appreciate some answers: https://stackoverflow.com/questions/71313931/persisting-variables-in-core-async-style

ghadi20:03:12

Once Java gets virtual threads from Project Loom, none of the code-rewriting macros will be necessary.

🤞 3
1
Ben Sless20:03:33

@U053XQP4S has a few criticisms of how they're implemented. Revolving mostly around not being able to fork continuations, iirc

ghadi20:03:59

¯\(ツ)

ghadi20:03:14

first class continuation support is a non-goal

leonoel20:03:43

virtual threads are also not serializable, which is required to solve @U4EMCR2BG’s problem IIUC

leonoel20:03:39

> first class continuation support is a non-goal it was an explicit goal in the first place, they removed it from scope afterwards

ghadi20:03:50

async/await style programming is "first generation" technology

ghadi20:03:20

(not a direct answer to your question)

vlaaad20:03:35

isn't callback hell first generation?

mll20:03:42

@ghadi async/await is solved in Clojure through core.async. My problem is different, as I want to persist all the variables declared in scope in the database for deferred execution.

ghadi20:03:33

have you considered using an explicit state machine?

mll20:03:41

I am using it now

mll20:03:45

And it is a mess

mll20:03:01

This is an effort to reduce bugs and intellectual load on the project

mll20:03:21

I need the state machine to be hidden so that my devs can focus on implementing features

ghadi20:03:07

well writing your own code rewriting macro will crush your spirit

mll20:03:38

My spirit can be crushed as long as the final outcome is working well.

👀 1
ghadi20:03:59

need to make a model of the control flow in the lexical scope, then determine suspension points

mll20:03:01

I am prepared to bang my head against the wall a few times.

mll20:03:33

Is this what core.async invokation of the analyser does?

ghadi20:03:06

before we used the tools.analyzer library, we had a mini-clojure compiler within the macro

ghadi20:03:54

suspending and resuming across jvm invocations is not a thing that core.async does

ghadi20:03:14

I would consider an explicit state machine, with clear data contract

ghadi20:03:43

a la AWS Step Functions, or whatever the state machine library du jour is