hoaproject/Central

API documentation v2

Hywan opened this issue · 8 comments

Hywan commented

Hello fellow @hoaproject/hoackers and users!

Related RFC: #51, #52, and #53.

The API documentation is a mess, and useless. Not specifically in Hoa, but in the majority of PHP projects. Recently, I learned from Rust, Elm, Haskel, Caml… and they have a nice usage of it. I would like to change the way we write API documentation in Hoa.

Intro

What is “API documentation”? Basically everything written in the code. Not only the doc-comment on functions, classes, attributes, or methods, but everything.

I would like to define useful API documentation, which can be browsable nicely (see #53), that can be used to auto-check itself (see #52), and helpful.

Documentation format

First, let's start by defining the documentation format. HTML is awesome and would be the best, but it is hard to read in the code (HTML in comment of PHP, too much syntaxes). Moreover, we do not need particular semantics. So markdown is the format we will use. Of course, there are several versions of Markdown, so maybe we will choose CommonMark, don't know what is the best move here.

Elements of the documentation

<?php

/**
 * License code block
 */

namespace Foo\Bar;

/**
 * Class documentation
 */
class C
{
    /**
     * Attribute documentation
     */
    public $a;

    /**
     * Method documentation
     */
    public function f() { … }
}

/**
 * Function documentation
 */
function f() { … }

Class documentation

Explain what the class does, why it exists, how does it interact with others, examples, links to resources like RFC, online documentations, explain the design, explain the decision, explain the performance impact, design and decisions etc.

Provide at least one example about how to use it.

Attribute documentation

Explain what it holds, how it interacts with other, why it exists, design decision etc. If this is structural type, explain all its possible forms. Provide examples too.

Method and function documentations

Explain what the function does, why it exists, how does it interact with others, when should we call it, why, performance impact, design decisions etc.

Provide examples too, if possible for all of them.

Structure of a documentation element

A document element has different section in it, like:

/**
 * This is a complete description.
 * You have all these arguments. `$x` represents this, `$y` that etc.
 *
 * # My first section
 *
 * Hello, World!
 *
 * # Examples
 *
 * This example shows how this stuff works bla bla:
 *
 * ```
 * $x = 1;
 * $y = 2;
 * assert(3 == $x);
 * ```
 *
 * This is another example showing this and that:
 *
 * ```php
 * # use Vendor\Gordon;
 * use Foo\Bar;
 * 
 * ```
 *
 * # Exceptions
 *
 * In this particular circumstance, this method will throw the `E` exception.
 * Here is why, what does it mean and bla bla.
 *
 * # Contract
 *
 * ```praspel
 * @requires x: u8() and y: /fo+/;
 * @ensures \result: boolean();
 * @throwable …;
 * ```
 */
public function f(int $x, string $y): bool
{
    …
}

Special sections

There are special sections in this format:

  • Examples, provide a list of examples, where code blocks are real examples. The type of code block can be empty (3x), which will default to 3x + php, or any other types. See #52 for more details about this,
  • Exceptions, provide explanations and examples about what exceptions can be throw. Can be related to #51,
  • Contract, contain only one code block, if its type is praspel, then it will be used for Contract-based Testing, see Hoa\Praspel.

These sections are not mandatory!

assert in code blocks are related to #52.

No more PHPDoc?

Yes. Removed. We have types in PHP 7, we have meaningful argument names, PHPDoc is useless. The first part of a method documentation can explain what the argument does. More importantly, if this is not possible to understand what a method/function does just by reading its name and its argument names, then we have an issue.

Outro

I think this is a nice direction to go. It will be hard, but it will be good. This RFC is strongly related to RFC #51 RFC #52, and RFC #53.

Thoughts?

More importantly, if this is possible to understand what a method/function does just by reading its name andume its argument names, then we have an issue.

@Hywan I don't get your point here! What do you mean by we have an issue if we understand what a method/function does?

Except that the RFC LGTM 👍

Hywan commented

I forgot the negation 😉!

Hywan commented

Fixed.

@Hywan great RFC, it will open the doors for some cool new tools :)

But...

We have types in PHP 7

This is indeed a good argument in favor of removing PHPDoc. Unfortunately, this feature (type-hinting on class and scalars) does not cover all use cases on all PHP versions: think about nullable return.

We will only get this feature when the related RFC will be implemented and merged in php-src. And even with this feature being merged, you won't be able to use it unless you drop support for PHP < 7.2 (or more).

Think twice before removing every PHPDoc annotations, especially @returns. The only workaround to this would be the Option RFC which I totally like :)

Finally, I don't know if IDEs can infer thrown exceptions. If not, it could be interesting to keep @throws.

Hywan commented

@jubianchi The IDE part is also very interesting. Should we write plugins to support Praspel? Heavy, long, not gonna be used I guess… so we will be marginalized, and this is a not a good thing.

For the @return annotation, this is not required if we target the latest PHP version. I will come back to it in a moment. For the @throw annotation, here is the situation: It seems to be ignored. Most IDE will not warn if a method can throw an exception and this isn't in a try/catch block, because the exception can throw to the callee, etc. until reaching the root of the program, and even here, we can have an uncaught exception handler. What scenario did you have in minds?

Hywan commented

I said I will come back to “if we target the latest PHP version”. Well, we have this discussion currently, http://discourse.hoa-project.net/t/drop-php-5-5-in-favor-php-7/234/2. If we need PHP 7.1, then, why not targeting 7.1. The project will still work anyway, people will not receive new updates, that's all. Popular libraries are stable, most of the others are stable too, we can drop 5.x, and target 7.1 or 7.2 directly. We will need time to implement all these RFC, particularly this one. We should not restrict ourselves on a version number that will be outdated when the RFC implementation will be over.

Hywan commented

In http://discourse.hoa-project.net/t/drop-php-5-5-in-favor-php-7/234/5?u=hywan, I made a recap about why we should jump to 7.1 directly.

for me phpdoc helps a lot in ide... but you can produce stubs like some other libs do to help IDE.