[WIP] Documentation Refactor
Iterative process.
Feel free to comment on sections or contribute.
@MangelMaxime I'm concerned that exhaustive/detailed documentation will just bury the codebase in fluff. However, I do think it is also helpful, and a mark of improvement. Could we side step this issue with .fsi files instead? What would the implications there be.
Edit:
From my understanding, we might be able to have documentation show through .fsi signature files without having them present in the implementation files, or even have implementation specific documentation for contribution and user/consumer specific documentation through the signature files. But this does make maintenance more difficult.
We would not be able to generate the signature files after the first iteration; I assume this would overwrite the documentation that would be added specifically to the signature files. Of course, this could be staged though, a contributor could generate the sig file, and then copy the new/changed sections to the version controlled sig file.
Could we side step this issue with
.fsifiles instead? What would the implications there be.
Using .fsi does means that the documentation is written in the .fsi instead of the .fs file, but there are several issues with .fsi files.
- The DX is not good... when you try to navigate the code and do things like
Ctrl+ClickorGo to definition/implementation, you often ends up in the.fsiwhen you wanted the.fsfile and vice versa - People are not well versed in
.fsiand often intimidated which can make contribution harder - It means you need to do twice the same work sometime, like if you add a new API, new DU case, you need to write it at both places
I wrote Fable.Form using .fsi file originally and I decided to revert it because of these reasons.
Having better documentation is always something worth it, we just need to find the right balance.
cc @dbrattli any thought ?
With regards to target example codes for common members, what about linking to a Fable Repl with the example code so that the user can change the target as needed while still seeing how the member works?
An advantage would be that documentation examples et al can be updated independent of whether the fable.io docs have been or not. As an example, the interaction of Erase with anything other than a Union isn't mentioned in the docs on fable.io, but we can easily quickly add a reference to it in the docs and link to a repl with the example.
An example would be this example code:
open Fable.Core
[<Erase>]
type ValueType =
| Number of int
| String of string
| Object of obj
[<Global>]
let prettyPrint (value: ValueType) = nativeOnly
prettyPrint (Number 1)
prettyPrint (String "Hello")
prettyPrint (Object {| Name = "Fable" |})
type AnimationBuilder() = class end
let anime = AnimationBuilder()
[<Erase>]
type TimelineBuilder() = class end
let tl = TimelineBuilder()
I'm in favor of better documentation 🥰 However, there are some things about this PR that worries me:
- Having JS specific examples will be confusing and feel wrong for those of us that use other targets, and pseudo code will most likely just confuse AI to give both incorrect suggestions and completions. Links to https://fable.io/docs/ can be good, but I'm not in favor of language specific links, i.e https://fable.io/docs/javascript/features.html#erased-unions
- Maintainability. When making changes to Fable.Core it will be significantly more workload for us to keep examples up-to-date. Especially when there are external links that needs to be updated as well, and in multiple locations.
- Having JS specific examples will be confusing and feel wrong for those of us that use other targets, and pseudo code will most likely just confuse AI to give both incorrect suggestions and completions. Links to https://fable.io/docs/ can be good, but I'm not in favor of language specific links, i.e https://fable.io/docs/javascript/features.html#erased-unions
Fair, can just reduce the documentation to provide F# example code of usage and link to the homepage for the docs.
Keep in mind there are already dead links in the docs, and I have mostly just included the already existing links into the xml notation.
- Maintainability. When making changes to Fable.Core it will be significantly more workload for us to keep examples up-to-date. Especially when there are external links that needs to be updated as well, and in multiple locations.
The trouble here in my mind is that there is no fleshed out documentation source to begin with. The Fable Docs are not up to date, or are reduced with regards to the nuances of their usage (such as Erase being applicable to more than just unions).
My preference is to document the source code in full rather than the website, as the onus should be on contributors to update the documentation with their changes so that it is iteratively up-to-date rather than requiring larger efforts at major points.
If we were to instead delegate documentation to being 'in-full' on the website, then we would have the same issue of maintaining multiple pages covering the same material that have to be kept up to date by target language users. We are more likely to have contributions that don't get pushed to the docs, and then I fear there will be a slow build up of hidden features as we invariably miss some changes being added to the docs when it is updated. In saying that, how would the next major release be done with regards to the docs? It would be pretty gruesome if this type of process is heaped only onto the major contributors such as yourselves since the website documentation feels 'separated' from the implementation.
In saying that, I would defer to whatever informed choice is made. I will continue to do small iterations until a larger decision is made on some standard with which to finalise everything with.
Edit: I would also mention that at a certain point of familiarity, we are less likely to refer to the website. At this point, an incorrect tooltip will be more likely to prompt someone to make a small contribution in correcting the documentation, especially if they do not use the website docs. In this sense, I think it might invite more small contributions from seasoned users too. Just a thought
I am sharing the feeling of @dbrattli
Better documentation is always for the better, but in regards to Fable specificity I am wondering if the XML Doc is the right place for it.
I am wondering if the effort should not be put on https://fable.io/docs/, in the past I put a lot of effort making https://fable.io/docs/ relevant again, and finding a structure which works (it is not perfect of course).
On the website, we are not limited about what we can do (beside following the current structure for now) as the user can narrow down what he is looking for. It also allows us to have a single place where to redirect users.
Something to note also, is that Fable.Core don't change that often so in general if we document a function / attribute once, it stays relevant for a (very) long time.
If someone is willing to contribute to a PR here, I think they would be ok with sending a PR to Fable Docs repository and that's up to us as maintainer to ask them kindly to do so. If they offer documentation in this PR, we could also port it their manually. Updating the documentation is a straight forward process in general, the difficulty is in being concise enough but explicit too.
For example, so people like to write lengthy documentation but sometimes a short sentences with 1 example is all we need.
In this sense, I think it might invite more small contributions from seasoned users too
I understand what you are trying to say, but from my experience in OSS we are often lucky if people open an issue. Creating a PRs is rare in general especially on complex project like Fable because it can be intimidating to work with.
I think my stance currently is to keep XML doc really focused on a 1-2 sentences summary and use https://fable.io/docs/ for the complete explanation with edge cases etc.
Sounds good, I'm happy with that, and you both have more experience with OSS so I'll definitely take that reasoning on-board.
I'll make a pull on the website in conjunction with this and iterate over the docs simultaneously. I'll reduce the remarks to essentials, such as hinting towards related attributes/functions, or relevant considerations/examples. Will append the XML docs with links to the Fable docs:
/// <seealso href="https://fable.io/docs">
/// Fable Documentation
/// </seealso>
Thank you both!
I'll make a pull on the website in conjunction with this and iterate over the docs simultaneously.
Can you please keep the changes on the docs for this PR and the rest separated please. It will be easier to review as it will be more focused and smaller
I'll ask for this block to be reviewed and see if the style is agreeable before moving forward.
PS: I've left the TypeScriptTaggedUnion attribute as I wasn't sure if we may also take this chance to deprecate the TypeScript name, or move it to another namespace such as Fable.Core.JS or JsInterop.
I am still wondering if all the
seealsoadd something or not.I mean if people want to learn something about Fable, the first place to go would be Fable documentation.
/// <seealso href="https://fable.io/docs/"> /// Fable Documentation /// </seealso>
Agreed, doesn't serve much purpose unless it can route to a specific page/section.
I find the explanations with code samples difficult to interpret because in general. This is because, I think without the compiled code it is difficult to understand what they do.
One of the good example for that is
Erase, even if I am a user of Fable since 7+ years I have a hard time understanding what the description means.
Fair enough. I've reduced that out, but what about the general description? The thing is I think there is difficulty to remember viewing these documents without any context. The very concise documentation seems natural, but it really said nothing/meant nothing when I was trying to learn Fable.
I would usually have to just see how others were using it and copy paste. Whether in the xml, or on the website, there should be somewhere that explains how these things work.
Personally, I prefer there to be 0 requirement on external documentation (ie you can learn everything from the documentation on the codebase rather than needing to go to an external website), which is probably what influences my contribution style. This is understandably NOT something that can be done with Fable, but it does inform my style.
Where if I look at the documentation, I can directly see the effect it has.
Agreed.
Something to remember is that often these functions, attributes are used to created bindings so in general people know what the JavaScript or Python code they want look it. Which make it easier to understand by reading Fable docs.
This is at least how I learned it, and based on the popularity of similar blog post that's what works best for most people.
I disagree, I think the information on how to use Fable is pretty scattered across blog posts and libraries/repos that use it because the documentation primarily does not attempt to explore such topics itself, and the advanced usage and nuances of attributes are not entirely discussed or clear.
My opinion comes from recent experience, having just over the past 6-8 months started learning how to use it. I understand that I may just be slower, or I was learning in isolation, but I think it is important to not think our learning experience justifies the current status quo.
Some of the first plugins I reach for in an IDE have to do with making it easier for my tooling to show me the documentation, and to consume it within the IDE. This might just be me though.
I feel like I saying mostly negative thing in this PR, and I don't like that feeling. If my wording is bad feel free to reach to me, it is possible that I am really conservative too.
No, I really appreciate the honesty and feedback, because it helps me improve, learn, or understand others perspectives. I really do appreciate it. Thank you!
I feel like really simple comments like:
/// <summary> /// References to the module, type, function... will be replaced by import statements. /// </summary> type ImportAttribute(selector: string, from: string) = inherit Attribute()Is enough and people need to go to Fable docs in order, to learn special syntax like
[<Import("default", "my-lib">] [<Import("*", "my-lib">]for JavaScript, because in Rust, Python it will not be the same.
Honestly, the simple comment means nothing to me without having seen the docs first, and a lot of the documentation is like this. I think we become complacent with our breadth of experience/knowledge of the codebase informing the level of explanation required for someone without it.
Without example etc I HAVE to check the docs and hope it is explained further. As mentioned before, I understand this isnt possible in the context of Fable. I still think some example of usage in F# should be required, but I'm happy to leave this for the website with regards to the shared attributes etc.
While I do think that having target specific code is not a good idea, I also would say that it is more helpful to be able to try to infer the behavior from a compiled example in a different language rather than no example at all.
I would appreciate if you could have a look at the most recent iteration 🙇♂️
Similarly, please let me know if my comments are inferred as being rude or anything like that. I thoroughly enjoy discussion and debate, but I am aware that text is a very poor format that does not convey the tone in which I intend for some things to be said. Some points I make might just be to invite opinion so that I can learn.
Whether in the xml, or on the website, there should be somewhere that explains how these things work.
This should be the case on Fable docs, for example https://fable.io/docs/javascript/features.html#mangle
Personally, I prefer there to be 0 requirement on external documentation (ie you can learn everything from the documentation on the codebase rather than needing to go to an external website), which is probably what influences my contribution style. This is understandably NOT something that can be done with Fable, but it does inform my style.
I agree for standard documentation this what I do also but in this is a special context IHMO.
My opinion comes from recent experience, having just over the past 6-8 months started learning how to use it. I understand that I may just be slower, or I was learning in isolation, but I think it is important to not think our learning experience justifies the current status quo.
I am not saying the current situation is perfect, but that in order for the documentation to be as easy to understand as possible in the context of Fable it needs more information than what the tooltip can delivers.
This goes back to showing the generated code, adding more explanation, etc. and the place for that is Fable docs currently and not the XML doc.