This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # aleph (1)
- # announcements (31)
- # babashka (9)
- # babashka-sci-dev (36)
- # beginners (72)
- # calva (20)
- # clj-kondo (99)
- # cljsrn (1)
- # clojure (77)
- # clojure-europe (33)
- # clojure-nl (4)
- # clojure-norway (12)
- # clojure-uk (4)
- # clojurescript (23)
- # cursive (2)
- # datascript (5)
- # events (1)
- # fulcro (3)
- # honeysql (3)
- # inf-clojure (82)
- # interop (2)
- # kaocha (10)
- # lsp (15)
- # meander (1)
- # missionary (10)
- # off-topic (22)
- # pathom (4)
- # pedestal (3)
- # polylith (20)
- # re-frame (10)
- # react (4)
- # reagent (4)
- # reitit (27)
- # ring-swagger (1)
- # shadow-cljs (34)
- # specter (3)
- # sql (1)
- # testing (5)
- # tools-deps (22)
- # vim (12)
I'm currently renaming a bunch of interface files because I'm going to need to have a project that builds a js-based artifact and I don't want to worry about the naming collision for that platform, and I thought I'd share the list of interface-ns names I'm considering in case it's useful for anyone else: • api • bond • cap • ci (component interface) • component • contract • cover • face • front • i (interface) • pact • pledge • top • veil
One idea is to use
ifc. It’s a quite common abbreviation for
I had an idea to support more than one interface name in
:interface-ns , e.g.
["interface" "ifc"] . Do you think that would help?
If we're going to have a convention my preference is for it to be consistent, so I don't think I would use more than one interface name.
public are also reserved.
interface- would work? Then we keep the name interface but add a dash at the end.
@U1G0HH87L I think one source of pushback against Polylith is the interface/component split - people seem to think it introduces indirection, and doesn't add value if you have only one implementation of your component.
I think currently you can have your implementation in the interface namespace. That's not the intended usage, but I think it works, right? I'm thinking, if a team wanted to do this, they could agree on a convention where the public interface of a component was either called
interface or e.g.
implementation. The former would follow the interface/component split, the latter would have the implementation in the interface. Does this make sense?
Yes the interface namespace often feels like an extra unnecessary layer for newcomers. If your component contains only one namespace we could put the implementation there if we want (and it can be the right decision in some cases) but quite often we want to divide that single namespace into several namespaces, to improve readability and changeability. In this case it will be quite clear that one of the namespaces will expose the interface (even though it may also contain implementing code) and the other interface will only contain parts of the implementation. For me the interface is always the interface, even if you mix with implementing code, because the functions (and def/defmacro definitions) in that namespace is what the component exposes to other bricks. This also means that you need to be careful to set all definitions that you don’t want to expose as private, if you mix, which is not necessary if you split the interface and the implementation from start. In any case, you should signal with the name that the interface is what is exposed and I really think that
implementation is a bad name for that.
Right, I wasn't necessarily suggesting
implementation as an alternative name. My (perhaps misguided?) point was that if you have a component that does not have any implementation in the
interface namespace, that makes it easier to use alternative implementations for that interface if need be. So a component having an
interface namespace can communicate "this component has swappable implementations".
A team might want to have a different naming conventions for components that don't have alternative implementations yet, or probably never will. Am I wrong?
All public functions in the
interface namespace (including implementing code) will be part of the interface. The way to create a new swappable component is to include all the public functions (and def/defmacro definitions) in that interface. An alternative implementation is always possible to create, regardless if you mix implementing code in the interface or not.
the goal should be that you can refactor a brick totally and none of its callers should notice. if you start with just implementing the functions right in
interface.clj, that's fine. you can refactor it later (say by splitting the implementations among one or more other namespaces) and no one else can see it. this is decoupling.
whether my component has alternative implementations is itself an implementation detail! most code shouldn't need to care - that's a deployment or test infrastructure problem.
Yeah, I'm totally on board with the interface namespace, the only issue is that the name doesn't play as well on non-jvm platforms. Fortunately we have a workaround for that : )
definitely true. I favour
surface as a universal replacement.
I'm leaning towards "component", though it's just as long as "interface" and I wouldn't mind shortening it. I kind of like the semantics of "contract" - a sort of reminder that if you change it you need to get everyone to agree - and it is shorter.
The potential problem with using “component” for “interface” is that it overlaps with main concept of a component. It will probably be quite confusing if you have to say “Let’s add a new function to the user component’s component”.
Of the names you suggested, I like “contract” best. It has a stronger connotation than “interface”, but is a useful description of the type of relationship a building block enters into when it depends on a component.
It's helpful that "contract" is already used in this way in software: > It prescribes that software designers should define https://en.wikipedia.org/wiki/Formal_methods, precise and verifiable interface specifications for https://en.wikipedia.org/wiki/Component-based_software_engineering#Software_component, which extend the ordinary definition of https://en.wikipedia.org/wiki/Abstract_data_type with https://en.wikipedia.org/wiki/Precondition, https://en.wikipedia.org/wiki/Postcondition and https://en.wikipedia.org/wiki/Invariant_(computer_science). These specifications are referred to as "contracts", in accordance with a https://en.wikipedia.org/wiki/Conceptual_metaphor with the conditions and obligations of business contracts. https://en.wikipedia.org/wiki/Design_by_contract