This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # aleph (4)
- # announcements (2)
- # babashka (48)
- # beginners (59)
- # calva (5)
- # cider (14)
- # clj-kondo (4)
- # cljs-dev (3)
- # clojure (77)
- # clojure-europe (6)
- # clojure-italy (6)
- # clojure-nl (5)
- # clojure-spec (4)
- # clojure-uk (67)
- # clojurescript (19)
- # clr (3)
- # cursive (7)
- # datomic (36)
- # duct (33)
- # events (3)
- # figwheel (1)
- # fulcro (4)
- # funcool (2)
- # graalvm (3)
- # jobs (1)
- # joker (25)
- # kaocha (1)
- # leiningen (45)
- # malli (17)
- # off-topic (103)
- # quil (1)
- # re-frame (16)
- # reitit (1)
- # rewrite-clj (27)
- # shadow-cljs (39)
- # spacemacs (3)
- # sql (11)
- # tools-deps (14)
- # vim (41)
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. -> https://clojurians.slack.com/archives/C5K1SHR6X/p1574063278220300 Any suggestions or pointers to appropriate documentation here?
My twitter rant relating the whole arcuri affair to skillsmatter https://twitter.com/cddr/status/1196413438119096320 Whole thing makes me sick.
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 http://nitter.net and the browser extension to redirect twitter to it are fantastic, such fast loading times)
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
a ns to talk to the database (across all features or abstractions), a ns to do all the web handling, etc
This goes back to use-case driven design, which I keep seeing coming up every few years in different contexts
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)
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
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)
It's inevitable that there'll be an
infrastructure layer somewhere, because all these features need to communicate somehow
What's the scope of a feature / use-case? Is it as small as "Login", or is it larger like "Auth"?
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
The idea is that it drives you towards a very plugin-oriented architecture, very "open for extension, closed for modification"
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?
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?
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.
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.
The canonical book -> https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215 The book I most recently read was this one. Code quality wasn’t great, the messages and strategy were covered well, albeit in C# -> https://www.packtpub.com/application-development/hands-domain-driven-design-net-core There’s also a Slack community -> http://ddd-cqrs-es.slack.com
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.
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.,
ws.messaging.io.redis etc -- if there's sufficient "external" code to warrant a whole, dedicated namespace.
That has a bunch of I/O interactions (sockets, http, plus those two as I recall).