From: Thomas Walker Lynch Date: Mon, 22 Jun 2026 08:44:44 +0000 (+0000) Subject: moved code format to RT-style X-Git-Url: https://git.reasoningtechnology.com/%27%20%20%20resolved_path%20%20%20%27?a=commitdiff_plain;h=refs%2Fheads%2Fcore_developer_branch;p=Harmony moved code format to RT-style --- diff --git a/developer.tar b/developer.tar deleted file mode 100644 index b64d49e..0000000 Binary files a/developer.tar and /dev/null differ diff --git a/developer/document/RT-code-format-Lisp.html b/developer/document/RT-code-format-Lisp.html deleted file mode 100644 index 888e5fe..0000000 --- a/developer/document/RT-code-format-Lisp.html +++ /dev/null @@ -1,398 +0,0 @@ - - - - - RT Code Format: Lisp Addendum - - - - - - - - - - -

- This document serves as the authoritative addendum for applying the RT code format conventions to Lisp dialects, specifically Emacs Lisp. It integrates micro-syntax rules with macro-structural organization to ensure consistency across the software ecosystem. -

- -

File Architecture and Section Banners

-

- To maintain a predictable progression from static data to external hooks, a Lisp file is divided into standard architectural sections. Each section is introduced by an Architectural Banner. -

- - - -

Comment Ontology

-

- The commenting style in Lisp is highly structured, using semicolon counts and indentation to create a clear visual hierarchy. A programmer should assume the reader can understand Lisp syntax; avoid comments that merely translate the code below them into English prose. -

- - - -

Header case, for all RT documents and code, is an initial capital letter, and no trailing period. Acronyms and tagged code or terms keep their original capitalization or lack thereof.

- -

Identifier Naming and Namespaces

- -

Primary and Secondary Separators

-

- Because Emacs Lisp and Common Lisp support the hyphen character in identifiers, Lisp code utilizes snake-kebab_case. The hyphen acts as the primary word separator. The underscore is reserved strictly as a secondary separator to group logically related portions of an identifier or to denote semantic boundaries, acting as a structural namespace within the symbol (e.g., city-scape_building-height). -

- -

Ad Hoc Namespaces

-

- Emacs Lisp shares a global environment. To prevent global environment pollution, functions and global variables use the center dot (·) to separate namespace hierarchies. Spaces are omitted around the dot to ensure the symbol evaluates contiguously. -

- - (defconst RT·first-order-list·control·continue 0) - - -

Code Structure Attributes

-

- The code structure heavily applies the RT Code Format conventions to a Lisp environment, resulting in a distinct visual footprint. -

- -

Global Two Space Offset

-

- Unlike standard Emacs Lisp where top level forms like defun or setq are flush left, the entire programmatic contents of the file are indented by two spaces. -

- -

Function Call Enclosures

-

- Lisp function calls are exempt from the multi-level enclosure padding rule. The outer parentheses forming a function call receive no padding, even when they contain nested data lists. -

