. Improving RetroForth Comprehensibility with `retro-document`

Rick Carlino

Personal blog of Rick Carlino, senior software engineer at Qualia Labs, co-founder of Fox.Build Makerspace. Former co-founder of FarmBot.

Improving RetroForth Comprehensibility with `retro-document`

Intended Audience: Software developers with a novice-level understanding of Forth.

Goal: Understand what retro-document is and why it is an integral part of the RetroForth ecosystem.

RetroForth Glossaries

When I first learned RetroForth I encountered a situation familiar to many language learners. Although I read the documentation and understood the syntax, I still did not know the commonly used built-in words and patterns of the language.

The RetroForth website provides many examples of using the language. Reading other people’s source code is a great way to learn a new language and RetroForth is no different. Reading a real-world example exposes you to new patterns and also shows you how the standard library is used in an applied context. When you read other people’s example code, you will start seeing patterns emerge. You will also see which parts of the standard library are used most.

Seeing other people’s usage of unknown standard library code can be a learning opportunity. Still, it comes with a challenge: you need to flip between the codebase and the standard library documentation. Flipping between two documents can slow the learning process.

Around this point, I noticed that each example provided on the RetroForth website also linked to a “glossary”. To show what I mean, we can view the Conway’s Game of Life example. It references a glossary found here.

The glossary provides a listing of every standard library call used in the source code. By reading the glossary before reading the implementation code, you can mentally prepare yourself to study the code. All references to standard library words will be covered ahead of time, reducing the need to reference standard library documentation. The glossary acts as a sort of “study guide”. The glossary is a distilled version of the full RetroForth documentation containing only the documentation needed to understand the application at hand.

Using Glossaries in Custom Applications

The official documentation examples are not the only place you will find glossaries. RetroForth authors can create glossaries for any application, including their own. A standard installation of Retro contains retro-document, a tool that generates glossaries from arbitrary source files.

Given a hello.forth file:

'Hello,_world! s:put nl

We can generate the following glossary via retro-document hello.forth:


  Data:  -
  Addr:  -
  Float: -

Display a newline.

Class: class:word | Namespace: global | Interface Layer: all


  Data:  s-
  Addr:  -
  Float: -

Display a string.

Class: class:word | Namespace: global | Interface Layer: all

---Remainder of file redacted for clarity---

As you can see, retro-describe detected the two standard library calls to s:put and nl and added them to the glossary. On less trivial projects, the glossary will be larger in size.

RetroForth’s Documentation-First Approach

Forth’s strong point is its adaptability to the author’s needs. Forth code can be molded in any way and provides very few “guard rails”. Unfortunately, this has led some to classify Forth as a “Write-Only Language” since it is easy for authors to create a system that they alone understand. Authors must make a constant effort to maintain readability since the language will not get in the way of authors that choose poor practices.

retro-document is a helpful tool for comprehensibility, and it is only one of many practices that make RetroForth a very readable flavor of Forth.

Some other tools and practices that have made my RetroForth learning experience easier than others include:

  • retro-unu: A tool that is used by the Retro compiler internally. It allows authors to write application code within a Markdown document. Retro can directly compile the Markdown file. Having literate source files means that RetroForth code lives inside of its documentation. The documentation and application code are always located in the same file.
  • Tests often serve as a form of documentation for developers that must modify pre-existing code. RetroForth supports first-class testing within Markdown documentation. Regular code is fenced within tilde (~) delimiters, whereas test code is held inside backtick delimited fences (). Tests a runnable by passing a-t` flag at start time. If an application has unit tests, it will live alongside the source code and documentation.
  • retro-tags / retro-locate: As mentioned previously, spending time searching documentation for a specific entry can be time consuming. Retro ships with a tool called retro-tags that can generate a ctag that indexes the location(s) of definitions in the current directory. You can then use retro-locate to search the tag index for the location of the word. Since RetroForth has first-class documentation, the documentation is almost always located directly above a word’s definition.
  • retro-describe: retro-describe allows authors to search for documentation of the standard library. For example, you can see the documentation entry of s:put by typing retro-describe s:put, which can be more convenient than grepping through the official docs. This is useful when writing new code that does not yet have a glossary entry.

Looking Ahead

Because RetroForth accepts user input on a per-token basis (whitespace delimited words) rather than the more traditional “input stream” seen in other Forths, it is easier to create tools like retro-document and retro-describe. I would also argue that it makes the source more readable by project outsiders (though not everyone agrees).

Some tools I would hope to build or see in future versions of Retro:

  • Better integration with VSCode
    • Hoverable documentation
    • jump-to-definition (UPDATE: This is already possible but you will need to rename your retro-tags file to .tags)
    • syntax highlighting
  • Test coverage reporters
  • Interactive debug shells (currently using one privately; may release later)
  • Automated formatters and linters