I was inspecting the type to generate some config files, and to my knowledge there’s no other API for this.
If that’s a layering violation, then A) I wish I knew that before writing my config, and B) I’ll have to figure out how to rewrite my config to employ mkOption’s apply, or failing that, even mkOptionType’s merge (which, tbh, seems more like a layering violation in my mind, but eh).
Or if there’s some other API for inspecting the type, I’d love to know about it.
Even since its inception 8 years ago, .functor was marked internal and never documented as a stable interface anywhere. (Edit: Well, mkOption { functor } is, but type.*.functor isn’t).
However it’s true that it provides access to data that’s not otherwise accessible, so it should be no surprise that users start relying on it.
The meta question is: If an interface is truly internal but accessible, how do you discourage its use and encourage creation of stable interfaces instead? I can only imagine these, best together:
Not documenting the interface in user docs (the case for functor).
Prefix the interface with _internal (not the case for functor), so that you can see that it’s internal at every use site.
I’m tending to err on the side of stability (in line with our values), so I’m also tending towards reverting this PR, especially because you’re already the second user to report a breakage (and I always estimate an order of magnitude more people running into the same problem that we don’t hear from).
There are ways of not breaking anything, they’re just more involved and will come with (soft) deprecation of .functor entirely.
Oh good find, I forgot about that. This is confusing, but not conflicting, because that page describes the arguments of lib.mkOption, which do need to be kept backwards-compatible, and the PR did not break that. There’s no mention of the result of the function. And the documentation for the different types also doesn’t mention anything about what their specific functor contains.
I’m actually fine with the breakage, as the change on my side was pretty minimal and the structural change makes sense at least as noted in the release notes. I was just moreso blindsided because I didn’t read the notes beforehand, as I got out of that habit (oops) once I switched off arch, and I’ll eventually have to figure out how to rewrite my code to avoid getting hit with a more complex breaking change.
I would be in favour of adding _internal to make it more obvious in any case, as I stumbled on it in the repl and then went to the (what I believed to be related) docs.
Regarding the docs. I think this this is a documentation issue too.
We should NOT remove the docs. But make it clear If functor is internal at all right now.
Regarding the breakage i am fine with both ways:
keep as is. Make migration more clear.
revert. Introduce an abstraction (i.e. getter function) and deprecate direct Access. Migrate both.
The second would require more time and downstream Projects must migrate to use the getter.
Versus:
downstream Projects migrate to use the now stable attribute.
I am fine with both ways although i think it would be less effort to just search github occurences and open Up a Couple of PRs myself.
I had the perception that the option types internal as well as the produced options are internal and should not be relied on. Instead i always try to organize my own Code in a reusable fashion so i dont need to acess types or Options back once i plugged them in.
I would be interested in seeing you use cases you Said something like “Schema”?
Sounds like you’re mixing some things up: The existing documentation is for the lib.mkOption argument interface, which definitely needs to stay and should be considered stable. However, accessing .functor of a type does not have any user documentation and is meant to be internal. Internal things definitely shouldn’t have user docs, because that would imply people can rely on it, which would effectively make it stable.
We did talk about stabilising .functor.payload in our call, but we didn’t make that a reality. To actually stabilise it, it needs to be documented and marked as such.
Yes and i think that this is the problem because this documentation is missing the ability to guide different user groups. (i.e. user vs contributor who might need more insights also on internals)
However I just tried to show the actual problem without having a solution.