Suggested areas for documentation improvements

Suggesting a couple of areas where documentation could be improved. I’m fully realizing that docs are considered in flux as the language changes, but thought feedback is welcome regardless.

  1. More prominent linking from Documentation - The Zig Programming Language to the standard library reference.

  2. Comptime and comptime reflection: builtins associated with comptime are documented under the Builtin Functions, but IMO this format is not adequate when writing code that inspects types. You can kind of get an idea of what functions can work on types, but when writing actual code, most likely you’ll need to look up the details from the std library source code. ZLS doesn’t seem to handle type infos very well (at least the version I use), so it doesn’t help here much either. I’d find it easier to browse the type-related built-ins in some sort of HTML format rather than code.

  3. std.json module could do with some end-to-end examples on how to use it. I was happy to notice that it recently added diagnostics (you can see line/column info for parse errors), and I can use it with a scanner when calling std.json.parseFromTokenSource. However, I guess I can’t get diagnostics if I use std.json.parseFromSlice since the scanner is internal. The parse API also had changed how tagged unions are now handled (github issue), breaking my existing code. So I started switching to using parseFromValue instead as I can override “JSON → Zig value” mapping by defining jsonParseFromValue on my type. I succeeded in doing this but it’s not very clear from the docs how to do this. Again, I seem to lose diagnostics if I use parseFromValue so I have no idea which node in my input JSON had a problem if the input doesn’t map to my types. There’s also a jsonParse function that I can attach to my types which would be called when parsing through std.json.parseFromTokenSource but I have no idea how to use it.

I guess my 3rd point is half-rant, half docs feedback, but I find this module a little hard to use. I think good end to end examples in the std.json docs would go a long way to make it more approachable and teach users of this library the idiomatic way to use it.

IMO the “lack of interfaces” in the core language may also make exploring API’s such as std.json a bit harder as hooks like jsonParse and jsonParseFromValue are not present in the top-level functions or their types.

In terms of your 3rd point, are you referring to this page? Documentation - Zig

If not disregard this point…

In regards to examples, I think it’s important to note that this documentation is auto-generated which has a few pros and cons. On the pro side, it will stay current with the implementation if the doc-comments are updated as well, meaning that it only has to be updated in one place.

More to your point though - this also means these aren’t “example driven” documents. They certainly chart the technical specification, but some functions just simply have no description as they don’t have a related comment in the source code.

At some point, it would probably be worth supplementing this documentation with more direct examples in general (including your concerns, although I haven’t looked into the json section yet). Even though cppreference is a very unapproachable website from a readability standpoint, they still have quite a few examples per page that give the user a quick idea about how to use stuff. That said, it would be additional effort to keep up the documentation apart from what is already auto-generated.

Just my two cents.

Yes, the standard library API reference. I don’t think I’ve seen the std.json module documented elsewhere.

I used to do a fair bit of Haskell coding in the past and in the Haskell community, people are often recommended to “just follow the types” when they’re trying to learn how to use some new library. I was never good at “just following the types”, I’m much more productive if I can start with some example code that already compiles and does something.

I think it’s a problem in many languages that it’s often easier to write a blog post or a gist with some code examples, but very often these don’t end up in the actual reference documentation.

2 Likes

I think a major development in programming language documentation has been the inclusion of sample code within the documentation and having those samples run as part of the tests. This ensures that the documentation (at least the samples) stay updated as the code evolves, while at the same time showing the user how to do things. I think Zig’s tests could be a natural fit for this, maybe you could mark a test as a sample in some way, telling the doc generator to include it in the docs.

/// This is how you get the nth Fibonacci number
test "[example] get nth fibonacci" {
    const n = 1;
    const nth_fib = fib(n);
    std.testing.assertEqual(@as(usize, 0), nth_fib);
}

Here the [example] would be the marker.

6 Likes

The best documentation I’ve seen is Android, almost all public functions have some doc-comment, and the more complicated ones sometimes have 200+ lines of doc-comments explaining the usage, and documenting the edge cases.

I honestly think that’s a great idea. I was thinking about that writing some more tests cases here - it’s a lot of use cases that have to directly prove correctness. I wonder what it would take to do this?

