Fork me on GitHub
#clojure
<
2019-12-22
>
Jeremy00:12:44

Hi again. Does anyone have experience using leiningen to make multiple uberjars from one project? I have a lot of shared code in src/common and then code for a desktop client in src/desktop and code for a server in src/server. All I want to do is be able to make separate uberjars for desktop and server. However, even if I make separate profiles for the two (with the corresponding source-paths), all the classes for both desktop and server end up in both. Is there a trick to this?

hiredman02:12:18

You need to run lein clean between the builds or specify a different target directory in the profiles

hiredman02:12:32

(sounds like you are aot compiling)

vemv02:12:42

:target-path "target/%s/" helps as well. %s gets replaced with the build name, so that each build is isolated (instead of having competing builds mutate the same folder)

Jeremy06:12:47

thank you; unfortunately neither of those suggestions prevented code being pulled in from an unwanted dir (e.g. src/desktop classes go to the server)

Jeremy06:12:44

I'm pretty sure there aren't any dependencies between the namespaces to account for their inclusion

borkdude13:12:00

This is pretty interesting: src/foo.clj:

(ns foo)

(println (the-ns 'foo))

(def x (/ 1 0))
$ clj
Clojure 1.10.1
user=> (require '[foo])
#object[clojure.lang.Namespace 0x22bb5646 foo]
Execution error (ArithmeticException) at jdk.internal.reflect.NativeMethodAccessorImpl/invoke0 (NativeMethodAccessorImpl.java:-2).
Divide by zero
user=> (the-ns 'foo)
Execution error at user/eval150 (REPL:1).
No namespace: foo found
It seems like the namespace foo is created, but on exception it's removed again?

danielglauser17:12:38

What are folks opinions on the best AWS API wrappers with a focus on S3?

danielglauser17:12:11

Thanks Tim. Looks interesting. Seems that and Amazonica are the two main ones out there.

potetm17:12:59

My fav in principle. Not used professionally.

potetm17:12:15

If you’re risk-averse, you can’t go wrong with the official Java AWS API

Alex Miller (Clojure team)17:12:01

Personally I think using the Java API is going wrong by introducing a giant wad of unnecessary OO between your beautiful Clojure data and a nice simple wire protocol :)

metal 8
potetm17:12:23

It offers more than that 🙂

potetm17:12:16

Ideal? No. But more than you’d get by home-rolling HTTP calls.

potetm17:12:25

Honestly, I’d be more concerned about introducing a giant wad of macros over a giant wad of objects 😉

potetm17:12:34

(read: amazonica)

Alex Miller (Clojure team)17:12:11

Well Amazonica has the glory of both macros over OO :)

Alex Miller (Clojure team)17:12:13

I’ve used the aws-api a lot in the last week and really enjoy it (and not just b/c it’s a Cognitect thing)

potetm17:12:15

I used it a number of months ago and stumbled across a number of shortcomings. I’m sure it’s improved in the meantime.

potetm17:12:31

Like I said, it’s my favorite in principle.

Alex Miller (Clojure team)17:12:48

It’s not perfect but the gaps are closing

bananadance 4
danielglauser17:12:01

I haven’t been clojuring for a bit and hadn’t even heard of it. Thanks for the pointer I’ll give it a go.

potetm17:12:29

@danielglauser David Chelimsky gave a really good rational talk about a year ago: https://www.youtube.com/watch?v=ppDtDP0Rntw

potetm17:12:55

Lays out the general approach. Makes a good case for it.

Alex Miller (Clojure team)17:12:59

Huge props to David C for being a great maintainer too - good mix of regular small updates and periodic important adds

Kari Marttila17:12:48

I'd like to ask you "more seasoned" clojurians one question: do you actually use these application state management libraries like Component, Mount or Integrant? I was experimenting with one of these libraries and somehow I felt that the library caused more hassle with my repl workflow than helped me with my repl workflow.

jjttjj18:12:47

I've found https://github.com/riverford/objection to be somewhat underrated and it tends to be the first thing i reach for

didibus18:12:59

I don't, but I know that some do and really like it.

potetm19:12:18

Use it for prod codebases. Just do it manually and pass objects in play codebases.

seancorfield20:12:49

@U76D9RZRR We've used Component very heavily in production for years. We find it great in the REPL too. What sort of problems are you having?

seancorfield20:12:27

Is it because you're trying to use the "Reloaded" workflow and it's causing you problems? We do not use that workflow -- we don't need it.

seancorfield20:12:46

Eric Normand talks about this in his REPL-Driven Development course -- and Stu Halloway talks about it on podcasts and in his conference talks. If you have good practices around the REPL, you do not need "reload" / "refresh" workflows.

potetm20:12:07

(it is a good amount of ceremony when you only have, say, 1 or 2 objects)

seancorfield20:12:56

The "opinionated" installation guide for ProtoREPL for Atom advocated turning on the full refresh workflow but it causes lots of problems for beginners. Chlorine also supports it but I advise people not to use it for the same reason.

seancorfield20:12:30

Component solves a problem that you don't have in simple programs -- but you do have in spades in a large, complex program.

✔️ 4
potetm20:12:52

I think the latest hostility toward reloaded workflow is overblown.

potetm20:12:15

one should always consider whether there is a more appropriate code structure with fewer dependencies

seancorfield20:12:39

I agree with Eric and Stu that it is unnecessary -- and it certainly seems to cause endless problems for beginners (since they don't understand what's really going on, under the hood), so I encourage folks to avoid it until they really think they need it (which they don't).

potetm20:12:02

but it’s nice to have a guaranteed clean env to check for slimage

seancorfield20:12:33

If it works -- which it doesn't for a lot of people.

potetm20:12:56

I’m kind of perplexed by the idea that it doesn’t work for folks.

potetm20:12:04

Always did what it said on the tin for me.

potetm20:12:37

perhaps it’s somewhat unintuitive?

seancorfield20:12:42

Yeah, for some folks It. Just. Works. I've had it work perfectly in some projects and not at all in others.

potetm20:12:58

what did it do when it “didn’t work”?

potetm20:12:06

I don’t even understand the statement! 😄

potetm20:12:35

Like, it just hung? It hit errors? You got errors after it ran?

potetm20:12:27

(I’ve hit loads of unexpected behavior/errors before running reload. Usually to do w/ interop.)

vemv20:12:08

it's bit of an unfortunate tradeoff - both Reloaded and manual management have some gotchas I think Reloaded could be improved, in the end it's a fancy name for 'automation'. The current status of that automation is relying in a slightly unmaintained library that doesn't document all its intricacies Raw clojure isn't perfect either - keeping track of namespaces in your head or intricacies related to the compiler isn't perfect either One always can experiment with both approaches, document observations and draw conclusions

💯 4
seancorfield20:12:05

If we had searchable archives here, you could just search for the problems many people have experienced with it... 🙂

didibus22:12:46

I'm not even sure what people mean by reloaded? tools.namespace ?

didibus22:12:14

I use cider ns refresh all the time, without using a component library

didibus22:12:37

Its pretty great, for when you want to make sure your code compiles without restarting the repl

didibus22:12:27

I do think there are certain things it can't clean though, like thread locals and all

didibus22:12:02

But just gettijf rid of bindings and letting me know I've got all the right require in place and declared functions is great

mauricio.szabo00:12:08

I use the "reload" workflow in most of my projects, and indeed, sometimes it works, sometimes it doesn't. With Clara-Rules, for example, I wasn't able to cut an approach that works without reload

mauricio.szabo00:12:48

But for multiple other projects, manual load-file / other tools work fine too (if there isn't too many protocols/records)

mauricio.szabo00:12:43

Nowadays, I use a mix of approaches. The thing is, I work mostly with very small microservices now, so the dep graph is very simple to understand (and maybe that's the reason the "reload workflow" works so well for me 😄)

didibus01:12:17

I still think I'm confused about what is the "reloaded" workflow. Initially, from Stuart's talk it was about being able to perform starting and stopping logic in the correct order to initialize and shut down resources

didibus01:12:56

For that, you need a Component like system

didibus02:12:00

But there is also the issue that load doesn't unload. And sometimes, you just want a clean REPL without having to restart it (because its so slow to restart). Tools.namespace is targeting that issue.

Kari Marttila10:12:14

Sorry for late answer, @U04V70XH6 . I used Mount but occasionally one namespace didn't compile anymore (No matching field found: stop for class mount.core.DerefableState) and the only way to fix the issue was to restart REPL - which I'm learning to avoid. I have a personal learning project in which I'm mostly trying to learn a personal efficient REPL workflow. I think next I'm trying to do the same project without any application state management library and see how REPL driven development feels like that way.

Kari Marttila10:12:20

Clojure is really a great language and I think REPL is the soul of Clojure - I really want to learn to use REPL smoothly when developing Clojure code.

Kari Marttila10:12:51

Actually I have fallen in love with Clojure so much that I gave up my good corporate career and moved to a smaller company just for the chance to do Clojure full-time. 🙂 Well, I have paid my mortgage and my kids are grown-up now so I thought that I can do for the rest of my career what ever I want - and I want to do Clojure. 🙂

🙂 4
Kari Marttila10:12:21

BTW. If you guys know links to good REPL driven development sites / pages, please provide links here.

Kari Marttila10:12:17

I have watched Purely Functional TV's Repl Driven Development course and I must say it is really great (thanks Eric!).

Kari Marttila10:12:07

Also "Chicago Clojure - 2017-06-21 - Stuart Halloway on Repl Driven Development" (https://vimeo.com/223309989) is really wonderful. After watching this video I realized that I have done REPL driven development totally wrong - editing stuff in a REPL editor. After watching that video I immediately started using a scratch file (for REPL experimentation) that I save for future review.

Kari Marttila10:12:16

If I remember correctly Stuart somewhere said that he mostly compiles namespaces one after another following the dependency graph manually to better understand what kind of dependencies there are. I have tried to do that also myself more now (and try to avoid fixing issues just by "restarting repl").

Kari Marttila11:12:35

... @U04V70XH6 already said it in this thread, I somehow missed it when reading this thread the first time: "Eric Normand talks about this in his REPL-Driven Development course -- and Stu Halloway talks about it on podcasts and in his conference talks. If you have good practices around the REPL, you do not need "reload" / "refresh" workflows." => Maybe that's what I'm trying to achieve: "good REPL practices". 🙂

4
frozenlock17:12:09

I prefer not to use it if I can get away with it. I'm keeping an eye open for https://github.com/juxt/clip which should be more repl/cider friendly.

lilactown18:12:16

in the past I have used mount but these days, most of my apps are quite small so I avoid it

andy.fingerhut18:12:25

I cannot provide any background, but was watching Sean Corfield's videos on how he uses Atom + Chlorine + REBL + tools.deps + Clojure CLI, and it showed that their fairly large Clojure code base at the company he works at, World Singles, uses Component: https://www.youtube.com/channel/UC8GD-smsEvNyRd3EZ8oeSrA

andy.fingerhut18:12:07

Note: Those videos do not go into any detail on the use of Component -- it is simply apparent that they do use it in their code base from seeing it mentioned in the video.

andy.fingerhut18:12:58

I believe I have heard him mention that he does not use the "reloaded" workflow that some other Clojure devs use, instead choosing to force himself to remember to explicitly resend (via a single keystroke configured in his editor) any modified functions to the REPL, to redefine them.

craftybones18:12:53

@alexmiller mentions 30 tools built for CLJ in his tools.deps clojure conj talk. Are those listed somewhere?

craftybones18:12:43

Darn, these are cool!

sogaiu18:12:46

fwiw, mark bastian's talk at the recent conj covers integrant a bit -- am slowly trying to digest that along with the many pieces used (he's got a repository that has the code for the talk plus extra)

didibus18:12:09

I like mount-lite as well.

dominicm19:12:25

My problem with mount is that it doesn't make a statement about passing around your state, so it's easy for it to leak where it shouldn't.

💯 4
potetm19:12:01

Managing mutable state (including I/O calls) ought to be explicit IMO.

kulminaator19:12:26

re aws and any of it's apis, imo aws people, with their official java sdk, slayed an ant with an hammer and then drove a tank over it

lol 4
truestory 4
kulminaator19:12:48

last time i checked the language of clojure was smaller than the aws sdk for s3 access + the deps that the latter needed

kulminaator19:12:55

and their next gen sdk is even worse in that light