{"id":11710,"date":"2025-08-28T01:03:00","date_gmt":"2025-08-28T05:03:00","guid":{"rendered":"https:\/\/www.both.org\/?p=11710"},"modified":"2025-08-29T15:09:48","modified_gmt":"2025-08-29T19:09:48","slug":"exploring-gnu-algol-68","status":"publish","type":"post","link":"https:\/\/www.both.org\/?p=11710","title":{"rendered":"Exploring GNU Algol 68"},"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=\"11710\" 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>Since early 2019, I\u2019ve spent some time here and there refreshing my appreciation for the Algol 68 programming language, courtesy of Marcel van der Veer\u2019s most excellent <a href=\"https:\/\/jmvdveer.home.xs4all.nl\/en.algol-68-genie.html\">Algol 68 Genie implementation<\/a>. Using the Genie compiler \/ interpreter, I\u2019ve written a fair bit of code, mostly for fun but occasionally for small work-related projects. And even though the design of Algol 68 predates many useful and appealing programming language features that are today mainstream, Algol 68 got so much very right that it seems short-sighted to ignore the many useful lessons it can provide.<\/p>\n\n\n\n<p>Earlier in 2025, I was delighted to stumble upon another modern implementation of Algol 68 \u2013 <a href=\"https:\/\/gcc.gnu.org\/wiki\/Algol68FrontEnd\">GNU Algol 68<\/a>, which is built using the GNU Compiler Collection. If having one great Algol 68 implementation is good, how can having two such not be even better?<\/p>\n\n\n\n<p>And so I decided to spend some time exploring GNU Algol 68, which has motivated me to write a few more articles about this revolutionary programming language.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">GNU Algol 68 is in development&#8230;<\/h2>\n\n\n\n<p>&#8230; and the Roadmap section of <a href=\"https:\/\/gcc.gnu.org\/wiki\/Algol68FrontEnd\">the GNU Algol 68 wiki entry in the GNU Compiler Collection<\/a> \u2013 hereafter abbreviated to <em><strong>ga68<\/strong><\/em> and <em><strong>GCC<\/strong><\/em> respectively \u2013 provides an overview of what\u2019s yet to be implemented. Perhaps the most broadly painful as-yet-missing feature is conversion of integers, reals, booleans, bits and bytes to strings and back again, since without these utilities, it\u2019s quite difficult to write a program that can output its results in human readable form.<\/p>\n\n\n\n<p>So my first order of business was to hack together the standard Algol 68 <em><strong>transput<\/strong><\/em> procedures <em>whole()<\/em> and <em>fixed()<\/em>, which convert integers and reals to string. In writing these procedures, I reacquainted myself with a few Algol 68 design decisions that have never felt particularly useful to me:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>a call to <em>whole(i, -4)<\/em> will yield\n<ul class=\"wp-block-list\">\n<li>&#8220;\ufe4e\ufe4e\ufe4e0\u201d, &#8220;\ufe4e\ufe4e99&#8221;, &#8220;\ufe4e-99&#8221;, &#8220;9999&#8221; or, if i were greater than 9999, &#8220;****&#8221;, where &#8220;*&#8221; is the yield of errorchar and \u201c\ufe4e\u201d represents a space;<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>a call to <em>whole(i, 4)<\/em> will yield\n<ul class=\"wp-block-list\">\n<li>&#8220;\ufe4e+99&#8221; rather than &#8220;\ufe4e\ufe4e99&#8221;;<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>a call to <em>whole(i, 0)<\/em> will yield\n<ul class=\"wp-block-list\">\n<li>&#8220;O&#8221;, &#8220;99&#8221;, &#8220;-99&#8221;, &#8220;9999&#8221; or &#8220;99999&#8221;;<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>and similar with <em>fixed()<\/em>.<sup data-fn=\"e8e50a03-a26d-4f84-a23c-8501212f036d\" class=\"fn\"><a href=\"#e8e50a03-a26d-4f84-a23c-8501212f036d\" id=\"e8e50a03-a26d-4f84-a23c-8501212f036d-link\">1<\/a><\/sup><\/li>\n<\/ul>\n\n\n\n<p>What is it I don\u2019t like about this? Two main things, really: first, as far as I can recall, I\u2019ve never wanted to print a positive number preceded by a plus sign, and while I\u2019m prepared to concede that some programmers might find this to be a great idea, I\u2019d rather it not require the active use of the negative width to turn it off; and second, if I\u2019m planning for output to fit in a certain width and I produce a larger number than will fit, I\u2019d prefer that my formatting be scrambled rather than my numbers, which seems like a lesser sin to me.<\/p>\n\n\n\n<p>As well, calls to whole() and fixed() most often occur within calls to the print() procedure, which is kind of a weird beast in Algol 68, defined as:<sup data-fn=\"772d0d54-3e5f-4166-90a6-9704b36c9d01\" class=\"fn\"><a href=\"#772d0d54-3e5f-4166-90a6-9704b36c9d01\" id=\"772d0d54-3e5f-4166-90a6-9704b36c9d01-link\">2<\/a><\/sup><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>proc<\/strong> print = (&#91; ] <strong>union<\/strong> (<strong>outtype<\/strong>, <strong>proc<\/strong> (<strong>ref<\/strong> <strong>file<\/strong>) <strong>void<\/strong>) x) <strong>void<\/strong>:\nput (stand out, x)<\/code><\/pre>\n\n\n\n<p>with the definition of the mode <strong>outtype<\/strong> being well and truly fudged as:<\/p>\n\n\n\n<p><strong>mode<\/strong> <strong>outtype<\/strong> = <strong>c<\/strong> an actual-declarer specifying a mode united from (2.1.3.6.a} a sufficient set of modes none of which is \u2018<strong>void<\/strong>\u2019 or contains &#8216;<strong>flexible<\/strong>&#8216;, &#8216;<strong>reference to<\/strong>&#8216;, &#8216;<strong>procedure<\/strong>&#8216; or &#8216;<strong>union of<\/strong>&#8216; <strong>c<\/strong>;<\/p>\n\n\n\n<p>Moreover, the Revised Report goes on to define the coercion straightening which is used to deal with multiple values (rows, rows of rows etc) and structured values; this definition is equally an algorithmic comment, rather than actual code.<sup data-fn=\"78311783-89fe-4943-843c-8349d36bd5bc\" class=\"fn\"><a href=\"#78311783-89fe-4943-843c-8349d36bd5bc\" id=\"78311783-89fe-4943-843c-8349d36bd5bc-link\">3<\/a><\/sup><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">&#8230; but I want to use it!<\/h2>\n\n\n\n<p>Given all this complexity and needing to live \u2013 for now, at least \u2013 within ga68\u2019s limitation of only providing the <em>puts()<\/em> procedure, which emits a single string, I came to some decisions \u2013 I would write a set of routines that:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>use a \u201clocale\u201d facility to govern things like thousands separator, plus or minus sign, decimal separator&#8230;;<\/li>\n\n\n\n<li>for integers, convert the number to the minimum length string, with or without thousands separators;<\/li>\n\n\n\n<li>for real numbers, convert the number to either fixed or scientific notation, respecting the approximate number of significant figures provided by the real mode (ie no specification for number of figures to the right of the decimal point \u2013 I might add this later);<\/li>\n\n\n\n<li>besides integer and real, additionally handle long integer, long real, bits and boolean, but for now no additional handling for short integer, etc;<\/li>\n\n\n\n<li>additionally provide binary and hexadecimal format for integer and long integer; and<\/li>\n\n\n\n<li>position one string within another \u2013 e.g. placing a 3 digit number to the right of a 10 character space \u2013 separately from the format conversion of the number to a string.<\/li>\n<\/ul>\n\n\n\n<p>A design decision made by the design committee allows the overloading of operators, so that the same operator \u2013 e.g. <strong>plus<\/strong>, + \u2013 can be used between two integers, an integer and a real, and so forth. However, the committee did not extend the concept of overloading to procedures. At least in relation to the problem at hand, this pushed me into deciding to implement my output routines as unary operators, of which there are currently:<\/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\n\n\n<li><strong>TOSE<\/strong> { format real, long real as scientific notation }<\/li>\n\n\n\n<li><strong>TOSF<\/strong> { format real, long real as fixed decimal string }<\/li>\n<\/ul>\n\n\n\n<p>Implementing these routines as operators provides the additional benefit of not requiring parentheses around the operand (unless it is an expression).<\/p>\n\n\n\n<p>Note that there is an indirect method to handle overloading, which works for both operators and procedures \u2013 the use of <em><strong>united mode parameters<\/strong><\/em> and the <em><strong>conformity clause<\/strong><\/em>. For example, a procedure that handles the same arguments as the TOS operator might look like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>proc tos<\/strong> = (<strong>union<\/strong> (<strong>int<\/strong>, <strong>long<\/strong> <strong>int<\/strong>, <strong>bool<\/strong>) x) <strong>string<\/strong>:\n     <strong>case<\/strong> x <strong>in<\/strong>\n(<strong>int<\/strong> ix): { do something when int argument supplied },\n(<strong>long<\/strong> int lx): { do something when long int argument supplied },\n(<strong>bool<\/strong> bx): { do something when bool argument supplied }\n<strong>esac<\/strong><\/code><\/pre>\n\n\n\n<p>So it\u2019s not the end of the world to go with procedure versions. Worth noting is that \u2013 as long as the argument to the procedure (or operator) taking a united mode parameter is not itself of a similar united mode, then the compiler could determine at compile time which case applies and the case clause need not be evaluated at run time.<\/p>\n\n\n\n<p>As I was working on these operators, a thought occurred to me \u2013 were I writing some program dealing with a particular structured or multiple value, I might find myself implementing a <strong>TOS<\/strong> operator for instances of those structured or row values. For example, I could see myself writing a <strong>TOS<\/strong> operator for the vectors and matrices I used in my <a href=\"https:\/\/www.both.org\/?p=11220\">least-squares fitting article<\/a>.<\/p>\n\n\n\n<p>In my next article, we\u2019ll dive into coding the <strong>TOS<\/strong>, <strong>TOSS<\/strong>, <strong>TOSB<\/strong> and <strong>TOSX<\/strong> operators.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n<ol class=\"wp-block-footnotes\"><li id=\"e8e50a03-a26d-4f84-a23c-8501212f036d\"><a href=\"https:\/\/www.softwarepreservation.org\/projects\/ALGOL\/report\/Algol68_revised_report-AB-600dpi.pdf\"><em>Algol 68 Revised Report<\/em><\/a>, p. 159. <a href=\"#e8e50a03-a26d-4f84-a23c-8501212f036d-link\" aria-label=\"Jump to footnote reference 1\">\u21a9\ufe0e<\/a><\/li><li id=\"772d0d54-3e5f-4166-90a6-9704b36c9d01\"><em>ibid<\/em>, p. 209. <a href=\"#772d0d54-3e5f-4166-90a6-9704b36c9d01-link\" aria-label=\"Jump to footnote reference 2\">\u21a9\ufe0e<\/a><\/li><li id=\"78311783-89fe-4943-843c-8349d36bd5bc\"><em>ibid<\/em>, p. 163. <a href=\"#78311783-89fe-4943-843c-8349d36bd5bc-link\" aria-label=\"Jump to footnote reference 3\">\u21a9\ufe0e<\/a><\/li><\/ol>","protected":false},"excerpt":{"rendered":"<p>Since early 2019, I&rsquo;ve spent some time here and there refreshing my appreciation for the Algol 68 programming<\/p>\n","protected":false},"author":430,"featured_media":2814,"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>, p. 159.\",\"id\":\"e8e50a03-a26d-4f84-a23c-8501212f036d\"},{\"content\":\"<em>ibid<\/em>, p. 209.\",\"id\":\"772d0d54-3e5f-4166-90a6-9704b36c9d01\"},{\"content\":\"<em>ibid<\/em>, p. 163.\",\"id\":\"78311783-89fe-4943-843c-8349d36bd5bc\"}]"},"categories":[794,98,5,150],"tags":[],"class_list":["post-11710","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-algol-68","category-code","category-linux","category-programming"],"modified_by":"David Both","_links":{"self":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/11710","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=11710"}],"version-history":[{"count":8,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/11710\/revisions"}],"predecessor-version":[{"id":11797,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/11710\/revisions\/11797"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/media\/2814"}],"wp:attachment":[{"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=11710"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=11710"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=11710"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}