There is one thing to consider though - I think a good thing about Zig (up to this point) is the readability of the standard library. Maybe instead we should just make it a point of importance that Zig developers should feel comfortable just reading the standard itself (and there in-lies those test cases). I think there is a long standing hesitancy from reading library code because of how dense and convoluted it can be, but I haven’t had that problem thus far with Zig - quite the opposite.

2 Likes

Yeah, no argument from me that hyper-verbosity can be as opaque as saying nothing at all. I think what @dude_the_builder and myself were referring to were executable snippets that just demonstrate the code in use. Again, cppreference does this and that was probably the better part of that website until fluency in standard-ese sets in.

1 Like

Same here with my experience reading the Zig source ocde directly. At first I was a little weary, coming from languages where the source is unreadable and docs are the only way to learn things. But soon I was pleasantly surprised as to how easy the Zig source reads. Now I find myself going straight to the source code and then moving to the docs if I don’t find what I’m looking for.

1 Like

I also dive right into std library source quite often. Especially when I’m in VSCode and can jump directly into symbol definitions. But it depends on which module I’m looking at. Sometimes the test source is all I need to get going, and that’s great! But some modules, such as std.json, is split into many source files and just browsing through it on GitHub is a little tedious as there’s apparently no way to follow symbols to declaration in the GitHub GUI.

A well-formatted API reference can have an advantage over browsing source directly, as it can be edited to focus on the main usage of the library.

2 Likes

I don’t have a huge issue with “follow the types”, but for that I’d like to have better “backwards” search/index available. For example if I have found a thing I need, I’d like to get a quick reading which functions return the thing.

I think the Guides feature could be used to create some high-level documentation with explanations and examples (maybe including @dude_the_builder’s idea of marked test case examples), I think that would address the 2nd and 3rd point.

Your 1st point also sounds good, but I haven’t thought enough about it enough.
I think one example is, to be aware that there are a bunch of useful functions in std.meta that help you avoid having to repeatedly come up with your own replicas of those (and probably there are similar cases).

But the other suggestions about reading the standard library source, also help in finding these shortcuts.


Thinking more about your 1st point I almost would want a specially styled link style (maybe in some other color than blue) that links to things in the standard library that are related to the section in the language reference. Or maybe each section could have an optional block of references to the standard library.

For example the Tagged Union section and @unionInit builtin would link to:
std:meta.Tag
std:meta.TagPayload
std:meta.TagPayloadByName

Showing/hiding these references might be nice too.

3 Likes

Looking at the language reference:

Introduction

Often the most efficient way to learn something new is to see examples, so this documentation shows how to use each of Zig’s features.

Zig Standard Library

Zig’s Standard Library contains commonly used algorithms, data structures, and definitions to help you build programs or libraries. You will see many examples of Zig’s Standard Library used in this documentation.

I think one good first step would be to create additional tests that serve as examples for things that currently aren’t really explained. For example @unionInit could use an example test that illustrates how it is used and also show off the useful std.meta functions.

While thinking along those lines, what if the tests that are in the reference would actually link to the standard library (so the code would be clickable), however it would be important that this doesn’t make the code awkward to copy. Similar to how the Racket documentation cross references all the things, even in code examples: 2.3 Lists, Iteration, and Recursion

This is probably not easy to implement (racket updates some documentation index-ing structure every time you build documentation), but from a user standpoint it is one of the things I have appreciated a lot about Racket’s documentation.

1 Like

Wow that Racket docs feature is impressive!

1 Like

Sorry I’m arriving to this discussion a bit late. I’m going to give some info instead of replying point by point to each comment:

  • For 0.12 we plan to merge language reference and stdlib docs into a single thing by turning the langref into a guide. We also plan to add in the same release a second guide that explains how to use the build system to solve common use cases, and probably more in the future.

  • Zig has a way of marking a test as a end-to-end “how to” test (called doctest). This is the syntax:

pub const MyType = struct {
   // ...
};

test MyType {
   // how to use MyType, will be displayed in autodoc
}

test "mytype is not borked" {
   // this is a normal test that won't show up in autodoc
}

And in fact std.json does have a few doctests (see bottom of the page): Documentation - Zig

