A very short story on pains of too much encapsulat...
# feed
a
A very short story on pains of too much encapsulation: https://dev.to/altavir/when-encapsulation-is-a-trouble-3k4h
c
Another reason they could have done it this way: if they want to change it/remove it, it's not a breaking change, which gives them a lot more room for modification in the future.
☝️ 2
s
Also bear in mind that an API whose implementation has hidden/encapsulated methods/properties that, in principle, could be publicly exposed may be hidden/encapsulated because that part of the API may not be ready yet for public consumption from the author's point of view. Opening up API brings the responsibility to maintain it, fixing issues, documenting it, making sure it remains backwards compatible for future changes, etc. Lot of (extra) work for the author 😀 If you think this part of this API needs to be opened up, you could submit an issue.
a
@CLOVIS there is an unstable API flag for that. The problem I encountered here is not unique. For example, take DataFrame. It has a nice external API layer, but when you want to implement a custom column, for example, you find out that most of technical details need to be reimplemented.
@streetsofboston The same answer here. You can use experimental opt-in flags for that. And it is not correct to say that it is an "implementation" detail. In this case it is not implementation of a contract, it is a part of the logic, which is required for API to function.
I think that the common misconception is that only the outer layer of the API should be public.
1
c
These are different levels IMO. As a library author, as long as it's public, I try to avoid breaking it. I use experimental for things I know I will need to break, but I will attempt to keep the breakage to a minimum / not too frequent. I change private details all the time.
s
As an author, any part of your api that is public has price. It is a quite a balancing act to make your API as useful as possible (eg make as much public as possible) and to limit the price you pay for that (make as private as possible).
Caveat; I haven't used the API you mention in your blog-post myself. My comments are just general comments for api designs.
1
a
In this particular case, the logic required to auto-close the menu on click outside is private. This means that anyone, who wants to do a custom menu needs to re-implement it. API surface is not a single layer, it is multi-layered. And here we have a case, where we have layer 1 and, say, layer 3 exposed, but layer 2 hidden. So everyone, who wants a custom layer 3 has to re-implement the whole layer.
We can continue in #library-development by the way
s
@altavir Your example could indeed be a case where the API design was too restrictive, where it allows a customization at one spot, but doesn't allow it at another spot that is essential (either that customization should not be allowed at all, or opened up even more...) 🙂
👍 2
l
I can't really tell what is "implementation which should be private" and what is "logic that is used by default should be public", but I agree on this particular aspect of compose: so much is unchangeable. I think this is a problem of composition which is not that severe in inheritance world. When you create a Composble, almost everything is fixed. If you need another one with just a slight change, you'd have to copy all the code. This is the biggest design problem I found in production.
1
o
Been there too. I understand the issues of opening up the wrong parts of an API, but in general with Compose, I'd say we need much more composability across Composable layers.
a
@Loney Chou it is not an intrinsic problem of functional composition. It is more that rules are slightly different from what happens in regular object code. But, as I said earlier. I saw the same problem a lot in object code as well. For example when API requires a type, which does not have public implementations and could only be created inside.
1