Fork me on GitHub

Morning all!


I posted this morning over on #duct to ask advise whether there’s a ‘duct’ place for string -> proper type conversions to happen. I’ve a map that is deserialized from a form post, and need integers to be integers, not strings as I assume all things from form posts come in as. -> Any suggestions or pointers to appropriate documentation here?


Morning all!


My twitter rant relating the whole arcuri affair to skillsmatter Whole thing makes me sick.


@cddr Not being in London for more than 2% of the year I’m a little confused.


I'm also confused


Tbh, I don’t spend a huge amount of time there either but from what I’ve seen in the news, “innotech” is the company that got all kinds of funding and access basically because it’s founder was having an affair with the mayor of London who is now our pm.


(as an aside and the browser extension to redirect twitter to it are fantastic, such fast loading times)


InnoTech is a competitor to SM?


Her company was basically tryin to be what skillsmatter actually was


Looking forward to your talk at reclojure btw @cddr



♥️ 4

In a kind of related because I started scrolling through twitter kind of way, I've recently realised that I have no idea how to structure namespaces. Or at least, I couldn't say if the way I've been doing it is okay. I know someone here mentioned structuring by feature, but I did some other reading talking about nouns, but then you look like objects, or you can break up nouns unconventionally, and now my googling got stuck... I thought I'd draw on clojure-uks many years of experience and see what I've missed


I think your namespace structuring should reflect the building up of abstraction layers. Abstractions in Clojure are mainly based on data, so functions working on the same abstraction tend to naturally cluster together (because the “utils” part of that processing gets reused consistently). The public part of the abstraction tends to appear at the bottom of the namespace (because of Clojure’s single-pass nature). One way to see this is to observe a namespace evolution without forcing new namespaces up-front and notice how some functions are move closed together (maybe with comments saying “here are the fns for doing X”). I think one good advice would be to resist the temptation to create a namespace too soon and live with a slightly bigger “core” namespace until the abstractions start to form. Then extract.


the only namesapacing in clojure I've ever regretted is when I've done it by layers

👍 4

a ns to talk to the database (across all features or abstractions), a ns to do all the web handling, etc


just to check - this is what you regretted right?


it is indeed what I regretted. Luckily that code is no longer in use. 🙂


I think a bigger core that gets factored out is a good idea too

Alex Young15:11:12

This goes back to use-case driven design, which I keep seeing coming up every few years in different contexts

Alex Young15:11:53

It's very easy to divide code up by what it is, keeping all the similar-looking bits together (so all your database access ends up together)


use case == feature AFAICT

Alex Young15:11:07

It's harder to divide code up by what it is for

Alex Young15:11:42

Yes, pretty much: the idea is that you should be able to navigate your code hierarchy from the top level by user-facing feature


I think a good code fragrance(?) is seeing things like database access in multiple namespaces, rather than all in one place. Tho this might get wrapped up a bit into something common, but then I'd expect to see that common thing used in multiple namespaces

Alex Young15:11:37

yep - it's the idea that having a high-level "models" directory where all your Active Record classes live is an antipattern (to pick a random example from a random ecosystem)

Alex Young15:11:31

It's inevitable that there'll be an infrastructure layer somewhere, because all these features need to communicate somehow

Alex Young15:11:03

but that layer can be quite thin


What's an infrastructure layer?


What's the scope of a feature / use-case? Is it as small as "Login", or is it larger like "Auth"?

Alex Young15:11:55

To pick a random app architecture, the infrastructure layer would be the bit which implements, say, an event bus for the various parts of the app to communicate

Alex Young15:11:11

The use case scope would be as small as "Login", yes

Alex Young15:11:43

The idea is that it drives you towards a very plugin-oriented architecture, very "open for extension, closed for modification"


What would connect together your use cases?

Alex Young15:11:57

In what sense?


How do you pull everything together from these disconnected use-cases? They're all just floating at this point. Would they be components in a system, or something else?

Alex Young16:11:04

They're components in a system. The infrastructure is what allows them to talk to each other and arranges the mechanism which instantiates them


Interesting. So the infrastructure and features will be dramatically different dependent on what you're exposing/consuming to/from the world?

Alex Young16:11:55

Potentially, yes


yeah, you still get some namespaces that tie things together (usually at the top of the call stack) but those should be really thin and just call out to the other namespaces that are the features.


I’ve really enjoyed going through some DDD material recently. Domain stuff structured around features and the domain in general. Then a flatter container for commands coming in, and a thin flat layer for infrastructure. I’m looking to put this into a Clojure project based on Duct soon.

👍 4

be warned the duct templates aren’t feature first / vertically organised. i.e. they tend to encourage the following structure: - app - app.handler - app.handler.feature-1 - app.handler.feature-2 - app.model.feature-1 - app.model.feature-2 The ataraxy duct module also has some annoying tag inference stuff that wants you to put handlers in those places. However you don’t have to do the above: You can wire up ataraxy to avoid infering those locations and have the following kind of layout: - app - app.feature-1 - app.feature-2 With features then internally split horizontally if you so desire. In my experience it’s much better if you lay things out this way.


oh, cheers for the pointer. I'm still at the early learning stage, so have been focused on the tactical how to, and less strategically at the moment.


DDD keeps coming up, what are your favourite reads?


The canonical book -> The book I most recently read was this one. Code quality wasn’t great, the messages and strategy were covered well, albeit in C# -> There’s also a Slack community ->


I should mention that middle book merges DDD with Event Sourcing and CQRS which go together extremely well.


In many ways, much of the Clojure ecosystem is ahead of this stuff, but could possibly learn some of the subtle stuff.


How are we ahead?


Organization of namespaces really seems to be an area that there's not much guidance for with Clojure.


We've ended up with a mostly domain/feature-based organization of most of our code, but in our more traditional web apps, they tend to have handlers, model, and views (or at least view-only logic) as high-level grouping with handlers being organized somewhat according to the sections of the web site/API and model following the more domain/feature-based organization instead.


If a domain/feature has extensive integration with external systems (3rd party APIs, databases, etc), we have that as a "sub" namespace, e.g.,, etc -- if there's sufficient "external" code to warrant a whole, dedicated namespace.


Overall, our structure is fairly flat tho': ws.<app>.<feature> for most stuff.


@seancorfield io isn't a feature, is it?


No, that is just in place as a grouping for various I/O implementations.


That has a bunch of I/O interactions (sockets, http, plus those two as I recall).


It's interesting that everyone who responded is doing this


I don't think that anyone is really talking about it


Google pulls up some abstract stuff, one even hinted at a next step