7 Likes

So to be clear the test MyType... will show up in the autodoc and run as part of the usual tests? That’s great!

yes, it’s a normal test wrt zig test and the fact that it refers to a decl directly (instead of having a string name) marks is as documentation for autodoc.

if you click the autodoc link I shared above you will see that std.json.parseSlice does have a doctest

4 Likes

My first post! I was doing research to inform a vision I have for Zig documentation and came across this comment so I thought I’d just comment in place.

Regarding For 0.12 we plan to merge language reference and stdlib docs into a single thing by turning the langref into a guide, a common and quick solution to linking content so it’s coherent and looks like it’s from the same source is to skin them so they look like they’re part of the same product and simply provide a link between them, either in the menu or navigation panel. It shouldn’t matter where each piece of content is hosted or how it’s generated, and adapting tooling to get the same result seems inefficient (and locks you in early to a particular tool).

The desire to merge the language reference and stdlib reference and add another guide also seems somewhat ad hoc, especially in view that I don’t see guiding information architecture principles in the released docs that support making such a decision. One principle might be that reference content is primarily composed of syntactic information (including examples) and the semantic content, which is also necessary and describes the how-to, is in the guides/tutorials. While there are valid arguments that auto-generating content doesn’t produce quality content, I think that for a fast-moving, new system it 's OK to auto-generate (at least for reference content, but not for how-tos). But if there are multiple contributors, that means you also need to provide some guidance on what goes into a reference document, what should be left out that belongs in the guides, and guidance on how to format it. For example:
https://go.dev/doc/comment
https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings
and the various Doxygen and Javadoc examples over the years.
In general, I don’t see that a sufficient doc foundation has been established to be able to make informed doc structuring decisions. Without that foundation, decisions seem ad hoc, tending to dig the hole deeper and entail effort that might, otherwise, not be needed.

I’m not ranting and hope I’m not being too negative or critical, making a bad impression in my first post as a newbie. I really like the potential that I think Zig offers and plan on using it for a project I have in mind.

I’ll elaborate on my thoughts about Zig docs in the next day or so, hoping to get a sense of the appetite for improving them. You don’t need to wait until the implementation is mostly done to address the docs; having a well-defined, intuitive structure actually facilitates getting it done.

3 Likes

First of all, I am a newbie in Zig, but I worked in C/C++ for decades (before doc comments were common) and then in Java for (more than) a decade, when Javadoc were already universal (and in Javadoc / Doxygen, you can put almost everything and have it properly rendered, sample code included).

So, I directly learned the importance of doc comments to familiarise oneself with something new (say, a new library or even a new language). The current std lib source code may be readable, but:

  • this is probably less true for someone who’s learning a new topic or is choosing a new library (and so the lack of other docs becomes a barrier to popularise the topic or to foster the adoption of the library);
  • it may become more complex and convoluted in the future, as the language evolves;
  • the documentation of the standard library may tend to establish documentation for the whole language eco-system; I have already noticed that many third-party Zig libraries have (almost) no doc comments in many cases (or have them for collateral notes rather than for the primary semantics / working of a file / function / …). I believe this is to be counteracted.

In summary, my very humble (and newbie) opinion is that the standard documentation should include plenty of doc comments (with “too verbose” better than “too terse”), possibly even extending its syntax to allow to mark code samples as such, parameters (with their documentation) as such and so on.

And better now than later, as the documentation is either written during the development or, in practice, never.

1 Like

In considering developing a product using Zig, I was put off by a couple of things, which caused me to detour to commenting on your docs:

  • The unconventional organization of the docs.
  • It took 3rd-party docs to install, build, and run in my Linux environment.

I’d expect a doc site to mostly be about docs. By doc site, I’m referring to Learn ⚡ Zig Programming Language. Doc site navigation should be almost entirely in the left panel. In small sites, you rarely need menu tabs, although, Download and Source Code could certainly be justified as menu items. I wouldn’t expect News, Zig Software Foundation, and Join a Community to be on a docs site. A common docs mistake that startups make is conflating marketing material with dev/engineering content. I understand the tendency but it tends to obscure and distract from the content a developer is really interested in.