- - (cat 'a 'b '( 2 (4 5))) - - -

Vertical Branching

-

- The if and while statements are expanded vertically. The operator, the condition, the true branch, and the false branch each occupy their own isolated lines. -

- -

Isolated Binding Blocks

-

- In let and let* forms, the variable declaration list is pushed to its own level. The opening parenthesis sits alone on a new line. Each binding sits on its own line. The closing parenthesis sits alone, vertically aligned with the opening parenthesis. The body of the form follows on the subsequent line. -

- -

Using let to destructure a list

-

- Don't destructure a list and then use the parts in a single `let*`, instead destructure the list in a first list, then use the parts in a second nested `let`. -

- -

Cascading Closures

-

- When the items of a list appear one per line, i.e. for a vertical list, the closing parenthesis, and all cascading closures, appear on a line of their own at the same indention level as though an element of the list. In a sense, the innermost vertical list wins, as it will close all the vertical lists it is nested in. -

- - (let - ( - (example_list - (list - '(4 [0]) - '(5 [1]) - '(6 []) - ))) - ... - - - -

A comment subsection

-

- When a comment under a triple semicolon section forms a subsection, the - comment starts at the indention level of the code, has two semicolons. After the comment there is a line at the indent level with only two semicolons. Then there is a blank line. The subsection contents follow. -

- - ;; Color logic - ;; - - (defun RT-literal·highlight-none () - nil - ) - - (defun RT-literal·highlight-default () - 'region - ) - - -

one line specific comment

-

- A single semicolon occurs after the code on the line, followed by a comment. -

- - - - - -

Contiguous Form Cluster

-

- When the comment adds insight into the code, the comment typically appears with two semicolons at the same indentation level above said code. There is no following blank line. All code the comment applies to then follows without intervening blank lines. -

- - ;; By contract: only called when overlay is in quoted form, and null string case already handled - ;; Everything from content_leftmost to content_rightmost is data, inclusive. - (setq RT-literal·describe-new-form_status (list 'new-good)) - (defun RT-literal·describe-new-form_message (status) - nil - ) - (defun RT-literal·describe-new-form (overlay_leftmost content_rightmost_right-neighbor) - (let* - ( ... ) - ... - ))) - - -

API Design Conventions

- -

Parameter Ordering

-

- When defining function signatures, static configuration parameters (such as sizes, limits, or modes) must precede data payloads or instances that are actively manipulated. This facilitates partial application and logical readability. -

- -

TTCA Theory Terminology

-

- The following definitions bridge the gap between abstract TTCA theory and practical implementation conventions. -

- - - -

- The TTCA ontology is a topological description. It speaks of left, and right, of leftmost and rightmost. Time dependent terms such as first or last imply scanning/traversal. The first cell scanned could be anywhere on the tape, depending on the algorithm used for the scan or traversal. Careful, the term rightmost refers to a cell that is included on the tape. It is an inclusive bound. Today exclusive bounds are more common. Inclusive found loops often exit from the middle. -

- - -

The First/Rest Loop Technique

- -

The first/rest loop is an iterative control flow pattern designed for sequence traversal and state machine evaluation. The pattern explicitly separates the evaluation of the initial state (the "first") from the continuous cycle of advancing and re-evaluating (the "rest").

- -

This technique eliminates the need for mid-loop escape clauses, such as break or throw/catch, and avoids evaluating out-of-bounds memory by ensuring the tape head is always validated before stepping.

- -

The Structural Form

- -

The structure requires performing the initial work on the first valid cell and evaluating the boundary condition simultaneously. Because a freshly cued tape machine always rests on valid data, the first cell is processed immediately within the initial variable bindings. The loop condition then evaluates both the result of that work and whether the machine has a right neighbor. Inside the loop, the machine steps, and both the work and boundary conditions are explicitly re-evaluated and updated at the absolute bottom.

- -

If the work performed on the cell is extensive, a programmer should extract that logic into a helper function. This helper function is called once in the initial bindings for the "first" phase, and once inside the loop for the "rest" phase.

- -

Here is the canonical RT code format for the first/rest loop:

- - - (let - ( - ;; 1. The "First" Work & Boundary Evaluation - (work-successful (evaluate-current-cell machine)) - (has_right-neighbor (RT·TM·has-right-neighbor machine)) - ) - ;; 2. The rest loop - (while (and work-successful has_right-neighbor) - (progn - ;; 3. The "Step" phase - (RT·TM·step machine) - - ;; 4. The "Rest" Work & Boundary Evaluation - (setq work-successful (evaluate-current-cell machine)) - (setq has_right-neighbor (RT·TM·has-right-neighbor machine)) - )) - ;; Return the final state of the work - work-successful - ) - - -

- Elisp does not have a middle-of-loop exit, but if it did, the logic would look like this: -

- - - (let - ( - (work-successful nil) - (has_right-neighbor nil) - ) - (loop - (setq work-successful (evaluate-current-cell machine)) - (setq has_right-neighbor (RT·TM·has-right-neighbor machine)) - - (if - (not (and work-successful has_right-neighbor)) - (break) - (RT·TM·step machine) - )) - work-successful - ) - - -

Which eliminates the need for two calls to evaluate-current-cell and has-right-neighbor. This can be done in other languages that have a loop break. (Donald Knuth argued in his 1974 paper, Structured Programming with go to Statements, that forcing programmers to duplicate code simply to satisfy a rigid while or repeat/until pre/post-test constraint was a failure of the language's expressiveness. Also discussed in the Art of Computer Programming.) -

- -

If we are willing to us catch and throw in normal control flow, this can be done in elisp as: -

- - - (catch 'loop-exit - (while t - (let - ( - (work-successful (evaluate-current-cell machine)) - (has_right-neighbor (RT·TM·has-right-neighbor machine)) - ) - (if - (not (and work-successful has_right-neighbor)) - (throw 'loop-exit work-successful) - (RT·TM·step machine) - )))) - - -

So defining:

- - (defmacro RT·loop (&rest body) - "An infinite loop construct designed to be exited via RT·break." - `(catch 'loop-exit - (while t - ,@body - ))) - - (defmacro RT·break (&optional return_val) - "Break out of an RT·loop, optionally returning RETURN_VAL." - `(throw 'loop-exit ,return_val) - ) - - -

Our example becomes:

- - - (let - ( - (work-successful nil) - (has_right-neighbor nil) - ) - (RT·loop - ;; 1. The Work & Boundary Evaluation - (setq work-successful (evaluate-current-cell machine)) - (setq has_right-neighbor (RT·TM·has-right-neighbor machine)) - - ;; 2. The Mid-Loop Condition Check - (if - (not (and work-successful has_right-neighbor)) - (RT·break work-successful) - ;; 3. The "Step" phase - (RT·TM·step machine) - )) - ) - - -

- Production code first/rest loop example without a middle loop break. -

- - - (defun RT·TM·sequence·eq (TM_substrate TM_target) - (let - ( - (TM-substrate-copy (RT·TM·entangled-copy TM_substrate)) - (TM-target-copy (RT·TM·entangled-copy TM_target)) - ) - (let - ( - (are-eq (= (RT·TM·read TM-substrate-copy) (RT·TM·read TM-target-copy))) - (target-has-right-neighbor (RT·TM·has-right-neighbor TM-target-copy)) - (substrate-has-right-neighbor (RT·TM·has-right-neighbor TM-substrate-copy)) - ) - (while - (and are-eq target-has-right-neighbor substrate-has-right-neighbor) - (progn - (RT·TM·step TM-substrate-copy) - (RT·TM·step TM-target-copy) - (setq are-eq (= (RT·TM·read TM-substrate-copy) (RT·TM·read TM-target-copy))) - (setq target-has-right-neighbor (RT·TM·has-right-neighbor TM-target-copy)) - (setq substrate-has-right-neighbor (RT·TM·has-right-neighbor TM-substrate-copy)) - )) - (and are-eq (not target-has-right-neighbor)) - ))) - - -

If the double call code is substantial, and we do not want to use a middle break, it can be put in a helper function, and then this reduces to two calls to the helper. the helper function is called in the first part and the rest loop. If the programmer tries to trick the loop by giving the variables fake values in the first part, the first/rest pattern will be broken. -

- -

Relationship between first/rest and Tail Recursion

- -

The first/rest loop is the exact iterative equivalent of a tail-recursive function.

- -

In a functional paradigm, a sequence is algebraically defined as a head (first) and a tail (rest). A tail-recursive function evaluates the head, performs the necessary work, and then returns the result of calling itself on the tail.

- -

Environments lacking Tail Call Optimization (TCO), such as Emacs Lisp, will throw a stack overflow error if a recursive function traverses a long sequence. The first/rest loop flattens this recursive mathematical model into memory-safe iteration by mapping the recursive phases directly to iterative steps:

- -

The Initial Function Call: The initial work and the let block bindings in the first/rest loop mirror the initial execution and argument evaluation of the recursive function.

- -

The Base Case Check: The while loop condition mirrors the recursive base case. If the condition fails, the loop terminates, mimicking the recursive function returning its final value.

- -

The Tail Call: The step and setq updates at the bottom of the loop body mirror the argument passing of the tail-recursive call. Updating the variables and allowing the while loop to jump back to the top is functionally identical to the function invoking itself with a new set of parameters for the "rest" of the sequence.

- -

By adhering to this pattern, a programmer retains the strict, predictable state management of functional recursion while satisfying the physical memory constraints of an iterative runtime environment.

- -

To illustrate the mathematical equivalence, here is the exact same logic written as a tail-recursive function. Note that while this form is theoretically pure, the first/rest iterative loop is strictly preferred in Emacs Lisp. Because Elisp lacks Tail Call Optimization (TCO), this recursive form would eventually exhaust the call stack and crash when traversing massive sequences.

- - - (defun process-sequence-recursively (machine) - (let - ( - ;; 1. The "First" Work & Boundary Evaluation - (work-successful (evaluate-current-cell machine)) - (active (RT·TM·has-right-neighbor machine)) - ) - ;; 2. The Condition check - (if (and work-successful active) - (progn - ;; 3. The "Step" phase - (RT·TM·step machine) - - ;; 4. The Tail Call (The "Rest") - ;; This directly replaces the setq updates and loop jump - (process-sequence-recursively machine) - ) - ;; Base case: loop terminates, return final state - work-successful - ))) - - -

Exercise

-

Show the 'production code' with a first/rest pattern using the RT macros and a middle break loop.

- -
- - diff --git a/developer/document/RT-code-format.html b/developer/document/RT-code-format.html deleted file mode 100644 index e4924fa..0000000 --- a/developer/document/RT-code-format.html +++ /dev/null @@ -1,287 +0,0 @@ - - - - - RT code format conventions - - - - - - - - - - -

- This document has been evolving. Consequently there is a body of non-conforming code. Whenever we run up against it, it is nice to update it. -

- -

Object vs. instance nomenclature

-

- It is too much of an ask to remove the word 'object' from the English language, and then set it aside and give it a esoteric technical meaning. This is why the term is often misused. So we instead talk about an interface as being a set of functions that share one or more state variables. The term instance is then a collection of such state variables and their values sitting in memory. Interface functions are usually grouped within a named container, and state variables are often grouped into a single named data structure. -

-

- In some languages the instance occurs to the left of a lower dot (period) operator and is referred to as this from inside the interface functions. In other languages there is a convention where the instance is passed in as the first parameter to interface functions. There can also be interface functions that accept multiple instances of the same type. Bridge interfaces can be created that accept two instances potentially of different types. -

-

- Since we have released object from captivity, a programmer can talk about math objects, as things found in mathematics, and C objects, as things found in the C language, even though they are not instantiated from classes, or might not even be data. For example, the for loop is a C object. -

- -

Identifier names

- -

Case

- - -

Proper nouns and acronyms

-

- Even in PascalCase and snake-kebab_case, proper nouns and acronyms remain capitalized, as per standard English language conventions (e.g., IEEE_publication-count). -

- -

Abbreviations

-

- For outer scope identifiers we spell things out for clarity. This follows Lisp programming culture. This makes it clear for people who are 'not in the club' to be able to get started and read the code, and tends to be self documenting. Our file system names mirror our program identifier rules, so you find things such as 'library', 'source', spelled out. -

-

- For long words, inner scope identifiers, temporary variables, and conventional suffixes, abbreviations become more common. By the time we get to inner loops variable names, such as loop counters are typically 1 letter long. -

- -

Primary and secondary separator use

-

- When a language supports the dash, -, dash connected components are given precedence and of choice, and bind semantically higher than under score separated components. E.g. rounded_x-coordinate. -

-

- Otherwise, if the language does not support hyphens in identifiers (such as C, Python, and Java), we conventionally drop the nicety of multiple semantic bindings, e.g. rounded_x_coordinate. However if the distinction has high value, a double underscore and be used, rounded__x_coordinate. -

- -

Ad hoc namespacing

-

- Most parsers now a allow a center dot (·) in identifiers. In languages were namespaces are not explicitly available, we use the cdot to represent a namespace. Namespaces are closely related to module names, class names, interface names, and to type names,so all are written in PascalCase. So for example, Math·rounded__x_coordinate, might be variable in the Math namespace, a function on the Math interface, etc. - -

Component order

-

- As long as it is sensible, and doesn't break parallel constructions, place the least changing component, or the broadest category, to the left of the identifer. For example, a conditional write functions would be called, `write-conditional`, not `conditional-write` because it is a refinement on the general category or write functions. -

- -

Copy,read, write

-

- 'read' and 'write', are the two ends of a copy. When 'this instance' is understood as being one end of the copy, then using 'read' or 'write' makes sense. However, it is generally better to provide an external copy command. The order of arguments in a copy command are `read from source value --> write to destination value` i.e. data flows from left to write. (This is contrary to an assignment operator, which has data flowing from right to left during a copy.) -

- -

The term make

-

- When allowed by the langauge, factory functions are called 'make'. They are not called 'create', nor 'new'. -

- -

Function terminology

-

- Parameters are what give a function its characteristics. They are typically static. They are one step away from values that are curried into a function. Parameter variables are given with the function definition, and parameter values are given to the function at run time when it is called. -

-

- Given argument values can be said to be bound to arguments variables upon call. -

-

- Arguments drive the function computation. Conceptually they might change on every separate call, so they are highly dynamic. Argument variables are specified when the function is defined. Argument values are given to the function at call time. -

-

- Values are said to be given to a function. We don't say a function takes arguments, as though a call stack could reach into memory and grab values. We use terms accept and reject of values for guard code. For a function to accept an argument value is to mean that argument value was tested and passed. As an example, we can say that a square root function only accepts values greater than or equal to zero, or that it rejects negative values. -

-

- Operators are logically functions by another name. Syntactically infix notation is often used. Operands are arguments given to an operator. -

- -

Plural identifiers

- -

- Do not make the names of containers plural, instead prefix the container abstract type, or actual type before the identifier. Recall that types are PascalCase. -

- - - -

Add a type prefix when it adds clarity.

- - -

Identifiers for directory/file names

- - -

Comma separated lists

- -

Horizontal comma list

-

The comma is preceded by a space and abuts the item it follows.

- - int x ,y ,z; - - -

Vertical comma list

-

The comma is placed before the item on the new line, aligned with the item's indentation. This applies to all languages, including Python and C.

- - result = some_function( - first_argument - ,second_argument - ,third_argument - ); - - -

Enclosure spacing

- -

Single-level enclosures

-

No space padding inside the enclosure punctuation.

- - if(condition){ - do_something(); - } - - -

Multi-level enclosures

-

One space of padding is applied only to the outermost enclosure punctuation.

- - - if( f(g(x)) ){ - do_something(); - } - - -

This rule is not applied to function calls in Lisp. For example, the outer parentheses forming a function call receive no padding, even when they contain nested data lists:

- - - (cat 'a 'b '( 2 (4 5))) - - -

Indentation

- -

Python enforces indentation syntactically. Use two-space indentation for all Python code, even though four is common in the wider ecosystem.

- -

The CLI vs. work function pattern

-

- To avoid the "String Trap" (where logic is tightly coupled to the terminal and requires string serialization to reuse) executable modules must separate the Command Line Interface from the core logic. -

- - -

Python application

-

Put argument parsing and if __name__ == "__main__": in the CLI section. Keep side effects out of import time.

- -

Bash application

-

Bash scripts should start with #!/usr/bin/env bash and set -euo pipefail. RT-style Bash separates a small top-level CLI harness from a set of functions that implement the work. Parse arguments into variables, call a main function with explicit parameters, and avoid relying on global mutable state where possible.

- -

C addendum: error handling and ownership

- - -

Automated formatting tools

-

- To ensure consistency without manual drudgery, the Harmony skeleton provides a dedicated code formatter called RTfmt. A person can find this tool in the shared/tool/ directory. -

- -

The RTfmt CLI

-

- RTfmt is a shallow-tokenizing formatter written in Python. It parses source code into structural blocks (strings, comments, commas, and enclosures) without needing a full Abstract Syntax Tree. This architecture allows it to safely enforce RT formatting rules across multiple languages while preserving indentation and protecting native operators. -

- - -

Emacs integration

-

- For Emacs users, the RT-formatter.el file provides the RT-formatter-buffer interactive command. -

-

- This wrapper passes the current buffer through the RT-formatter pipe command. It automatically detects Lisp-derived modes to append the --lisp flag. Furthermore, it utilizes a non-destructive buffer replacement strategy. This ensures that a programmer's cursor position, selection marks, and window scroll state remain anchored exactly where they were before the formatting occurred. -

- -

Exercises

-

Exercise 1: Comma and function call formatting

-

Reformat the following C code snippet to strictly adhere to the RT code format rules.

- - void my_function(int a, int b, int c) { - int result = calculate_value(a, b, c); - printf("Result: %d, a: %d, b: %d, c: %d\n", result, a, b, c); - } - - -

Exercise 2: Multi-level enclosure and short stuff rule

-

Reformat the following C code snippet to use the multi-level enclosure rule and the short stuff rule.

- - if (check_permissions(user_id, file_path) && is_valid(file_path)) { - for (int i = 0; i < 10; i++) { - if (i % 2 == 0) { - printf("Even: %d\n", i); - } - } - } - - -

Exercise 3: Identifier Naming Conventions

-

- Rename the following poorly named variables to strictly adhere to the RT code format rules. Assume these are variables in a C or Python program (using standard snake_case). Pay close attention to proper nouns, acronyms, and the expanded suffix semantics. -

- - -

Exercise 4: Identifier naming with hyphens

-

- Rename the same poorly named variables from Exercise 3, but this time assume they are written in a language that supports the hyphen (-) in identifiers. Apply the rules for primary and secondary separators, keeping in mind the structural boundary of suffixes. -

- - -
- - diff --git a/setup b/setup index 7603f3e..a249e2e 100644 --- a/setup +++ b/setup @@ -44,8 +44,10 @@ fi # setup the role # export ROLE="${1}" + export ROLE_HOME="$REPO_HOME/$ROLE" + echo ROLE_HOME "$ROLE_HOME" - tool="${REPO_HOME}/${ROLE}/tool" + tool="${ROLE_HOME}/tool" if [[ ":${PATH}:" != *":${tool}:"* ]]; then export PATH="${tool}:${PATH}" fi diff --git a/shared/linked-project/RT-style-JS_public b/shared/linked-project/RT-style-JS_public deleted file mode 120000 index 9600bc6..0000000 --- a/shared/linked-project/RT-style-JS_public +++ /dev/null @@ -1 +0,0 @@ -../../../RT-style-JS_public/ \ No newline at end of file diff --git a/shared/tool/setup b/shared/tool/setup index 6cfc738..76983e7 100644 --- a/shared/tool/setup +++ b/shared/tool/setup @@ -77,41 +77,6 @@ umask 0077 export PATH -#-------------------------------------------------------------------------------- -# used by release scripts -# - install_file() { - if [ "$#" -lt 3 ]; then - echo "env::install_file usage: install_file ... " - return 1 - fi - - perms="${@: -1}" # Last argument is permissions - target_dp="${@: -2:1}" # Second-to-last argument is the target directory - sources=("${@:1:$#-2}") # All other arguments are source files - - if [ ! -d "$target_dp" ]; then - echo "env::install_file no install done: target directory '$target_dp' does not exist." - return 1 - fi - - for source_fp in "${sources[@]}"; do - if [ ! -f "$source_fp" ]; then - echo "env::install_file: source file '$source_fp' does not exist." - return 1 - fi - - target_file="$target_dp/$(basename "$source_fp")" - - if ! install -m "$perms" "$source_fp" "$target_file"; then - echo "env::install_file: Failed to install $(basename "$source_fp") to $target_dp" - return 1 - fi - done - } - - export -f install_file - # -------------------------------------------------------------------------------- # closing #