{"id":11832,"date":"2025-09-03T01:01:00","date_gmt":"2025-09-03T05:01:00","guid":{"rendered":"https:\/\/www.both.org\/?p=11832"},"modified":"2025-09-02T21:04:09","modified_gmt":"2025-09-03T01:04:09","slug":"exploring-gnu-algol-68-formatting-numbers-as-strings-for-output","status":"publish","type":"post","link":"https:\/\/www.both.org\/?p=11832","title":{"rendered":"Exploring GNU Algol 68: Formatting numbers as strings for output"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"11832\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">    <\/span>\r\n<\/div><\/div>\n<p>As I mentioned in <a href=\"https:\/\/www.both.org\/?p=11710\">my introductory article to this mini-series<\/a>, GNU Algol 68 is in development, and as of the date of writing this article, <a href=\"https:\/\/gcc.gnu.org\/wiki\/Algol68FrontEnd\">does not include<\/a> procedures (nor operators) to convert integer, floating point, boolean, bits or bytes to string for output \u2013 what Algol 68 calls <em><strong>transput<\/strong><\/em>. While the Algol 68 revised report defines transput procedures <em>whole()<\/em>, <em>fixed()<\/em> and <em>float()<\/em>,<sup data-fn=\"5ff20f42-1ceb-4068-abab-2765ce612b56\" class=\"fn\"><a href=\"#5ff20f42-1ceb-4068-abab-2765ce612b56\" id=\"5ff20f42-1ceb-4068-abab-2765ce612b56-link\">1<\/a><\/sup> I mentioned that I don\u2019t care for some of the design decisions that went into those routines and so I decided to create my own.<\/p>\n\n\n\n<p>In this article, we will design and code Algol 68 operators:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>TOS<\/strong> { format int, long int, bool as decimal string }<\/li>\n\n\n\n<li><strong>TOSS<\/strong> { format int, long int as decimal string with thousands separators }<\/li>\n\n\n\n<li><strong>TOSB<\/strong> { format int, long int, bits, long bits as binary string e.g. 2r010010 }<\/li>\n\n\n\n<li><strong>TOSX<\/strong> { format int, long int, bits, long bits as hexadecimal string e.g. 16r15ea }<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">But first, terminology, operators and stropping&#8230;<\/h2>\n\n\n\n<p>Algol 68 was designed by the ALGOL 68 Support subcommittee (the committee) of the International Federation for Information Processing (IFIP) Working Group 2.1 on ALGOL (WG2.1). In addition to designing the programming language, the committee also selected a <em><strong>metalanguage<\/strong><\/em>, proposed by A. van Wijngaarden, to formally describe the syntax and semantics of the programming language.<\/p>\n\n\n\n<p>Because it was a fresh-sheet design and took on the task of formally specifying both syntax and semantics, this metalanguage was seen as going too far by some of the committee members and other interested parties, resulting in acrimony and division.<\/p>\n\n\n\n<p>As a result, endless ink (or bits, at least) have been spilled complaining about the design of Algol 68, including up to present times.<sup data-fn=\"f480ed90-fe78-46ef-8814-e8f2588b169f\" class=\"fn\"><a href=\"#f480ed90-fe78-46ef-8814-e8f2588b169f\" id=\"f480ed90-fe78-46ef-8814-e8f2588b169f-link\">2<\/a><\/sup> Most of the early complaints centre on the supposed difficulty of writing a compiler for the language, which seems to be less of an issue today given the existence of the excellent GNU Algol 68 and Algol 68 Genie compilers. Many other complaints stem from a commonly held perspective that a fresh-sheet design including a new means for language description was much more than just coming up with a facelift for Algol 60, which had been the original goal of WG2.1, and which eventually materialized independently as Algol W, Pascal and its descendants.<\/p>\n\n\n\n<p>More recent negative observations on Algol 68 rehash these two arguments over and over again, but beyond that, one clear thread emerges from the criticism: van Wijngaarden\u2019s metalanguage is unusual, even today, and the writing style of the report is replete with puns and in-jokes that is obviously seen as insufferable to some and generates dismissive comments based on no real understanding of, nor experience with, the programming language itself.  Many have stopped before starting, to their loss.  Oh well!<\/p>\n\n\n\n<p>One of the really delightful and useful by-products of the GNU Algol 68 compiler is <a href=\"https:\/\/jemarch.net\/a68-jargon\">The Algol 68 Jargon File<\/a>. Having this document handy while learning the terminology of Algol 68 is a great help.<\/p>\n\n\n\n<p>Another nearly essential document for learning Algol 68 is <a href=\"https:\/\/inria.hal.science\/hal-03027689\/file\/Lindsey_van_der_Meulen-IItA68-Revised.pdf\">Informal Introduction to ALGOL 68<\/a>, created at the behest of the committee as a more approachable document for learning the language and its accompanying terminology.<\/p>\n\n\n\n<p>Algol 68 introduced the concept of user-definable <strong><em>operators<\/em><\/strong>, distinct from <strong><em>procedures<\/em><\/strong>, in several ways:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>operators are <strong><em>monadic<\/em><\/strong> (taking one argument) or <strong><em>dyadic<\/em><\/strong> (taking two arguments), whereas procedures take zero or more arguments;<\/li>\n\n\n\n<li>monadic operators are applied to their operand immediately to the right of the operator;<\/li>\n\n\n\n<li>dyadic operators are applied to the operand immediately to the left and immediately to the right of the operator;<\/li>\n\n\n\n<li>procedures with one or more arguments accepted those as a parenthesized list separated by commas, that is, a <em>collateral clause<\/em>;<\/li>\n\n\n\n<li>operators are associated with the concept of <strong><em>priority<\/em><\/strong>; monadic operators have a single priority, higher than any dyadic operator; dyadic operators also declare their priority;<\/li>\n\n\n\n<li>operators can be <strong><em>overloaded<\/em><\/strong>; that is, the same name can be defined multiply for different parameter types or <em>modes<\/em>;<\/li>\n\n\n\n<li>both operators and procedures can achieve a kind of \u201coverloading effect\u201d by declaring parameters of <em><strong>united modes<\/strong><\/em> and dealing with the different constituent modes using a special kind of case statement, the <em><strong>conformity clause<\/strong><\/em>; however, operator overloading permits the defining of a similar operation on a new type in independent fashion, whereas using united modes requires altering the united parameter definition and conformity clause.<\/li>\n<\/ul>\n\n\n\n<p>Finally, in Algol 68 there is a need to distinguish between a <em>begin-symbol<\/em> and, for example, a variable named \u201cbegin\u201d, both of which are legal. In documentation, the begin symbol (and all other symbols) are written in boldface (sometimes bold italics, as in the Revised Report), as <strong>begin<\/strong>, <strong>end<\/strong>, <strong>if<\/strong>, <strong>then<\/strong>, <strong>else<\/strong>, <strong>do<\/strong> and so on; names, such as constants or variables, are written in italics, as <em>x<\/em>, <em>y<\/em>, <em>foo<\/em>, <em>bar<\/em> and so on; and non-text symbols such as parentheses, or plus-symbol as (, ), + and so on. Recognizing that this typography wasn\u2019t immediately feasible back in the 1970s, a mechanism for marking text symbols was defined as <em><strong>stropping<\/strong><\/em>. Some forms of stropping included <em>point stropping<\/em>, where <strong>begin<\/strong> would be typed as <code>.begin<\/code>, or <em>upper stropping<\/em>, where <strong>begin<\/strong> would be typed as <code>BEGIN<\/code>.<\/p>\n\n\n\n<p>By default, GNU Algol 68 uses <strong><em>supper<\/em><\/strong> stropping, where, as the fledgling ga68.pdf manual (created by the compiler build process) states:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><em>In the SUPPER 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.<\/em><\/p>\n<\/blockquote>\n\n\n\n<p>The manual goes on to state that a mode-indicant, for example defining a 3D vector, could be entered as <kbd>Vector3D<\/kbd>, <kbd>VECTOR3D<\/kbd>, <kbd>Vector_3D<\/kbd> and so on, suggesting that \u201ccamel case\u201d convention used for type or class definitions in other languages is supported here. The manual further counsels Introducing new operator-indicants as all in upper case, as in<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">v1 EQUALS v2<\/pre>\n\n\n\n<p>Finally, implied but not stated, all predefined symbols such as <strong>begin<\/strong>, <strong>end<\/strong>, <strong>if<\/strong> etc and all predefined mode-indicants such as <strong>int<\/strong>, <strong>real<\/strong>, <strong>bool<\/strong> etc are entered in lower case; and all predefined operators such as <strong>and<\/strong>, <strong>or<\/strong>, <strong>abs<\/strong> etc are entered in upper case.<\/p>\n\n\n\n<p>Ok, enough background. Whew! Let\u2019s get coding&#8230;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conversion from integer to string<\/h2>\n\n\n\n<p><a href=\"https:\/\/towardsdatascience.com\/34-faster-integer-to-string-conversion-algorithm-c72453d25352\">This article<\/a> has a nice description of an efficient conversion from integer to string. We\u2019ll follow its recommendations.<\/p>\n\n\n\n<p>First, because we are proceeding from left to right for the sake of cutting the number of integer divisions in half, we need to know how many base-10 digits there are in the integer to be converted, so we define this Algol 68 operator:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">op DIGITS = (int number) int: begin\n\n    { get number of digits in an integer (max int = 2147483647) }\n\n    int work = ABS number;\n    if   work &lt; 10 then 1\n    elif work &lt; 100 then 2\n    elif work &lt; 1 000 then 3\n    elif work &lt; 10 000 then 4\n    elif work &lt; 100 000 then 5\n    elif work &lt; 1 000 000 then 6\n    elif work &lt; 10 000 000 then 7\n    elif work &lt; 100 000 000 then 8\n    elif work &lt; 1 000 000 000 then 9\n    else 10 fi\n\nend { DIGITS };<\/pre>\n\n\n\n<p>Two alternatives exist to the sequence of if&#8230; elif&#8230; fi would be<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>binary search instead of sequential;<\/li>\n\n\n\n<li>calculate the base 10 logarithm of the number and truncate it.<\/li>\n<\/ul>\n\n\n\n<p>I have a feeling there is nothing much to be gained by either of these&#8230;<\/p>\n\n\n\n<p>Second, we need a \u201cpower of 10\u201d lookup table, which looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">[]int int_powers_of_10 = (1, 10, 100, 1 000, 10 000, 100 000, 1 000 000, 10 000 000, 100 000 000, 1 000 000 000);<\/pre>\n\n\n\n<p>Since we know the number of digits, and we also know the sign, and we know we don\u2019t want a plus-symbol to precede a positive number, we can modify the suggested algorithm slightly as follows:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">op TOS = (int number) string: begin\n\n    { convert integer to string with no MOD }\n\n    int number_digits = DIGITS number;\n    int work;\n    int chars_needed = (number &lt; 0 | work := -number; number_digits + 1 | work := number; number_digits);\n    [1:chars_needed]char result;\n    int result_char := (number &lt; 0 | result[1] := \"-\"; 2 | 1);\n    int char_zero = ABS \"0\";\n    for digit_number from number_digits by -1 to 1 do\n        int p10 = int_powers_of_10[digit_number];\n        int digit = work % p10;\n        result[result_char] := REPR (digit + char_zero);\n        result_char +:= 1;\n        work -:= digit * p10\n    od;\n    result\n\nend { TOS };<\/pre>\n\n\n\n<p>A few things to mention in relation to the above code:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>one thing that often catches me when I haven\u2019t used Algol 68 for awhile:\n<ul class=\"wp-block-list\">\n<li>the integer division symbol is % or OVER;<\/li>\n\n\n\n<li>the real division symbol is \/ or DIV;<\/li>\n\n\n\n<li>the integer modulo symbol is %* or MOD<\/li>\n\n\n\n<li>I should probably always use OVER and MOD and I do dislike %* though I can see the sense of it&#8230;<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>in the definition of the constant <code>chars_needed<\/code> I use the brief form of if &#8230; then &#8230; else &#8230; fi which is ( &#8230; | &#8230; | &#8230; ) and I also set the value of the variable <code>work<\/code> within that expression; normally I would avoid side effects like this but I believe in this kind of simple case there is more clarity created by the compactness than by some other approach;<\/li>\n\n\n\n<li>the same is true for the definition and initialization of the variable <code>result_char<\/code> and inserting the minus-symbol into <code>result<\/code> if the number is negative;<\/li>\n\n\n\n<li>because we have the number of digits needed, we can create the output buffer <code>result<\/code> to be the exact size required;<\/li>\n\n\n\n<li>I\u2019m making a conscious effort to use constant values whenever possible, leaving only three variables: <code>work<\/code>, <code>result<\/code> and <code>result_char<\/code>.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Integer to string, with thousands separators<\/h2>\n\n\n\n<p>What if we want thousands separators in our output? Here\u2019s TOSS:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">op TOSS = (int number) string: begin\n\n    { convert integer to string with no MOD and with thousands separators }\n\n    int number_digits = DIGITS number;\n    int work;\n    int chars_needed = (number &lt; 0 | work := -number; number_digits + 1 | work := number; number_digits) + number_digits % 3;\n    [1:chars_needed]char result;\n    int result_char := (number &lt; 0 | result[1] := \"-\"; 2 | 1);\n    int char_zero = ABS \"0\";\n    for digit_number from number_digits by -1 to 1 do\n        int p10 = int_powers_of_10[digit_number];\n        int digit = work % p10;\n        result[result_char] := REPR (digit + char_zero);\n        if digit_number &gt; 1 AND (digit_number - 1) MOD 3 = 0 then\n            result_char +:= 1;\n            result[result_char] := \",\"\n        fi;\n        result_char +:= 1;\n        work -:= digit * int_powers_of_10[digit_number]\n    od;\n    result\n\nend { TOSS };<\/pre>\n\n\n\n<p>A few comments:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>the <code>chars_needed<\/code> constant definition is adjusted for the number of thousands separators required;<\/li>\n\n\n\n<li>the separator itself is inserted after the thousands digit;<\/li>\n\n\n\n<li>thinking for down the road, we should probably provide some basic internationalization here by defining constants that indicate the positive, negative, decimal and thousands separator characters.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Boolean to string<\/h2>\n\n\n\n<p>Ok, we\u2019re on a bit of a roll&#8230; Let\u2019s write a version of <code>TOS<\/code> that takes a boolean argument:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">op TOS = (bool v) string: begin\n\n    { convert boolean to \u201ctrue\u201d or \u201cfalse }\n\n    if v then \"true\" else \"false\" fi\n\nend { TOS };<\/pre>\n\n\n\n<p>This is pretty self-explanatory \u2013 the result of the if &#8230; fi is either the string \u201ctrue\u201d or the string \u201cfalse\u201d.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Bits and int to bit string<\/h2>\n\n\n\n<p>Moving on to TOSB, let\u2019s do the operator to convert a <code>bits<\/code> value to the standard Algol 68 binary representation e.g. <code>2r0101010<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">op TOSB = (bits v) string: begin\n\n    { convert bits to Algol 68 bit string representation }\n\n    [1:bits_width]char co;\n    for c from LWB co to UPB co do\n        if c ELEM v then\n            co[c] := \"1\"\n        else\n            co[c] := \"0\"\n        fi\n    od;\n    \"2r\" + co\n\nend { TOSB };<\/pre>\n\n\n\n<p>This is straightforward, depending on the constant <code>bits_width<\/code> and the <code>bits<\/code> operator <code>ELEM<\/code> which indicates whether a given bit is 0 or 1, defined in the standard prelude. Note that it prints all 32 bits, rather than suppressing leading zeros.<\/p>\n\n\n\n<p>We can build on this to handle integer values:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">op TOSB = (int v) string: begin\n\n    { convert int to Algol 68 bit string representation }\n\n    TOSB BIN v\n\nend { TOSB };<\/pre>\n\n\n\n<p>Here we use the <code>BIN<\/code> operator to convert the <code>int<\/code> value <code>v<\/code> to <code>bits<\/code>.<\/p>\n\n\n\n<p>This is a good moment to revisit the concept of monadic operators \u2013 the expression <code>TOSB<\/code> <code>BIN<\/code> <code>v<\/code> is evaluated as though there are parentheses around <code>BIN<\/code> <code>v<\/code>, forcing it to be evaluated before the operator <code>TOSB<\/code> is applied. It\u2019s also a good moment to remember that the so-called \u201cunary minus\u201d is a monadic operator in Algol 68. Later on, when we consider extending these TOS operators to work on <code>long<\/code> <code>int<\/code>, <code>long<\/code> <code>bits<\/code> and so on, we will see that the expression<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">long 3<\/pre>\n\n\n\n<p>is not an operator applied to the int value 3 but rather a way of declaring a long int constant, whereas<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">LENG 3<\/pre>\n\n\n\n<p>converts the int value 3 to long int.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Bits and string to hexadecimal<\/h2>\n\n\n\n<p>FInally, the TOSX operator that converts a <code>bits<\/code> value to the standard Algol 68 hexadecimal representation e.g. <code>16r1234abcd<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">op TOSX = (bits v) string: begin\n\n    { convert bits to Algol 68 hexadecimal string representation }\n\n    bits bv := v;\n    [1:bits_width % 4] char co;\n    int vc0 = ABS \"0\", vca = ABS \"A\";\n    for c from UPB co by -1 to LWB co do\n        int hdv = ABS (bv AND 16r0f); \n        co[c] := REPR (hdv + (hdv &lt; 10 | vc0 | vca - 10)); \n        bv := bv SHR 4\n    od;\n    \"16r\" + co\n\nend { TOSX };<\/pre>\n\n\n\n<p>and the version that converts an int to hexadecimal:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">op TOSX = (int v) string: begin\n\n    { convert int to Algol 68 hexadecimal string representation }\n\n    TOSX BIN v\n\nend { TOSX }; <\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Let\u2019s test it&#8230;<\/h2>\n\n\n\n<p>Here\u2019s a very minimal test script:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">pr include \"tos.a68\" pr\n\nbegin\n\n\tputs(\"TOS 123456 = \" + TOS 123456 + \"'n\");\n\tputs(\"TOSS 123456 = \" + TOSS 123456 + \"'n\");\n\tputs(\"TOS -123456 = \" + TOS -123456 + \"'n\");\n\tputs(\"TOSS -123456 = \" + TOSS -123456 + \"'n\");\n\n\tputs(\"TOS (1 = 1) = \" + TOS (1 = 1) + \"'n\");\n\n\tputs(\"TOSB 2r010101 = \" + TOSB 2r010101 + \"'n\");\n\tputs(\"TOSB 42 = \" + TOSB 42 + \"'n\");\n\tputs(\"TOSB -1 = \" + TOSB -1 + \"'n\");\n\n\tputs(\"TOSX 2r010101 = \" + TOSX 2r010101 + \"'n\");\n\tputs(\"TOSX 42 = \" + TOSX 42 + \"'n\");\n\tputs(\"TOSX -1 = \" + TOSX -1 + \"'n\");\n\n\n\tskip\nend\n<\/pre>\n\n\n\n<p>A few observations:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>here we see clearly the difference between <code>TOS<\/code> as operators vs as procedures \u2013 the only time we use parentheses is to provide an expression as the argument, for example <code>TOS (1 = 1)<\/code>;<\/li>\n\n\n\n<li>what\u2019s not seen is that I have incorporated all my operator definitions into the file \u201ctos.a68\u201d and I include it using the <code>pr<\/code> <code>include<\/code> &#8230; <code>pr<\/code> pragmat;<\/li>\n\n\n\n<li>when I\u2019m writing test code I often leave a <code>skip<\/code> just before the end of the particular-program (the serial clause between the <code>begin<\/code> and <code>end<\/code>), so that I don\u2019t have to be careful about leaving off the semicolon on the last test statement.<\/li>\n<\/ul>\n\n\n\n<p>Assuming this code is in the file \u201ctesttos01a.a68\u201d, compile it with<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ga68 testtos01a.a68<\/pre>\n\n\n\n<p>and run it with<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">.\/a.out<\/pre>\n\n\n\n<p>to get the output<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">TOS 123456 = 123456\nTOSS 123456 = 123,456\nTOS -123456 = -123456\nTOSS -123456 = -123,456\nTOS (1 = 1) = true\nTOSB 2r010101 = 2r00000000000000000000000000010101\nTOSB 42 = 2r00000000000000000000000000101010\nTOSB -1 = 2r11111111111111111111111111111111\nTOSX 2r010101 = 16r00000015\nTOSX 42 = 16r0000002A\nTOSX -1 = 16rFFFFFFFF<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Dealing with long int, long bits<\/h2>\n\n\n\n<p>We\u2019re going to park this issue for now and revisit it later, but a few things to ponder in the meantime:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>it seems like the conversion process will look almost the same for long int and long bits as for int and bits, which leads to the question \u2013 should we duplicate the code, then change it? or should we use the same code for both int and long int, bits and long bits, by converting the int and bits parameters to long int and long bits, thereby using the long version for each?<\/li>\n\n\n\n<li>we\u2019ve already almost duplicated the code for TOS and TOSS on int values; should we refactor the formatting into a shared routine and use a flag to indicate whether or not to incorporate the thousands separators?<\/li>\n\n\n\n<li>should we take on the idea of internationalizing the code while we\u2019re making the change, so that we can use for example the period as the thousands separator and the comma as the decimal point, or printing numbers in financial format, where \u242212,345.00\u2422 represents positive 12345 and (12,345.00) represents negative 12345?<\/li>\n<\/ul>\n\n\n\n<p>In our next article, we\u2019ll take on the floating point conversion operators <code>TOSE<\/code> and <code>TOSF<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n<ol class=\"wp-block-footnotes\"><li id=\"5ff20f42-1ceb-4068-abab-2765ce612b56\"><a href=\"https:\/\/www.softwarepreservation.org\/projects\/ALGOL\/report\/Algol68_revised_report-AB-600dpi.pdf\"><em>Algol 68 Revised Report<\/em><\/a>, pp. 159-160. <a href=\"#5ff20f42-1ceb-4068-abab-2765ce612b56-link\" aria-label=\"Jump to footnote reference 1\">\u21a9\ufe0e<\/a><\/li><li id=\"f480ed90-fe78-46ef-8814-e8f2588b169f\">See for example \u201c<a href=\"https:\/\/craftofcoding.wordpress.com\/2024\/10\/21\/algol-68-seemed-like-a-good-idea-until-it-wasnt\">Algol 68 seemed like a good idea until it wasn\u2019t<\/a>\u201d, published in late 2024 in the blog <a href=\"https:\/\/craftofcoding.wordpress.com\/\"><em>The Craft of Coding<\/em><\/a>. <a href=\"#f480ed90-fe78-46ef-8814-e8f2588b169f-link\" aria-label=\"Jump to footnote reference 2\">\u21a9\ufe0e<\/a><\/li><\/ol>","protected":false},"excerpt":{"rendered":"<p>As I mentioned in my introductory article to this mini-series, GNU Algol 68 is in development, and as<\/p>\n","protected":false},"author":430,"featured_media":7679,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","footnotes":"[{\"content\":\"<a href=\\\"https:\/\/www.softwarepreservation.org\/projects\/ALGOL\/report\/Algol68_revised_report-AB-600dpi.pdf\\\"><em>Algol 68 Revised Report<\/em><\/a>, pp. 159-160.\",\"id\":\"5ff20f42-1ceb-4068-abab-2765ce612b56\"},{\"content\":\"See for example \u201c<a href=\\\"https:\/\/craftofcoding.wordpress.com\/2024\/10\/21\/algol-68-seemed-like-a-good-idea-until-it-wasnt\\\">Algol 68 seemed like a good idea until it wasn\u2019t<\/a>\u201d, published in late 2024 in the blog <a href=\\\"https:\/\/craftofcoding.wordpress.com\/\\\"><em>The Craft of Coding<\/em><\/a>.\",\"id\":\"f480ed90-fe78-46ef-8814-e8f2588b169f\"}]"},"categories":[794,98,792,106,5,150],"tags":[783,152],"class_list":["post-11832","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-algol-68","category-code","category-hacking","category-history","category-linux","category-programming","tag-algol-68","tag-programming"],"modified_by":"David Both","_links":{"self":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/11832","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/users\/430"}],"replies":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=11832"}],"version-history":[{"count":2,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/11832\/revisions"}],"predecessor-version":[{"id":11835,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/11832\/revisions\/11835"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/media\/7679"}],"wp:attachment":[{"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=11832"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=11832"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=11832"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}