Thumbs up to choosing Hugo for your doc site (sort of). It’s what I recommend for startups, porting to a more English-major-centric static site generator later in a company’s development. If you view Learn ⚡ Zig Programming Language as an organization landing page, which I did at first, Hugo seems like an odd choice. Whatever tool corporations tend to use for their Home page might be better. But as a docs site, Hugo works. But you don’t actually use Hugo for your docs. Instead, there’s this strange langref.html.in file that is your real docs. I’d highly recommend porting that to Hugo .md files. The more conventional implementation might encourage more people to write for Zig docs instead of writing for their blogs.

As far as the auto-generated stdlib doc, I’m in agreement with mgavioli, above. The autogen vs. !autogen debate is decades old and no minds have been changed; it’s not likely to be resolved here. So autogen, as you do now, is fine, although I don’t think it gives you the best docs and the argument for maintaining currency with the code doesn’t tend to be realized in practice. Also, for something like stdlib, it’d be contemporary to have a 3-panel presentation, nav | content | example; see the DocuAPI Hugo theme.

It would be a good idea to document the stlib functions as you code them, not after the fact (although, the horse is already out of the barn). Something that might help is to not approve stdlib PRs unless the associated functions are also documented; but then you’ll need an autodoc style guide, as previously mentioned, to avoid a mess.

Here’s a proposed doc structure. I think it’s more conventional and modern than the current structure, making it more like what the reader expects to see. Tweaks are fine and expected but the core doc skeleton and vision must first be established. Of all the doc design objectives, these are the ones that are driving this proposed structure and associated process/tools:

  • maintainability
  • ease-of-authoring
  • discoverability-of-content
  • coherent doc style

Documentation ::=

Release notes

Quick start

Introduction

Learn

    Compile and build options
    Target environments
    General application structure
    Guides
        Building with Zig
        Testing
        Memory management
        [ tutorials per language feature, including ...]
        Inline assembly
        Package management
        Undefined behavior
            Compile-time
            Runtime
        C integration

Reference [use 3-panel layout: nav|description|example]

    Zig language reference (just the syntax, with examples)
    Builtin functions reference
    stdlib reference
    Environment variables
    CLI reference
    Keywords

Tools

Examples

Program style guide

3rd-party resources

    A structured introduction to Zig
    Ziglings
    Zig on Exercism
    The road to Zig 1.0
    Zig and the relationship with LLVM

The 2nd- and 3rd-level headings are just to give the flavor of what goes in those sections. A key principle is that Reference content should be separated from How-to content. The How-to is in the Learn section. Guides is usually called Tutorials but almost everything that isn’t Reference is a tutorial. Using “Tutorial” as a broad, encapsulating term lets you differentiate the different kinds of tutorials: guides, quick starts, tech notes, recipes, etc. Along those lines, Learn is a node of Documentation, as Reference is, not vice versa. The menu item should be Documentation, not Learn. I’m not used to seeing it that way so it threw me off, initially. I’ll admit that Learn is becoming more common among companies as a main category and they include all their resources under Learn, but they also tend not to have very developed documentation. When I want documentation, I look for Documentation; it may be a cultural thing.

A stretch goal might be to also envision Cookbook documentation. I propose that because, other than actually using a system, a Cookbook is considered the best form of documentation for teaching a system. Each recipe encourages hands-on use of the system, covers error paths, and provides links to additional resources, in addition to walking the reader through progressive steps toward learning the system. It’s a stretch and lots of companies (and O’Reilly) that have a Cookbook doc don’t do it right.

Finally, some doc approach recommendations going forward:

  • prototype the docs-only Hugo site using existing content (port langref.html.in to .md files)
  • provide a clear visualization/nav of what kind of content goes where; reference-learn-etc. One benefit is that it makes it obvious what’s missing.
  • integrate 3rd-party content if it’s better than official content
  • create a minimal doc style guides for contributors; preferably based on Google Dev Docs Style Guide.
  • use Vale, vale.sh, in the doc build to validate doc style guide conformance.

I don’t have a big picture view of what is going on with the development of Zig’s documentation, but recently there have been some changes regarding autodocs and I believe sooner or later Hugo will be replaced with Zine static site generator.