Fork me on GitHub

I have done anti-ORM talks in other tech 🙂

Sam Ritchie22:08:17

Do folks have a pointer to a library project that does a good job splitting itself into modules?


that's a good question! It can be argued that modularity tends to be a need that is more frequent in apps than in libs... libs typically compose by simply making/extracting more libs, independent of each other. The simplicity of this design might have some appeal. i.e. your API consumers don't perceive anything different - just a set of libs. If the libs are inter-related and often need to developed in sync, the libs might be better placed in a monorepo (personally I'm agnostic about them) and managed with deps.edn (Lein can work just as well, but IMO requires some additional expertise if you don't want to depend 100% on plugins)

Sam Ritchie01:08:42

@U45T93RA6 yes, a monorepo is the goal here, since I do plan on developing the modules in sync (and running all tests together) - I'm thinking of a setup like I commonly use in Scala, on projects like Algebrd:

Sam Ritchie01:08:44

and then the links between them are managed by the build, similar to "checkout dependencies" with lein, but all in a monorepo. they're all released at the same time, same versions etc

Sam Ritchie01:08:13

@U45T93RA6 I hear you on separate projects, and I think that's appropriate if a module stabilizes, but otherwise I've found that that style, if you get beyond a couple of libraries, leads to a bad time when you go to release


Yeah a single .jar can be handy. It helps that clj .jars are just source files, so the size difference is negligible whether you ship 1 lib or 10 libs inside with Lein, I'd create a project laid out similarly to algebird. Then I'd set the :source-paths to ["foo/src", "bar/src", ...]. If you use unquote, you can set the :source-paths dynamically with clojure code (I did exactly that earlier this year)


IMHO monorepos are a gordian knot solution to hard architectural decisions, and if your problem is small enough you gain a lot from the discipline needed when you don't use them

👍 3

this is especially true (in my opinion / experience) if you intend to have collaborators - the design decisions that are discouraged by having multiple libraries are the ones that make onboarding new devs hard (too often big projects are implementation complete - that is to say, the work needed to understand what's there is or even exceeds the work needed to make it from scratch)


Curious, where does the implementation complete term come from? Without the explanation I would have failed interpret that meaning


"implementation" as in the verb, act of implementing, describing a scope of work or amount of effort. I might have made that up (based on eg. turing complete as a measure of functionality).

Sam Ritchie01:08:22

@U051SS2EU yes, this is slightly different than that concern, which I’m very familiar with

Sam Ritchie01:08:15

This is more like - I have one project that implements the physics engine behind the Steucture and Interpretation of Classical Mechanics book, and then namespaces that describe and implement every exercise in the book

Sam Ritchie01:08:40

One conceptually rides on the other but it doesn’t do me or anyone any favors to actually split it out into another repo

Sam Ritchie01:08:04

Vs keeping the source tree separate, but versions identical and published as modules

Sam Ritchie01:08:12

I’ve found that a nice style early on is logical breaks like this in a “mono repo”, like algebird’s, but then once the core protocols become mature and stable split them out for others to depend on and extend

Sam Ritchie01:08:16

But maybe it’s like buying ice cream. If you can’t do the single repo discipline and keep knitting logic together, you need to go mono repo to get the discipline (if you can’t resist the ice cream don’t keep it in the house)


if the relationships are well defined that's clearly convenient, I was talking on a very abstract level of course about one of the hazards to avoid


clojure is quite intentionally a "you can do it that way if you know what you're getting yourself into" language at the core


as long as you understand the way you can waste your time and energy with bad abstraction boundaries and can understand the signs that's happening, I say go for it

Sam Ritchie01:08:23

Yup, I’ve been burned so I do. But it’s a good point that contributors to libraries like this don’t necessarily have that “embodied experience”, so it’s risky to take on

Sam Ritchie01:08:58

A GitHub organization is maybe the level you really want. With automatic builds of every project in the grouping whenever a dependency changes, to give you a heads up

Sam Ritchie01:08:03

And a rolling release

Sam Ritchie01:08:33

It would be nice to be able to nest projects more deeply to enable things like this. No one would call Github as a whole a “monorepo”

Sam Ritchie01:08:51

The fact that each of these boundaries is very different in terms of costs and incentives is not great


I grew up with hippy parents, so my core guidance is to "go with the flow" and create setups where the easy / simple thing is the right technological solution. This is well out of the domain of craft and more of an artistic decision.


You two are talking a bit too meta for me 😅 Justed wanted to add that with tools.deps creating modules in one repo is not much more than putting code in another namespace. No need to make hard choices from the start. And these “module libraries” can be used externally from the start


It does require picking the right version of for example lein-tools-deps , and for external usage, some Github Actions hackery to make this work


:D makes sense


to be more concrete: I like a code layout that makes the lazy thing the right thing, and usually that's separate libs, to me the friction of changing interfaces (after you leave the brainstorming stage) is a positive

👍 6
Sam Ritchie22:08:00

Years ago I used lein-sub... the idea is that I have this extensible arithmetic and physics library, but it’s huge so I want folks to be able to opt in

Sam Ritchie22:08:20

Or pull in the core protocols and extend it themselves without taking the full library