FSharpPlus
FSharpPlus copied to clipboard
Improve docs
I opened this issue to discuss how can we improve the docs.
It's very valuable the input from users, as I have a deep knowledge of the library already, so my view doesn't help a lot.
We can start compiling a list of things we need to add, like another tutorial, some how-to sections, a better readme or doc home page and so on.
One place I go to often, is Operators.fs. The API doc is pretty useless since it orders alphabetically.... in the source there are sections delineated by comments, like // Tuple
WDYT about making separate modules for each section, and then potentially placing in sub folder?
Operators/Tuples.fs
...each would auto open same as "module Operators" does now.
The API doc is pretty useless
I fully agree with that part, i don't think they add anything at all.
We can definitely split it, but let's open an issue to split also extensions and to put stuff in folders, in general.
Was considering docs when I talked about separate files... only needs modules to reflect the sections in 'generic functions and operators' doc - the one generated from Operators.fs. I'll open a separate issue for it.
Other thoughts:
I like the github readme, but links there should be reflected in fsprojects site in sidebar.
Also, I could try to introduce the parts of the library a little more comprehensively in a intro/getting started guide, which would ideally contain links to detailed API docs.
Then I'd like to:
-
Use readme intro on fsprojects doc site as index, merge in examples to both.
-
Create tutorial stressing using FSI, adapted from current Tut
-
Create similar tutorial, based on installing into a new project, showing nuget/paket cmds, and how can adapt to your own existing projects
On Thu, Jan 16, 2020, 11:55 PM Gustavo Leon [email protected] wrote:
The API doc is pretty useless
I fully agree with that part, i don't think they add anything at all.
We can definitely split it, but let's open an issue to split also extensions and to put stuff in folders, in general.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/fsprojects/FSharpPlus/issues/239?email_source=notifications&email_token=AAAKBDJNPNJ7W5P3XDKGNRDQ6BN4VA5CNFSM4KHOZESKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEJEBOBA#issuecomment-575149828, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAKBDN4ONR3SUTE6ZMVJRTQ6BN4VANCNFSM4KHOZESA .
I agree, that would be really nice. But also a bit tricky, some functions make sense in more than one section, but I don't want to discorage you, please go ahead, and later we can focus in details.
Ok, here's an initial cut at intro for README and fsprojects home page. I want to add a little more, but what do you think about it so far?
I feel it was previously missing philosophy, motivation, scope and spread out 'what F#+ contains'.
I will move this to a PR, but putting here since I kept getting hung up on not being able to build docs:
FSharp Plus
F#+ is a base library that aims to take F# to the next level
of functional programming.
What if we imagine F# as more than it is?
F#+ builds upon FSharp, and by naming conventions and signatures,
can be seen to 'enhance' rather than 'replace' existing patterns
as much as possible.
The additions can be summarised as:
* extensions to core types, such as `String.toLower`
* generic functions and operators, like `map`
* generic computation expressions, like `monad`
* generic math module numerics,
* abstractions that capture common FP patterns,
such as the standard monads Cont, Reader, Writer, State
and their Monad Transformers
* some new types that work well with the abstractions,
such as NonEmptyList, DList and Validation
* lenses to easily read/update parts of immutable data
Note, however, that F#+ does not go into solving a specific
thing for a specific technology, such as JSON parsing.
Getting started is easy since you can start with enjoying some
of the extensions and generic functions, but you will find
other parts of F#+ unfold before you and become useful the
deeper in you get.
TODO:
Introduce each dotpoint above with a paragraph or two, with a simple example.
Add small example to each.
Mention conventions (i.e. different styles of calling)
Consider where to stick links to sections.
I love it, we can add Free Monads and add a small note about integration with other libraries.
Some other ideas:
- in the API docs, use well-known syntax, instead of the parenthesized one. I.e., you write
findIndex(predicate source). This reads as "apply function predicate to source, and the result is the input to findIndex". Obviously that is not what you mean, you mean:findIndex predicate source. - show an example of how each function can be used, incl output. People tend to understand examples quicker than anything else.
- fill in the blanks: a lot of functions have no description
- that you can see the signature when hovering is nice, and keeps the text concise, but personally I find it distracting. Perhaps consider a way to always show the signature? Or optionally, through a button on the page?
- Use mark-up in the descriptions, esp. when you refer to the parameters. Writing predicate, or
predicatemakes a difference in understanding the text. - Explain exceptional circumstances. For instance, do the string functions deal with
nulllike F# does? Or does it throw? Are they safe on invalid input (i.e., negative padding)? What is meant with codepoints? (I know the answer to the latter: they are not real codepoints, but the 32-bit encodings of the string. Codepoints would return 64 bit integers.) I'm not saying that's bad, but it would be great if such things can be explained.
I know that writing documentation is a lot of work, and where/when I can I'd love to help.
I agree with you.
The problem is that the API docs currently generate from source code into a specific format.
I think we can do some custom processing to add intro sections, show args better and examples like you mentioned. It's still new to me, but FYI is using FSharp.Formatting.
I started recently by adding the Extensions index page, because the generated docs reorganized alphabetically and it's hard to separate these from other parts from the generated API index page.
I want to repeat that for generic functions, Invokables and the mix of remaining parts.
However, there's also the slog of detailing each existing function. We can do this in the source code which is probably best, assuming we can extract better in future. Maybe start having a look where you noticed blanks?
Additionally, for generic functions it's a bit tricky to detail, and examples are sometimes hard without just showing a few specific instances. However, I'm keen to try!
Finally, I'd say we need some coordination and you should join the slack. Note we're in differing time zones which just has to be worked around.
On Mon, Feb 17, 2020, 7:00 AM Abel Braaksma [email protected] wrote:
Some other ideas:
- in the API docs, use well-known syntax, instead of the parenthesized one. I.e., you write findIndex(predicate source). This reads as "apply function predicate to source, and the result is the input to findIndex". Obviously that is not what you mean, you mean: findIndex predicate source.
- show an example of how each function can be used, incl output. People tend to understand examples quicker than anything else.
- fill in the blanks: a lot of functions have no description
- that you can see the signature when hovering is nice, and keeps the text concise, but personally I find it distracting. Perhaps consider a way to always show the signature? Or optionally, through a button on the page?
- Use mark-up in the descriptions, esp. when you refer to the parameters. Writing predicate, or predicate makes a difference in understanding the text.
- Explain exceptional circumstances. For instance, do the string functions deal with null like F# does? Or does it throw? Are they safe on invalid input (i.e., negative padding)? What is meant with codepoints? (I know the answer to the latter: they are not real codepoints, but the 32-bit encodings of the string. Codepoints would return 64 bit integers.) I'm not saying that's bad, but it would be great if such things can be explained.
I know that writing documentation is a lot of work, and where/when I can I'd love to help.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/fsprojects/FSharpPlus/issues/239?email_source=notifications&email_token=AAAKBDI23GBO3FXEXZDVV5LRDGO7TA5CNFSM4KHOZESKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEL4RLCA#issuecomment-586749320, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAKBDLYNEESDUEHGLXLU2TRDGO7TANCNFSM4KHOZESA .
Maybe start having a look where you noticed blanks?
@adz There are a lot of blanks here: https://fsprojects.github.io/FSharpPlus/reference/fsharpplus-string.html
Yep, very different timezones! ;) I'll have a look at slack.
Suggestions for how to improve the documentation from the f# code slack @Swoorup :
search by function signature would definitely mean a plus
the documentations assume you are already familiar with advanced functional concepts. And tutorial is very sparse. Also an example sample project would help. not just monad, but overall though.
Also @TheAngryByrd:
I highly recommend libraries consider this format: https://documentation.divio.com/ Doesn’t solve writing them but at least puts you in the mindset of which categories you should focus on. Waypoint and MiniScaffold have this as their starting concept with doc generation SAFE stack has been doing “How-To” with their “recipes” and that’s been so fantastic to watch come about.
I'm a big fan of docute for writing my documentation lately. It obviously don't auto-generate the API reference, which is a big pain to write it all out but I like the end result. Some examples of documentation for libraries I've written: Fable.SignalR and Fable.Jester.
I'd like to expand on my comment about https://documentation.divio.com/. (from @wallymathieu) After reading this thread, I think this project is exactly in need of the structure that divio provides. The arguments seem to be about how API docs aren't tutorials, which is true, but they're also different and both need to live along side each other. Also some of those tips falls into the "How To" category like configuring a project with a specific technique. I think F#+ would also do well with needing to fill out "Explanations" since a lot of the concepts here tend toward the harder/more academic side of functional programming and most of the terms of scary nor do they seem to solve a problem a person has immediately. Showing those terms in what they mean to an F# programmer would make this library all the less scary for newer people.
I highly recommend watching the talk and reading their website in it's entirety. I think this project (any really) would benefit from this structure.
In terms of actually generating, MiniScaffold and Waypoint have some some work in making divio the default concept but I still think our tooling isn't the best experience. FSharp.Formatting has taken interest in solving this issue too but I'm not up to date with all it's new changes.
MiniScaffold's docsTool is flexible since you get the source but you get all the source code making it a pain to keep up dated if you've made drastic customizations. It's able to build and serve locally. With how MiniScaffold has it all setup, it's possible to change either the tooling, the code/doc comments, or the content and get hot loading of the website. WIth how the FAKE build steps are setup you can release the docs separate from an actual release. When you do a regular release it will also generate the docs and put them into a separate commit.
- MiniScaffold docsTool areas of interest
- docsTool - holds all the tooling/templating for generating docs
- docsSrc - holds all the content like Tutorials/HowTos/Explanations/photos
- use in FAKE script
- Example docs generation shows the website with an example project. You can see the tutorials/howtos/references/explanations structure at the top.
Waypoints experience is much more simple and straight forward but you have to hardcode certain things in the loaders. It also updates the docs via a github action, which is really nice. Also build and watch locally. Fornax doesn't hot reload when you change code/doc comments or the generator/loader scripts themselves but works fine on content. Fornax also include search with lunr.js by default, and the site looks nicer than MiniScaffold's. I don't have as much experience with Waypoint so I may be incorrect in places here. (cc @Krzysztof-Cieslak)
- Waypoint using Fornax areas of interest
- docs puts all the generation and content in one folder
- Example docs generation shows the website with an example project. You can see the same structure on the side.
As @Shmew explained docute is nice for not needing the generation but does not solve generation for API references.
The big issue here is writing documentation. I think ideas about how to structure the documentation is valuable.
I'm unsure if docute or Waypoint are applicable since we already have a solution that uses F# Formatting.
I think we can always consider changing our documentation solution, as suggested by @Shmew and @TheAngryByrd
The most critical issue with the docs are the how-to-guides, which may end up re-creating fsharp-for-fun-and-profit if we don't keep them focused.
Perhaps there should be clear that you should start out with fsharp-for-fun-and-profit when you arrive at the F#+ docs then?
Maybe, but we should explain how each concept relates to which abstraction here, and how those long code samples there would look so compact and expressing better the related abstraction with F#+.
Perhaps having multiple doc sites in order to combine different strengths? Though that could mean that the navigation ends up a bit inconsistent.
Regarding replacing the docs generations I’m merely trying to show how the pattern has worked in other areas and take influence rather than suggesting replacing the docs current solution.
Yeah same with FsToolkit.ErrorHandling, I didn’t work on the first version of the docs and have yet to change them but I’ve thought about how to incorporate Fun-And-Profit. I think linking to them makes sense in tutorials or explanations. I don’t think some duplication is bad because even if it’s similar concepts, the code in fun-and-profit may be different from the library’s implementation and showing people your own take with more direct examples on the subject is generally good in my opinion. Many people can get lost mapping the concept that a blog has given and the implementation of that concept in a library that has taken more use cases and real world use in account.
@TheAngryByrd I actually did re-write some examples of fun-and-profit with F#+ and the structures remains exactly the same, just all the boilerplate gets removed.
So, at least with that experience, my feeling is that with this library you learn easier those concepts, because of the noise reduction
Ideally he should use F#+ in his site, and save writing and more importantly reading time.
I will have a look if have those diffs somewhere and will show you what I mean.
@TheAngryByrd I completely agree about the types of documentation shown in divio. It really helps to think in those terms! I actually read that a few months back when searching for ideas to improve/write docs.
We're about to push out a new template which has a better menu, and updated API docs. It's not a lot of new stuff, but it's better presenting what we've got. Once that's out, it'd be great to rethink the doc presentation in terms of Tutorial/HowTo/Explanation/Ref. A lot of it is pure reference since it's just collections of functions (like the Extensions), however, there's also a lot that requires explanation.
The docs state:
#r @"../../src/FSharpPlus/bin/Release/net45/FSharpPlus.dll"
open FSharpPlus
to include FSharpPlus. I had quite a hard time to figure out what works for me:
#r "nuget: FSharpPlus"
open FSharpPlus
Should this be updated? Let me know, if I should use another/new issue for this.
Yes. I think it would make sense to use F# 5 style include as an introduction to scripting with F#+.