Automatic namespace names

I’m a React developer, and often have very deep file hierarchies in my projects. For example, on of my javascript projects has the following heirarchy:

src->scenes->editor->scenes->code->component->Editor.js

From my current understanding of namespaces, that means that I’d have to define and import the following namespace:

(ns my-project.scenes.editor.scenes.code.component.editor)

Is there any way to avoid having to write out the full path when defining namespaces? The only option that I’ve been able to come up with is flattening the hierarchy into different folders and putting all of them into the resource-paths section of my Boot config, but that seems awkward.

It’s idiomatic in Clojure(Script) to have somewhat flatter hierarchies. Without knowing the structure of your React.js apps, it’s hard to know exactly what to suggest here, but seeing scenes and editor both appearing twice in the path would be a bit of a red flag for me about the structure.

When you’re using namespaces in other files, you can :require .. :as .. to provide a short alias that only has to be unique within that file. That alias is typically the last segment of the full namespace – so that should probably guide you in terms of organizing code by name and scope so that the filename (last segment) should be unique within its likely scope of use. That’s not always possible, of course, but it’s a useful rule of thumb.

In general, in Clojure(Script), namespaces are a lot less granular than classes tend to be in other languages because we separate data from functionality as much as possible so a) functions tend to be more generic and b) more functions tend to be grouped together in support of one “concept” (namespace).

Does that help at all?

2 Likes

Yes, thank you so much! I think that you bring up a great point about Clojure just having a different fundamental design philosophy, so nested hierarchies shouldn’t really exist. Do you know of any complete cljs React applications that demonstrate this? I haven’t been able to find many good examples.

I don’t know how many decent-sized Om/Om.Next/Reagent/Re-Frame apps are out there as opensource to look at. I suspect most such apps being built are for proprietary applications.

Clojure(Script) namespaces will have some level of nesting but it tends to be more coarse-grained (because data and functionality are separate – and data is not encapsulated). For example, at work we’ve settled on a pattern of ws.domain.appname for our main entry point (e.g., ws.billing.member, ws.seo.geo) and then we have nested namespaces like ws.billing.member.controllers, ws.billing.member.views, ws.seo.geo.listing, etc with implementation details nested below that (ws = World Singles). Our older code used worldsingles at the top-level but we got tired of typing that :slight_smile: We also have quite a bit of “generic” code that’s just worldsingles.concept.

Just for fun, I scanned the whole of our Clojure codebase for counts at each level in the source code (61,000 lines):

  • Two-segment names: 83
  • Three-segment names: 125
  • Four-segment names: 53
  • Five-segment names: 1

(and the first segment is always ws or worldsingles just to distinguish our code from other library code – so you can effectively take one segment off all of the above)

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.