This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # adventofcode (140)
- # beginners (107)
- # boot (120)
- # boot-dev (1)
- # clara (13)
- # cljs-dev (9)
- # clojure (107)
- # clojure-argentina (5)
- # clojure-art (16)
- # clojure-dev (23)
- # clojure-greece (19)
- # clojure-italy (5)
- # clojure-russia (2)
- # clojure-serbia (3)
- # clojure-spec (27)
- # clojure-sweden (1)
- # clojure-uk (15)
- # clojurescript (134)
- # cursive (5)
- # data-science (10)
- # datomic (23)
- # duct (28)
- # fulcro (48)
- # garden (5)
- # hoplon (2)
- # instaparse (1)
- # klipse (7)
- # leiningen (8)
- # lumo (36)
- # off-topic (72)
- # om (4)
- # onyx (37)
- # perun (4)
- # re-frame (64)
- # reagent (86)
- # remote-jobs (1)
- # shadow-cljs (59)
- # spacemacs (16)
- # sql (1)
- # uncomplicate (6)
- # unrepl (90)
@weavejesterDuct could support both styles without any issue, so everyone could go for their style. However, many newcomers like me might just follow the convention in project template as @rickmoynihan saying, would it be nice to put the style into the template that creator feel comfortable to work with? That’s why I asked about the preference. Since the preference really affect the newcomer’s user experience.
> I don’t think Duct has a real preference either way.
@weavejester: Except I think it does express a preference; as
lein new duct foobar +site +example creates
foobar.boundary which I think sets people off on the wrong foot of grouping things by framework concepts, rather than by application domain concepts.
We’ve found this style problematic on real codebases, and it’s been a source of personal frustration that practically every project template does it this way, leading to a proliferation of this style in various webapps we maintain, and time consuming refactorings later on.
It’s not a frequently discussed topic of conversation in the clojure community though… so perhaps it’s just Russell Dunphy, myself and @albert.lai who feel this way. But I’m a strong believer that the code layout should say something about how your domain is structured, and having folders like
foo.routes (not so common in duct with a data driven router), and
foo.datamodel etc… puts your technology choice above your domain… much better is a layout like:
As the top level says what your app does. Within each you can partition horizontally if you need to, e.g.
In terms of partitioning by feature or layer, I actually intend to partition by feature.
I place most of a feature’s code under
foo.handler.feature. It’s only interfaces that are shared between features that get their own namespaces.
e.g. if several handlers wanted to access the users table, one might have a
foo.boundary.user, but otherwise boundaries would be part of the handlers themselves.
@weavejester ok, in that case we both agree that by feature is better 🙂
foo.handler.* encourages people to partition by layer though, as the layer (handler) is the outer-most thing; even though I see that’s not how you think of it.
Is there an argument that reversing it to
foo.feature.handler would clear that up misconception up?
obviously it might mean that top level namespaces might end up including features and other odds and ends (like boundaries)… but I’d probably be ok with that
@rickmoynihan I think the problem is that we have features, and things that exist across features. For example, we might have two features,
bar, that share a common boundary
Unless you use
app.baz.boundary, but then that also conflicts with things like the way middleware namespaces are usually laid out.
@weavejester: yes there are usually shared/cross-cutting things… I normally put them in a common namespace, e.g.
@rickmoynihan I mean that usually namespaces in libraries are not organised by feature (since they don’t have any), so you have namespaces like
Ok… I don’t think that’s an issue though… I think applications and libraries are very different
e.g. it’s not usually the job of a library (in clojure) to specify state inside vars… It should let the application do the
Similarly I think it’s reasonable for us to layout applications differently to libraries
and that layout is something frameworks usually encourage… where as a library wouldn’t.
@rickmoynihan It might be a good idea to draw a line between libraries and applications, though I think in practice there’s a lot of cross-pollination. Namespaces might migrate between an application to a library.
there is cross pollination but if you were moving code from an application to a library you’d likely be renaming it to remove the application name from it… If you’re sharing a
feature (perhaps user login - would be an example) then you’re really sharing a module or component (i.e. a chunk of application) rather than a normal library.
I think I agree with the general thrust of your argument. I’ll need to give it some thought.
it’s more common for code to be extracted from an application to a library - and in the process its contract changing (i.e. new names). Libraries rarely move into applications; though if they do, it’s probably on the scale of copy/pasting a middleware or utility function to patch it somehow. When that happens I think you usually have new names too… or if patching you’re deliberately keeping the name (and it’s not in your apps namespace anyway).