Fork me on GitHub

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 interface.


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.

👍 1
Braden Shepherdson15:03:02

export and public are also reserved. surface?


Maybe interface- would work? Then we keep the name interface but add a dash at the end.

Teemu Kaukoranta08:03:18

@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.

Teemu Kaukoranta08:03:25

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.

Braden Shepherdson14:03:11

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.

polylith 1
Braden Shepherdson14:03:57

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 : )

Braden Shepherdson15:03:28

definitely true. I favour api or 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.


I like contract too.

Norman Kabir13:03:55

It's helpful that "contract" is already used in this way in software: > It prescribes that software designers should define, precise and verifiable interface specifications for, which extend the ordinary definition of with, and These specifications are referred to as "contracts", in accordance with a with the conditions and obligations of business contracts.


"api" is short, but it overlaps a bit with the description of bases - they're the "public api". It might be confusing to have a distinction between a (private) component api and a public base api.