[DRAFT] GNURES, a "modern" stropping regime for Algol 68
Jose E. Marchesi
jemarch@gnu.org
Sun Apr 20 12:27:11 GMT 2025
GNURES, a "modern" stropping regime for Algol 68
************************************************
GNU68-2025-004 (draft)
Copyright © 2025 Jose E. Marchesi.
You can redistribute and/or modify this document under the terms of
the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option)
any later version.
The following specification has been released under the auspices of the
GNU Algol 68 Working Group, and has been scrutinized to ensure that
a. it is strictly upwards-compatible with Algol 68,
b. it is consistent with the philosophy and orthogonal framework of
the language, and
c. it fills a clearly discernible gap in the expressive power of that
language.
The source of this document can be found at
<https://git.sr.ht/~jemarch/gnu68>.
The informal description of this proposal introduces the proposed new
language features, providing a rationale and usage examples.
The formal definition of this proposal uses the existing formalism and
conventions of the Standard Hardware Representation for Algol 68, and it
is expressed as modifications to the Standard Hardware Representation.
Finally, the implementation notes of this proposal describes a way in
which the features added by this specification can be implemented. No
implementer should feel committed to do things as described there; the
same language facilities may well be implementable in other ways, more
suitable to specific implementations.
1 Informal Description
**********************
Stropping
=========
The Algol 68 algorithmic language establishes that certain source
constructs, namely mode indications and operator indications, consist in
a sequence of “bold letters” and “bold digits”, known as a “bold word”.
In contrast, other constructs like identifiers, field selectors and
labels are composed of regular or non-bold letters and digits, known as
a “tag”.
What is precisely a bold letter or digit, and how it differs from a
non-bold letter or digit, is not specified by the Report. This is no
negligence, but a conscious effort at abstracting the definition of the
so-called “strict language” from its representation. This allows
different representations of the same language.
Some representations of Algol 68 are intended to be published in books,
be it paper or electronic devices, and be consumed by persons. These
are called “publication languages”. In publication languages bold
letters and digits are typically represented by actual bold alphanumeric
typographic marks, or sometimes underlined alphanumeric marks.
Other representations of Algol 68 are intended to be automatically
processed by a computer. These representations are called “hardware
languages”. Sometimes the hardware languages are also intended to be
written and read by programmers; these are called “programming
languages”.
Unfortunately, computer systems today usually do not yet provide readily
usable and ergonomic bold or underline alphanumeric marks, despite the
existence of Unicode and modern and sophisticated editing environments.
The lack of appropriate input methods surely plays a role on this.
Thus, the programming representation languages of Algol 68 should resort
to a technique known as “stropping” in order to differentiate bold
letters and digits from non-bold letters and digits. The set of rules
specifying the representation of these characters is called a “stropping
regime”.
There are three classical stropping regimes for Algol 68, which are
standardized and specified in the Standard Hardware Representation
normative document. These are “POINT stropping”, “RES stropping” and
“UPPER stropping”. The following sections do a cursory tour over them;
for more details the reader is referred to the Standard Hardware
Representation.
POINT stropping
===============
POINT stropping is in a way the most fundamental of the three standard
regimes. It was designed to work in installations with limited
character sets that provide only one alphabet, one set of digits, and a
very restricted set of other symbols.
In POINT stropping a bold word is represented by its constituent letters
and digits preceded by a point character. For example, the symbol ‘bold
begin symbol’ in the strict language, which is represented as *begin* in
bold face in the reference language, would be represented as ‘.BEGIN’ in
POINT stropping.
More examples are summarized in the following table.
Strict language Reference language POINT stropping
---------------------------------------------------------------------------
‘true symbol’ *true* ‘.TRUE’
‘false symbol’ *false* ‘.FALSE’
‘integral symbol’ *int* ‘.INT’
‘completion symbol’ *exit* ‘.EXIT’
‘bold-letter-c-...’ *crc32* ‘.CRC32’
In POINT stropping a tag is represented by writing its constituent
non-bold letters and digits in order. But they are organized in several
“taggles”.
Each taggle is a sequence of one or more letters and digits, optionally
followed by an underscore character. For example, the tag ‘PRINT’ is
composed of a single taggle, but the tag ‘PRINT_TABLE’ is composed of a
first taggle ‘PRINT_’ followed by a second taggle ‘TABLE’.
To improve readability it is possible to insert zero or more white space
characters between the taggles in a tag. Therefore, the tag
‘PRINT_TABLE’ could have been written ‘PRINT TABLE’, or even ‘PRINT_
TABLE’. This is the reason why Algol 68 identifiers, labels and field
selectors can and do usually feature white spaces in them.
It is important to note that both the trailing underscore characters in
taggles and the white spaces in a tag do not contribute anything to the
denoted tag: these are just stropping artifacts aimed to improve
readability. Therefore ‘FOOBAR’ ‘FOO BAR’, ‘FOO_BAR’ and ‘FOO_BAR_’ are
all representations of the same tag, that represents the
‘letter-f-letter-o-letter-o-letter-b-letter-a-letter-r’ language
construct.
Below is the text of an example Algol 68 procedure encoded in POINT
stropping.
.PROC RECSEL OUTPUT RECORDS = .VOID:
.BEGIN .BITS FLAGS
:= (INCLUDE DESCRIPTORS | REC F DESCRIPTOR | REC F NONE);
.RECRSET RES = REC DB QUERY (DB, RECUTL TYPE,
RECUTL QUICK, FLAGS);
.RECWRITER WRITER := REC WRITER FILE NEW (STDOUT);
SKIP COMMENTS .OF WRITER := .TRUE;
.IF RECUTL PRINT SEXPS
.THEN MODE .OF WRITER := REC WRITER SEXP .FI;
REC WRITE (WRITER, RES)
.END
RES stropping
=============
The early installations where Algol 68 ran not only featured a very
restricted character set, but also suffered from limited storage and
complex to use and time consuming input methods such as card punchers
and readers. It was important for the representation of programs to be
as compact as possible.
It is likely that is what motivated the introduction of the RES
stropping regime. As its name implies, it removes the need of stropping
many bold words by introducing “reserved words”.
A “reserved word” is one of the bold words specified in the section
9.4.1 of the Report as a representation of some symbol. Examples are
*at*, *begin*, *if*, *int* and *real*.
RES stropping encodes bold words and tags like POINT stropping, but if a
bold word is a reserved word then it can then be written without a
preceding point, achieving this way a more compact, and easier to read,
representation for programs.
Introducing reserved words has the obvious disadvantage that some tags
cannot be written the obvious way due to the possibility of conflicts.
For example, to represent a tag ‘if’ it is not possible to just write
‘IF’, because it conflicts with a reserved word, but this can be
overcome easily (if not elegantly) by writing ‘IF_’ instead.
Below is the ‘recsel output records’ procedure again, this time encoded
in RES stropping.
PROC RECSEL OUTPUT RECORDS = VOID:
BEGIN BITS FLAGS
:= (INCLUDE DESCRIPTORS | REC F DESCRIPTOR | REC F NONE);
.RECRSET RES = REC DB QUERY (DB, RECUTL TYPE,
RECUTL QUICK, FLAGS);
.RECWRITER WRITER := REC WRITER FILE NEW (STDOUT);
SKIP COMMENTS OF WRITER := TRUE;
IF RECUTL PRINT SEXPS
THEN MODE .OF WRITER := REC WRITER SEXP FI;
REC WRITE (WRITER, RES)
END
Note how user-defined mode an operator indications still require
explicit stropping.
UPPER stropping
===============
In time computers added support for more than one alphabet by
introducing character sets with both upper and lower case letters, along
with convenient ways to both input and display these.
In UPPER stropping the bold letters in bold word are represented by
upper-case letters, whereas the letters in tags are represented by
lower-case letters.
The notions of upper- and lower-case are not applicable to digits, but
since the language syntax assures that it is not possible to have a bold
word that starts with a digit, digits are considered to be bold if they
follow a bold letter or another bold digit.
Below is the ‘recsel output records’ procedure again, this time encoded
in UPPER stropping.
PROC recsel output records = VOID:
BEGIN BITS flags
:= (include descriptors | rec f descriptor | rec f none);
RECRSET res = rec db query (db, recutl type,
recutl quick, flags);
RECWRITER writer := rec writer file new (stdout);
skip comments of writer := TRUE;
IF recutl print sexps
THEN mode OF writer := rec writer sexp FI;
rec write (writer, res)
END
Note how in this regime it is almost never necessary to introduce bold
tags with points. All in all, it looks much more natural to
contemporary readers. UPPER stropping is in fact the stropping regime
of choice today. It is difficult to think of any reason why anyone
would resort to use POINT or RES stropping.
Bold taggles
============
In all three classical stropping regimes it is not possible to write
white space characters between the constituent letters and digits of a
bold word. It is very common, however, for user-defined mode and
operator indicators to contain several natural words, such as in
‘TREENODE’ or ‘RECWRITER’. This can be a little difficult to read.
The GNU extension GNU68-2025-002, "Bold taggles in Algol 68", adds
support in all the standard stropping regimes to use underscores in bold
words. This is done by redefining bold words to be based on taggles,
much like tags.
With this extension, the above mode indications could have been written
like ‘TREE_NODE’ an ‘REC_WRITER’, improving readability.
The ‘recsel output records’ procedure, encoded in UPPER stropping and
using bold taggles, now looks like:
PROC recsel output records = VOID:
BEGIN BITS flags
:= (include descriptors | rec f descriptor | rec f none);
REC_RSET res = rec db query (db, recutl type,
recutl quick, flags);
REC_WRITER writer := rec writer file new (stdout);
skip comments of writer := TRUE;
IF recutl print sexps
THEN mode OF writer := rec writer sexp FI;
rec write (writer, res)
END
GNURES stropping
================
This proposal describes a new stropping regime that combines the
advantages of the RES and the UPPER regimes. The resulting form of
programs aims to be both more appealing to contemporary programmers and
also more convenient to be used in today's computing systems.
The RES stropping regime made it possible to avoid explicit stropping of
a big subset of all the bold words, namely the ones pertaining to the
fixed set of "reserved words". However, both user-defined mode
indications and operator indications still had to be stropped
explicitly, prefixing them with a dot character.
The UPPER stropping regime, cleverly exploiting dual-alphabet
installations, implemented the explicit stropping by having bold words
encoded using upper-case letters and tags encoded using lower-case
letters.
Combining and adapting both approaches we can obtain a stropping regime
in which explicit stropping is reduced to the minimum necessary, i.e.
user-defined mode and operator indications, and in which explicit
stropping is done in a way that looks more familiar to today's
programmers and less heavy on upper-case letters than in UPPER
stropping.
In the GNURES stropping regime bold words are written by writing a
sequence of one or more “taggles”. Each taggle is written by writing a
letter followed by zero or more other letters and digits and is
optionally followed by a trailing underscore character. The first
letter in a bold word shall be an upper-case letter. The rest of the
letters in the bold word may be either upper- or lower-case.
For example, ‘RecRset’, ‘Rec_Rset’ and ‘RECRset’ are all different ways
to represent the same mode indication. This allows to recreate popular
naming conventions such as ‘CamelCase’.
As in the other stropping regimes, the casing of the letters and the
underscore characters are not really part of the mode or operator
indication.
Operator indications are also bold words and are written in exactly the
same way than mode indications, but it is usually better to always use
upper-case letters in operator indications. On one side, it looks
better, especially in the case of dyadic operators where the asymmetry
of, for example ‘Equal’ would look odd, consider ‘m1 Equal m2’ as
opposed to ‘m1 EQUAL m2’. On the other side, tools like editors can
make use of this convention in order to highlight operator indications
differently than mode indications.
In the GNURES stropping regime tags are written by writing a sequence of
one or more “taggles”. Each taggle is written by writing a letter
followed by zero or more other letters and digits and is optionally
followed by a trailing underscore character. All letters in a tag shall
be lower-case letters.
For example, the identifier ‘list’ is represented by a single taggle,
and it is composed by the letters ‘l’, ‘i’, ‘s’ and ‘t’, in order. In
the jargon of the strict language we would spell the tag as
‘letter-l-letter-i-letter-s-letter-t’.
The label ‘found_zero’ is represented by two taggles, ‘found_’ and
‘zero’, and it is composed by the letters ‘f’, ‘o’, ‘u’, ‘n’, ‘d’, ‘z’,
‘e’, ‘r’ and ‘o’, in order. In the jargon of the strict language we
would spell the tag as ‘letter-f-letter-o-letter-u-letter-n
-letter-d-letter-z-letter-e-letter-r-letter-o’.
The identifier ‘crc_32’ is likewise represented by two taggles, ‘crc_’
and ‘32’. Note how the second taggle contains only digits. In the
jargon of the strict language we would spell the tag as
‘letter-c-letter-r-letter-c-digit-three-digit-two’.
The underscore characters are not really part of the tag, but part of
the stropping. For example, both ‘goto found_zero’ and ‘goto foundzero’
jump to the same label.
The ‘recsel output records’ procedure, encoded in GNURES stropping,
looks like below.
proc recsel_output_records = void:
begin bits flags
:= (include_descriptors | rec_f_descriptor | rec_f_none);
RecRset res = rec_db_query (db, recutl_type,
recutl_uick, flags);
RecWriter writer := rec_writer_file_new (stdout);
skip_comments of writer := true;
if recutl_print_sexps
then mode_ of writer := rec_writer_sexp fi;
rec_write (writer, res)
end
No white spaces in identifiers
==============================
GNURES is the only Algol 68 stropping regime that doesn't allow having
typographical display features (spaces, tabs and newline characters)
between the taggles conforming a tag. In other words, it is not allowed
to have white spaces as part of identifiers.
This is a shame, but there are two main reasons why it was decided to
proceed like this.
First and most importantly, the GNURES stropping regime is based on
reserved words, which are mapped from the representation specified for
the symbols of the language that are represented by bold words in the
reference language.
The reference language of Algol 68 was designed before the Standard
Hardware Representation introduced the RES stropping regime. Likely
this is the reason why it specifies so many and so short symbols: the
authors assumed that tags would always live in a different name space
than bold words.
With reserved words like ‘to’ and ‘in’, it becomes very difficult to
separate identifier taggles with white spaces without bumping into
conflicts. Consider for example the not at all unlikely procedure name
‘checked real to int’. This identifier would be not legal, because the
three last taggles conflict with the the standard mode ‘real’, the
syntactic bold words ‘to’ and the standard mode ‘int’, respectively.
Such conflicts may be overcame by making the offending taggles to be
adjacent to underscores, but then who would write something like
‘checked real_ to_ int_’ or ‘checked real_to_int’? It is much simpler
to just mandate for tags to be written as ‘checked_real_to_int’. This
avoids any possibility of conflict since all the taggles are adjacent to
an underscore and therefore cant collide with reserved words. Also, the
risk of programs breaking in the future once new reserved words get
added to the language via new symbols introduced by language extensions
gets dramatically lowered.
The second reason is that the notion of allowing spaces, tabs and
newlines to be interjected in user-defined identifiers is alien to most
if not all programming languages widely used today. It is,
unfortunately, an eccentricity, even if a beautiful one, which
unfortunately makes it difficult to leverage existing tools such as
editors, code indentation engines, and basically any program that makes
assumptions on the general form of programming languages. For example,
convincing a programming editor or IDE that a single identifier may span
for more than one logical line in the source code may prove challenging.
2 Formal Description
********************
This extension adds a new stropping regime to the Standard Hardware
Representation, so a new pragmat-item shall be invented.
3.5
... of which there are four. A new regime is invoked by a pragmat
containing one of the pragmat-items POINT, UPPER, RES or GNURES, and
takes effect following the closing pragmat symbol.
The new stropping regime is then described in its own section, as
follows.
3.5.4 GNURES Stropping
Bold words.
- A bold word is written as a sequence of {one or more} taggles
whose worthy letters and digits correspond, in order, to the bold
faced letters and digits in the word.
- A bold word must start with an upper-case letter. Upper- and
lower-case letters may be intermixed in a bold word.
- Upper-case letters may be written only in bold words and
character-glyphs.
Tags.
- A tag is written as a sequence of {one or more} taggles. The
taggles cannot be separated by typographical display features.
- A taggle is written by writing, in order, the corresponding
worthy letters and digits optionally followed by an underscore.
- A taggle must be adjacent to an underscore if its letters and
digits correspond, in order, to those of a reserved word.
- If a taggle does not end with an underscore, it must be followed
by a disjunctor.
{Examples:
Program: PR GNURES PR begin real x; x := x - 1 end
Bold: begin, AMode, AmOdE, AMODE, Oper, OPER
Plain: begin_, end_of_file, end_of_file_, xl,
x_l,
Error: Some_Mode, end of file, end____of__file,
end_of_file__ }
3 Implementation Notes
**********************
Stropping is to be implemented purely at the lexical level and it must
not have any impact on the letters and digits that constitute bold words
and tags. Therefore, in principle, of all the components of a compiler
or interpreter only the lexical analyzer (or tokenizer) shall concern
itself with the stropping regime.
More information about the Algol68
mailing list