In-source documentation pre-SRFI draft #2
Antero Mejr
(28 May 2024 05:35 UTC)
|
Re: In-source documentation pre-SRFI draft #2
Wolfgang Corcoran-Mathe
(28 May 2024 23:13 UTC)
|
Re: In-source documentation pre-SRFI draft #2
Antero Mejr
(29 May 2024 00:12 UTC)
|
Re: In-source documentation pre-SRFI draft #2
Arthur A. Gleckler
(29 May 2024 01:51 UTC)
|
Re: In-source documentation pre-SRFI draft #2
Antero Mejr
(29 May 2024 02:10 UTC)
|
Re: In-source documentation pre-SRFI draft #2
Arthur A. Gleckler
(29 May 2024 02:16 UTC)
|
Re: In-source documentation pre-SRFI draft #2 Philip McGrath (29 May 2024 19:19 UTC)
|
Re: In-source documentation pre-SRFI draft #2
Antero Mejr
(29 May 2024 23:37 UTC)
|
Re: In-source documentation pre-SRFI draft #2
Antero Mejr
(29 May 2024 23:41 UTC)
|
Re: In-source documentation pre-SRFI draft #2
Wolfgang Corcoran-Mathe
(30 May 2024 03:02 UTC)
|
Hi, I have a few thoughts and concerns from a fairly brief reading of the draft and discussion. There's a lot about documentation that's a matter of taste, so a word on where I'm coming from: I'm primarily a Racketeer, and I mostly write Scribble documentation out-of-source, though I have also used `scribble/srcdoc`. I write some Guile documented with its built-in plaintext docstrings and, for Guix, Texinfo fragments embedded in strings and a separate Texinfo manual. I've also contributed to the Chez Scheme User's Guide, which is written in stex [1], a subset of LaTeX with embedded Scheme that is preprocessed to plain LaTeX and rendered either to PDF by a normal TeX implementation or to HTML by one of the stex tools. Of these, Scribble is by far my preferred system. [1]: https://github.com/dybvig/stex Maybe I should also mention that I'm primarily familiar with Racket and R6RS, and have had to check R7RS Small to see what is missing. That perhaps leads to my broadest question about the goals of this pre-SRFI: On 5/28/24 20:12, Antero Mejr wrote: > Wolfgang Corcoran-Mathe <xxxxxx@sigwinch.xyz> writes: > >> I had difficulty with the notion of “attached” documentation as >> you’ve described it. What does it mean for ‘make-documentation’ >> to take “an expression” as its *content* argument? In your example, >> you pass it the value ‘(+ 3 2), but the idea, of course, is to attach >> documentation to expressions, not values. (In other words, shouldn’t >> ‘documentation-object’ return a syntax object?) Maybe I’m missing >> something about how you’re expected to invoke these procedures. > > The idea is to call (read-doc) to extract documentation from a > file/port, similar to how a REPL would call (read). When there are no > documentation comments, (read-doc) is the same as (read). When there > are, instead of returning an expression/object, (read-doc) returns a > documentation record, which wraps the expression/object along with the > text of the associated (or "attached") documentation comment. The > documentation comment must be "adjacent" to the expression/object in the > source code. Typically documentation comments would be placed > immediately before the expression, but I left the interpretation of > "adjacent" up to the implementation, based on feedback I received > earlier. > > The documentation-content field is an unevaluated expression or readable > Scheme object, since R7RS-small does not have #'() syntax objects. > What is the line between what this SRFI wants to make portable, and what is to be left to the implementation? In my view, the most useful thing would be to let Schemers write portable Scheme libraries with portable in-source documentation. But some aspects of this proposal seem to go in sort of the opposite direction: it specifies an API for documentation *tools* portable to many Scheme implementations, rather than focusing on making the *documentation* portable to many tools, including tools that might be integrated into a Scheme implementation. Leaving the interpretation of "adjacent" up to the implementation makes documentation non-portable: if I write `(foo #|*doc*|# bar)`, I need to know, portably, whether I am documenting foo or bar. More realistically, the example: > ``` > (define (add-one x) > #|* Add one to x. *|# > (+ x 1)) > ``` is not portable if it is treated as documentation for `add-one` by some implementations but for `(+ x 1)` by others. There is a similar issue with the `documentation-format` parameter (though it doesn't seem to actually be used): the format documentation is written in is a property of the written documentation, not of the tool configuration. See [2] for a real (albeit small) problem caused by `the supplied <command> is` being parsed as plaintext in some contexts but markdown in others. [2]: https://github.com/cisco/ChezScheme/pull/816 In the other direction, I see little value in standardizing `read-documentation` or `read-documentation`, especially if they must be constrained to the lowest common denominator of R7RS Small without syntax objects. Tools seem very likely to want to use implementation-specific features, such as Chez Scheme's "annotations" [3] or Racket's syntax properties [4] and `srcloc` values [5]. Many of Scribble's features, particularly automatic cross-reference links, use the full lexical context information in Racket syntax objects, so that, if you write `(define one 1)` in a code fragment, the identifier `define` can be linked to the documentation for the applicable definition of `define`. (There are currently 32 documented definitions of `define` in the Racket package catalog.) But library writers who want to write portable documentation don't need to care what API implementers of documentation tools use to process the documentation that they've written. [3]: https://cisco.github.io/ChezScheme/csug10.0/syntax.html#./syntax:h12 [4]: https://docs.racket-lang.org/reference/stxprops.html [5]: https://docs.racket-lang.org/reference/exns.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._srcloc%29%29 I also have some concerns about the parts of the draft that do deal with writing, as opposed to processing, documentation. I am not aware of any existing documentation system that documents "expressions", and I am confused about the intent. (I also note that, in a language with macros, a `read`-based approach that doesn't perform macro expansion is really documenting source S-expressions, not "expressions": macro expansion is needed to differentiate expressions per se from definitions, binding occurrences of variables, uses of syntax pattern variables with incorrect ellipsis depth, and other non-expressions.) Most documentation systems seem to document libraries and their exports: named functions, macros, structure types, and other values. There is no portable way to "import" extensions to lexical syntax, so they don't seem to me like a good solution in this case. A "magic" comment syntax avoids some of these problems, but not all, and, if enabled by default, can cause problems for source code that didn't expect the "magic", but expected all comments to be pure comments. While this is definitely a secondary concern, "magic" comments also require tool implementers to adjust their reader, at least in some modes, to avoid discarding comments. As a "lowest common denominator", plain text (as comments or Scheme strings) definitely has a role to play in documentation. However, one of the major contributions from Scheme and the broader Lisp family of languages is rich support for creating embedded domain-specific languages. For documentation to *only* support character-based DSLs, whether in strings or "magic" comments, that must be parsed by external tools, seems to me like a weakness/restriction that ought to be removed. The docstring approach: On 5/25/24 07:35, Jakub T. Jankiewicz - jcubic at onet.pl (via srfi-discuss list) wrote: > > (define (foo x y) > "(foo x y) > > x - this is a number > y - this is a string" > (+ x x)) avoids the problems of "magic" comments, and it has the advantage of simplicity for plain text. I think a more promising route would be to allow syntactic extension. For example, a simple implementation might allow: ``` (define-syntax markdown-doc (syntax-rules () ((_ str) str))) (define (add x y) (markdown-doc "Applies `+` to its two arguments.") (+ x y)) ``` and get the equivalent of a docstring by expanding to a string literal, while a different implementation might parse the markdown at a compile time and expand to implementation-defined primitive forms for documentation literals. There are two other resources I recommend to anyone thinking about this design space. Matthew Flatt's "Submodules in Racket: You Want it When, Again?" [6] presents a perspective on documentation as a kind of orthogonal extra dimension of phase levels. R6RS and R7RS have a more restricted model of phase levels (e.g. identifiers may not have different bindings at different phase levels in the same module), but there may be some ideas that could enhance the R7RS Large approach contemplated here: On 5/25/24 07:06, Daphne Preston-Kendal wrote: > The vague plan for R7RS Large is this: > > Documentation will be attached as an identifier property (a la SRFI > 213). > This means everything can be documented – not only procedures but > macros, variables, record types and associated procedures, etc. etc. > > There is an implementation to show how simple this idea could be at > <https://codeberg.org/scheme/r7rs/wiki/Identifier-property-use-cases>. > (This is only a sketch.) [6]: https://www-old.cs.utah.edu/plt/publications/gpce13-f-color.pdf (Less directly about documentation, for someone exploring those ideas I'd also recommend Ballantyne, King, and Felleisen's "Macros for Domain-Specific Languages" [7] and some of the experimental work by the Rhombus group, e.g. binding "spaces" and "portal" syntax.) [7]: https://dl.acm.org/doi/pdf/10.1145/3428297 Eli Barzilay's @-expressions are a very powerful extension to the lexical syntax of S-expressions for working with textual content. They are most prominently used by Scribble, but they are completely general: they are just an alternative concrete syntax for S-expressions. Eli's "The Scribble Reader: An Alternative to S-expressions for Textual Content" [8] is the most focused on the design and motivation of the concrete syntax, though parts of Flatt, Barzilay, and Findler's "Scribble: Closing the Book on Ad Hoc Documentation Tools" [9] and the reference manual [10] may also be useful. As Eli writes, "Generally speaking, the Scribble reader does not require any features specific to PLT Scheme. In fact, we hope that other implementors will consider doing so, which will provide their implementations with the same benefits, as well as benefit the whole Scheme community." [8]: https://www2.ccs.neu.edu/racket/pubs/scheme2009-b.pdf [9]: https://www2.ccs.neu.edu/racket/pubs/icfp09-fbf.pdf [10]: https://docs.racket-lang.org/scribble/reader.html Hope some of this is useful! Philip McGrath