<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Forth 203x]]></title><description><![CDATA[Forth 203x]]></description><link>https://forth203x.hashnode.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1593680282896/kNC7E8IR4.png</url><title>Forth 203x</title><link>https://forth203x.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Tue, 01 Sep 2026 16:51:14 GMT</lastBuildDate><atom:link href="https://forth203x.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Forth’s Architectural Mess: The Case of the Numeric Output Words]]></title><description><![CDATA[This article is a logical continuation of the article “Changes to the Standard, or, How Europe's Bush-Leaguers Murder Forth.”
The idea in this new article is the same: Forth has now become an architec]]></description><link>https://forth203x.hashnode.dev/forth-s-architectural-mess-the-case-of-the-numeric-output-words</link><guid isPermaLink="true">https://forth203x.hashnode.dev/forth-s-architectural-mess-the-case-of-the-numeric-output-words</guid><category><![CDATA[forth]]></category><dc:creator><![CDATA[Pure Forth]]></dc:creator><pubDate>Fri, 28 Aug 2026 14:48:54 GMT</pubDate><content:encoded><![CDATA[<p>This article is a logical continuation of the article “Changes to the Standard, or, How Europe's Bush-Leaguers Murder Forth.”</p>
<p>The idea in this new article is the same: Forth has now become an architectural mess. The problem lies in the language standard—or, more precisely, in the standards committee, whose members still have not understood which path the programming language should have taken. As a result, Forth has lost much of its standing in the global programming community. In contrast to the committee’s actions, I argue that a sound language architecture not only teaches Forth programmers to design programs properly, but also attracts new programmers to Forth. We will examine the issue using the numeric output words as an example.</p>
<p>Historical Forth mixes several different things together. The numeric output words simultaneously encode:</p>
<ol>
<li><p>the size of the number — single or double;</p>
</li>
<li><p>signedness — signed or unsigned;</p>
</li>
<li><p>the number base — BASE;</p>
</li>
<li><p>field width — for .R;</p>
</li>
<li><p>the actual algorithm for converting a number into a sequence of digits.</p>
</li>
</ol>
<p>Architecturally, however, this is the wrong approach: most of these distinctions should not give rise to different primitives.</p>
<p>The shortcomings of the current standard are rooted in its history. Forth was created as an interactive system. A person works at the console and types:</p>
<pre><code class="language-plaintext">HEX ABCD FFFF DECIMAL 1000
</code></pre>
<p>In other words, changing the number base is a property of the <strong>working session</strong>, not a separate function. This is excellent for a REPL. For libraries, it is not so good. Let us examine the problem using BASE as an example. Today, <strong>it is implicit global state</strong>. By itself, this is convenient. The problems begin when BASE becomes part of the execution context. <strong>Words cease to be pure</strong>: the behavior of a word depends not only on the stack, but also on external global state. In functional programming, one would say that BASE is a hidden argument to the function. <strong>The problem is implicit input data.</strong> Modern design practice favors simple composition of words without hidden dependencies on global state:</p>
<pre><code class="language-plaintext">f(x, base)
</code></pre>
<p>instead of</p>
<pre><code class="language-plaintext">global base
f(x)
</code></pre>
<p>because the first form is local and explicit.</p>
<p>Historically, Forth conflated two completely different tasks:</p>
<ul>
<li><p>how to interpret text (<code>123</code>, <code>ABCD</code>, etc.);</p>
</li>
<li><p>how to present a number to the user.</p>
</li>
</ul>
<p>BASE handles both at once. This was very convenient in the era of teletypes and interactive computing, but architecturally it couples two independent mechanisms. To completely redesign the current standard, these two things need to be separated:</p>
<ol>
<li><p>The input base for the REPL — global state of the interpreter.</p>
</li>
<li><p>The formatting base — an explicit parameter.</p>
</li>
</ol>
<p>The proper architecture for a new standard should look like this:</p>
<p><code>INPUT-BASE</code> — affects only the text interpreter;</p>
<p><code>FORMAT</code> — explicit conversion of a number into a string;</p>
<p><code>TYPE</code> — output of the string;</p>
<p>And the word “dot” is simply shorthand for the sequence of words:</p>
<pre><code class="language-plaintext">DECIMAL FORMAT TYPE
</code></pre>
<p>At the same time, one could write</p>
<pre><code class="language-plaintext">123 HEX FORMAT TYPE
</code></pre>
<p>without changing any global state. This preserves Forth’s conciseness when using the word “dot” while eliminating one of the language’s most unpleasant hidden dependencies.</p>
<p>If we look deeper into the problem of having several numeric output words in the standard, we encounter an interesting philosophical problem: <strong>the number of words in a dictionary is often a symptom not of a language’s richness, but of poorly chosen abstractions.</strong></p>
<p>Applied to Forth: <strong>the less successful the language model, the more words it needs as exceptions.</strong></p>
<p>Today, the words <code>U.</code>, <code>D.</code>, <code>U.R</code>, and <code>D.R</code> look like exceptions to a general rule. Historically, this is understandable, but conceptually they are simply different entry points into the same task. Why not have a single word? For example:</p>
<pre><code class="language-plaintext">123 PRINT
</code></pre>
<p>And that's it. If formatting and layout are needed, then:</p>
<pre><code class="language-plaintext">123 HEX 8 WIDTH PRINT
</code></pre>
<p>In this case, the stack describes <strong>intent</strong>, rather than selecting a specialized word.</p>
<p>Applied to Forth, it would be more appropriate to write it like this:</p>
<pre><code class="language-plaintext">123 HEX FORMAT TYPE
</code></pre>
<p>Architecturally, this is cleaner. At the same time, no one is taking aim at the historical word “dot,” because it follows from the general rule:</p>
<pre><code class="language-plaintext">: . DECIMAL FORMAT TYPE ;
</code></pre>
<p>Forth contains many historical “paired” words. Some of them arise because the language has no unified model of an object or data type. If there were a more rigorous concept of “value → representation,” half of these exceptions would disappear.</p>
<p>Let us establish the proper understanding once and for all: <strong>good Forth is not about having the minimum number of words. It is about having the minimum number of rules from which the words are derived.</strong></p>
<p>In this sense, <code>FORMAT</code> as a separate layer looks much more <strong>Forth-like</strong> than a collection of <code>U.</code>, <code>D.</code>, and so on. We are not adding a new word for every special case; we are building a small set of basic operations whose combinations cover all cases.</p>
<p>Historical Forth contains <code>U.</code>, <code>D.</code>, <code>U.R</code>, <code>D.R</code>, and <code>.</code>. Every new case requires a new word. The problem is not the number of words. The problem is that each word contains several decisions at once.</p>
<p>Today, the words in Forth have lost their purity, but suppose the model were:</p>
<pre><code class="language-plaintext">NUMBER FORMAT WIDTH ALIGN TYPE
</code></pre>
<p>Then the user does not learn the separate concept of <code>U.R</code>. The user learns several general concepts that can be combined.</p>
<p><strong>Good Forth should look like a small dictionary with a large space of possibilities. The dictionary may be large as well, but not because of new exceptional cases.</strong></p>
<p>The bad approach is:</p>
<p><code>U. D. U.R D.R .</code></p>
<p>because each word answers the question, “Which particular way of printing?”</p>
<p>The good approach is:</p>
<pre><code class="language-plaintext">FORMAT WIDTH ALIGN TYPE
</code></pre>
<p>because the words answer the question, “Which properties of the number’s representation?”</p>
<p>Of course, an <strong>adept of the old architecture</strong> will say that Forth is already minimalist enough as it is. But let us look at the fact that the language has not become any better for it: <strong>you have simply hidden the absence of a model behind names.</strong> We are not talking about composition at the implementation level, but about composition at the level of the language’s semantic model. <strong>The mere fact that a word is built from primitives says nothing about the quality of the abstraction.</strong> The key question is whether the word is a new building block, or merely a patch over a crack in the architecture.</p>
<p>We now move naturally to the question of which words should exist in the language as primitives, and which should be expressed in terms of them. Let us follow these principles:</p>
<ol>
<li><p>The dictionary remains extensible, but the standard should describe the core, not every possible library.</p>
</li>
<li><p>Minimize hidden state. In this case, that state is BASE.</p>
</li>
<li><p>Words should express concepts, not cases. If a new requirement calls for adding a new word, perhaps the abstraction is missing something.</p>
</li>
<li><p>A new level of abstraction should not explain what already exists; it should eliminate existing exceptions.</p>
</li>
</ol>
<p>Let us start with a simple question: what does the word “dot” do? It appears to be a single action. But in reality, several different things happen inside it:</p>
<ol>
<li><p>The number is taken from the stack.</p>
</li>
<li><p>Its interpretation is determined: signed? unsigned? single? double?</p>
</li>
<li><p>The base is selected: DECIMAL? HEX?</p>
</li>
<li><p>The number is converted into a sequence of characters.</p>
</li>
<li><p>The characters are output.</p>
</li>
</ol>
<p>In other words, this is not simply number output. It is a small combine harvester.</p>
<p>At what point does the problem begin? A requirement appears:</p>
<p>123 .</p>
<p>Fine. But then another requirement appears:</p>
<p>123 U.</p>
<p>Why? Because it turns out that the word “dot” did not merely output the number; <strong>it made a decision about the number’s type.</strong></p>
<p>Then comes 123 D. as another exception.</p>
<p>Then 123 U.R — another one.</p>
<p>Then 123 D.R — yet another exception.</p>
<p>Now imagine that tomorrow we need:</p>
<ul>
<li><p>output in HEX;</p>
</li>
<li><p>output with leading zeros;</p>
</li>
<li><p>output with thousands separators;</p>
</li>
<li><p>fixed-point output.</p>
</li>
</ul>
<p>Where do we add them? In the end, this becomes a path of endless exceptions.</p>
<p>Now consider the proper model. Separate the concepts. A number is a number. The representation of a number is a format. Output is output.</p>
<p>In the new model:</p>
<pre><code class="language-plaintext">: U.R ( u width -- )
    &gt;R
    10 FORMAT
    R&gt; WIDTH RIGHT
    TYPE
;
</code></pre>
<p>In other words, U.R is not a fundamental mechanism. It is simply a convenient combination.</p>
<p>And here a question arises: “Should the word U.R be part of the language, or is it simply the first convenient program written by a user?”</p>
<p>Taking this further, the question becomes: “What should be in the core, and what should belong to the layer of convenient extensions?”</p>
<p>A small combine harvester is a useful thing, but no sane person would think of building a combine harvester into a hammer.</p>
<p>And now the answer to the questions we have asked is this: “The core should contain not a combine harvester, but several simple mechanisms.”</p>
<p>And where should the “combine harvesters” that Forthers have long been accustomed to live? They should live in a special set of words containing canonical recipes, called <code>PATTERNS</code>. Strictly speaking, it would be more appropriate to call this set of words <code>IDIOMS</code>. An idiom is not only a linguistic term; it is also a programming term. An idiom is an established way of solving a problem using the means provided by a language. But since most programmers are often simply technicians, the term <code>PATTERNS</code> may be more suitable for them.</p>
<p>Here are the ready-made recipes from <code>PATTERNS</code>:</p>
<p><code>. U. D. U.R D.R .</code></p>
<p>These are not language primitives. They are canonical examples of dictionary extensions. And now for the most important point: <strong>we are not banning short words; we are proposing that combine harvesters should not be part of the core.</strong> In other words, we are not removing convenient words. We are removing the need to know dozens of special cases.</p>
<p>In the wrong model, every new need gives rise to a new word. In the right model, the combination of <code>VALUE + FORMAT + OPTIONS + OUTPUT</code> covers everything.</p>
<p>In fact, we are not arguing about the size of the dictionary, nor are we arguing about syntax or compatibility. We are asking just one question about every word:</p>
<p><strong>“Does this word add a new semantic concept, or does it merely fix one of the combinations of concepts that already exist?”</strong></p>
<p>If it is the latter, then it is a candidate for <code>PATTERNS</code>, not for <code>CORE</code>.</p>
<p>But this raises the next architectural question. If historical words are merely combinations of more fundamental operations, then we must have a clear understanding of exactly what those operations combine.</p>
<p>We need to identify the object being transformed: the numeric value has already been determined, but how should it be represented in textual form?</p>
<p>This is fundamentally different from interpreting the number itself. For example, a sequence of bits can be interpreted as a signed or unsigned value. This is a question of the semantics of the value. But once the value has been unambiguously determined, it can be represented in different bases, with different alphabets, and in different forms. This is already a question of representation policy.</p>
<p>This is where the architectural concept of <code>Notation</code> appears—not as yet another special word for outputting a number, but as a way of describing the rules by which a numeric value is transformed into a textual representation.</p>
<p>It is more natural to implement this concept not necessarily as a separate object on the user stack, but as a <strong>representation policy</strong> used by the number-conversion mechanism called <code>REPRESENT</code>. The concept of <code>Notation</code> is used to denote this policy.</p>
<p><code>Notation</code> describes exactly how a value should be represented: in which base, in what form, using which alphabet, and with what precision. A concrete machine representation of such a policy can be compactly encoded in a descriptor. Thus, <code>Notation</code> is an architectural concept, while a descriptor is its concrete representation, convenient for passing and processing.</p>
<p>This makes it possible to separate the representation policy itself from the numeric value and from the mechanism that outputs it. At the same time, <code>Notation</code> does not have to be a separate language object: what matters is not where the policy is physically stored, but that it becomes an explicit and orthogonal level of semantics.</p>
<p>An approximate orthogonal model looks like this:</p>
<pre><code class="language-plaintext">NUMERIC VALUE
│
│ interpretation
▼
REPRESENTATION POLICY
│
├── RADIX
├── POINT
├── ALPHABET
└── PRECISION
│
▼
REPRESENT
│
▼
TEXT REPRESENTATION
</code></pre>
<p><code>SIGNED/UNSIGNED</code> are deliberately not properties of the representation policy here. They determine the interpretation of the numeric value, not the way it is represented as text.</p>
<p>Thus, instead of a multitude of special-purpose words, we obtain a small orthogonal model of representation policy. It describes not a specific output operation, but the independent properties of how a value is to be represented. Various representation algorithms and different methods of subsequent output can then be built on top of it.</p>
<p>We are not claiming that this is the final <code>REPRESENT</code> API. At the same time, we have not merely assembled a convenient descriptor. We have applied the following criterion:</p>
<p>“If changing a parameter changes the mathematical value, it is not a representation parameter. If the value has already been determined and the parameter can be changed without changing that value, it is a candidate for the representation policy.”</p>
<p>A complete description of this model, including the specific structure of the representation policy, the <code>REPRESENT</code> algorithms, and their implementation, is beyond the scope of this article. What matters here is to establish the architectural principle itself: <strong>the value, its representation, and its output are different levels of semantics.</strong></p>
<p>If some newcomers to programming find parts of the above unclear, then let’s start with the basics: get acquainted with the term “orthogonality.” This is one of the fundamentals of modern programming, and it is well worth getting to grips with. The trouble with Forth today is that its standardization committee is made up of poorly qualified programmers who cannot even command terminology at the level of language architecture.</p>
<p>As a developer who implemented my own Forth many years ago and has now undertaken a new implementation, I can see all the shortcomings of the current standard. What was forgivable in the 1994 standard, where some words were retained for compatibility, became a crime in the 2012 standard, which incorporated all of the previous shortcomings. There are so many flaws in the current standard that I cannot confidently say I will be able to finish my project, because I have to shoehorn myself into the nonsense on which the standard is based.</p>
<p>I have read the criticism directed at me following the first article. For example, there was the issue of the <code>&gt;IN</code> word, which is supposedly used in application programs. First of all, let us define what we mean by application programs. Modern languages and ecosystems allow application programmers to work at a high level of abstraction without directly interacting with most of the details of program execution. Second, in my first article I briefly mentioned an implementation of the input stream as a separate stack, operating through an Input Source Frame (called different things in different implementations). Here again, the standards committee lumped everything together, leaving words that belong closer to the interpreter’s internal workings for users to deal with. Is that not why there are so few user applications written in Forth worldwide—that the standard itself is fundamentally unattractive for application development? And if the committee standardizes the <strong>internals of the input stream as part of its public interface</strong>, then that is a problem with the committee, not with the programming language.</p>
<p>The other issue is that the wrong tool has produced the wrong way of thinking in some of its users. Yes, they like such a tool, and they say so: “I like it.” But the problem is that such users are not the driving force behind Forth. What is more, they are destroying Forth, because the programming language has become unattractive to the global community and has turned into a tool for <strong>outcasts</strong>. And that is already a separate subject, beyond the scope of programming. Paraphrasing a well-known saying about sports, one might put it this way: <strong>“They do not love Forth in themselves; they love themselves in Forth.”</strong> If Forth did not exist, they would find another wrong tool and praise it to the skies, because they like wrongness in themselves. Guys, this is beginning to smell like some kind of cult.</p>
<p>All right, one could still argue about the word &gt;IN, but another example is the word BASE. Let us return once again to the subject of language architecture. Let us decide <strong>what we should be putting on the stack</strong>. The word <code>BASE</code> leaves an address on the stack. Now ask yourself: does the user need to see this address, for example, through the word <code>.S</code>? Consider the absurdity of the following combination:</p>
<pre><code class="language-plaintext">BASE .S @
</code></pre>
<p>Can you imagine the user needing to see the address of the current number base on the stack? No, of course not. And why? Because the address on the stack is an intermediate link that nobody is interested in: immediately after using <code>BASE</code>, one uses either <code>@</code> or <code>!</code>. And if an address is an intermediate state, it has no business being on the stack.</p>
<p>So what is the word <code>BASE</code> doing in the <code>CORE</code> word set in its current form? The question is rhetorical, because it is there like a scarecrow in a garden. This is an architectural flaw in the <code>BASE</code> interface.</p>
<p>Such <strong>exposed internals</strong> scare away any potential newcomers who could become the foundation of the Forth community. Instead, our programming language looks like a piece of junk to the entire global community. It is astonishing that the cultists boast about using a two-word combination instead of a single word that could immediately return the current number base to the stack. This is what a bad standard does: it raises a generation of programmers with distorted thinking.</p>
<p>Some people, of course, are already accustomed to working through the BASE @ combination, but that is because they were taught from the very beginning to take the scenic route. There is a nice ironic idiom in English for this: “to take the scenic route” — literally, to go the long way around. And that is exactly what they do: they go the long way around instead of taking the straight road.</p>
<p>Architecture runs throughout this article, and for me, the science of design as applied to Forth conjures up the physical image of an abandoned building somewhere on the outskirts of town. That building is run by a horde of street urchins led by a small-time prima donna. And if Forthers do not want to look like a marginalized group in the modern world, they need to stop clustering around that architectural structure, patched and repatched because it was fundamentally misdesigned from the outset.</p>
<p>As for the standardization committee, there is a familiar saying that has become a catchphrase: “You can take the boy out of the country, but you can’t take the country out of the boy.”</p>
]]></content:encoded></item><item><title><![CDATA[Changes to the Standard, or, How Europe's Bush-Leaguers Murder Forth]]></title><description><![CDATA[Programming language success is determined not only by the language itself, but also by its ecosystem—the availability of good IDEs, debuggers, libraries, and other development tools. Against this bac]]></description><link>https://forth203x.hashnode.dev/changes-to-the-standard-or-how-europe-s-bush-leaguers-murder-forth</link><guid isPermaLink="true">https://forth203x.hashnode.dev/changes-to-the-standard-or-how-europe-s-bush-leaguers-murder-forth</guid><dc:creator><![CDATA[Pure Forth]]></dc:creator><pubDate>Sat, 01 Aug 2026 14:45:48 GMT</pubDate><content:encoded><![CDATA[<p>Programming language success is determined not only by the language itself, but also by its ecosystem—the availability of good IDEs, debuggers, libraries, and other development tools. Against this backdrop, Forth has been steadily losing ground, even in the embedded domain that was once its natural home.</p>
<p>In my view, the problem is not just the technological revolution. It is also the gradual degradation of the Forth standard. Since 2012, the standards committee has made no meaningful progress in improving the language architecture, making Forth less attractive to potential programmers.</p>
<p>Under the pseudonym AbstractionFirst, I submitted a number of proposals to the standards committee. They did not even understand what the discussion was really about. Let's examine the issue step by step.</p>
<p>Today, Forth looks as if its guts are hanging out—its internal implementation mechanisms are exposed where a proper language interface should present well-designed abstractions.</p>
<p>First, the word BASE.</p>
<p>The API of BASE is poorly designed: it is exposed as the address of a variable. Why does the standard still expose the numeric base as the address of a mutable memory cell, instead of standardizing operations for reading and modifying this property?</p>
<p>The standard has standardized the implementation rather than the contract. What would the ideal design look like? It should follow a well-known API design principle: specify observable behavior, not the internal representation of state.</p>
<p>Every standard word should describe either the observable behavior of the language or a fundamental semantic capability—not the specific organization of an implementation's internal state.</p>
<p>At this point, there is no need to reduce the discussion to the question of what word should replace BASE. The more important point is this: the standard should not expose the representation of a language property as the address of a variable. It should standardize the operations on that property while leaving their implementation entirely up to the system.</p>
<p>I do have concrete proposals as well. One possible approach would be to use VALUE and TO.</p>
<p>The first person to respond to my proposal on forth-standard.org was a user under the pseudonym ruv. At first, he seemed to make a sensible suggestion by proposing the words RADIX and SET-RADIX. However, he concluded his comment with the rather strange remark that generating an exception through TO would be difficult. I found that statement quite puzzling.</p>
<p>In the context of BASE, where one numeric value is simply replaced with another, the idea of trapping an exception seems out of place. It gives the impression that ruv either had not fully thought through his response or was arguing merely for the sake of argument.</p>
<p>What a program actually needs is access to the current numeric base—not to the address of the memory cell where that value happens to be stored. This is the key point. In other words, VALUE was merely an example of a possible direction for the language to evolve, not the subject of the discussion itself. In fact, my proposal to the committee was about the architecture of the language rather than the name of a particular word.</p>
<p>The next response came from the committee chairman, Anton Ertl. His comment clearly carried an irritated tone. Let me say right away that, in my opinion, this is unprofessional. Fine. If Chairman Ertl chooses to engage on an emotional level, then I will respond in kind. All of my comments submitted to the committee were restrained and focused on technical substance. This article, however, is written at the level Ertl seems to understand better.</p>
<p>Incidentally, just like ruv, Ertl also failed to understand what the discussion was really about. My proposal was not merely about implementation mechanisms—it was about the proper architecture of Forth as a whole. But even if we focus on the details, I find his argument that "the proponents have not demonstrated why this is actually a problem" rather strange. It immediately raises a question: has Anton Ertl ever written a single line of assembly language himself, or does he merely supervise the Gforth project?</p>
<p>Today, the word BASE is never used by itself. It always appears as either BASE ! or BASE @. In threaded code, that means two operations instead of one. In other words, using BASE is twice as slow and produces twice as much code. As the author of my own Forth implementation, I know this very well. BASE is not only a user variable; it is also used by &gt;NUMBER, which in turn is part of the Forth engine itself. In other words, BASE has become a performance bottleneck in the language.</p>
<p>Instead of introducing VALUE, another possibility would be to merge the pairs BASE ! and BASE @ into single words: BASE! and BASE@. Code portability would not suffer significantly—provided there is a reasonable willingness to evolve. Better yet, the standard should embrace the following principle:</p>
<p>“Backward compatibility is not an absolute value if it stands in the way of architectural improvement”.</p>
<p>Arguments that replacing one word (BASE) with two (BASE! and BASE@) somehow makes the language worse are not, in my opinion, a serious basis for discussion. The current standard already contains words that could reasonably be declared obsolete, just as was once done with TIB, #TIB, QUERY, EXPECT, SPAN, and CONVERT.</p>
<p>Some words do not necessarily need to be removed from the standard. It is enough to move them into a secondary role. And that brings us naturally to the second part of the discussion.</p>
<p>Second, the words CMOVE&gt; and CMOVE.</p>
<p>Neither of them has any right to be in the STRING word set. Both words are inherently unsafe. There is already a reliable alternative—MOVE—that does not suffer from these shortcomings.</p>
<p>The only place where CMOVE&gt; and CMOVE can be justified is in embedded systems, where every byte matters. Therefore, I propose that the next revision of the standard introduce a separate EMBEDDED word set and move into it all words whose existence is justified solely by the need for compact implementations.</p>
<p>That said, given the amount of memory available in modern microcontrollers, even the need for a dedicated EMBEDDED word set remains an open question.</p>
<p>Third, the words SAVE-INPUT and RESTORE-INPUT from the CORE EXT word set.</p>
<p>The standard has conflated two different layers of Forth: one intended for implementers and one intended for users. Users should be exposed only to abstractions that are natural within their problem domain. For most Forth programmers, that domain consists of the stack, the dictionary, numbers, strings, and files—not the internal state of the text interpreter.</p>
<p>This raises an obvious question: why are SAVE-INPUT and RESTORE-INPUT placed in the same namespace as ordinary application words?</p>
<p>Let me repeat: the standard has mixed together two different interfaces:</p>
<ul>
<li><p>the API for writing application programs;</p>
</li>
<li><p>the API for implementing Forth itself and tools tightly integrated with the interpreter.</p>
</li>
</ul>
<p>This reveals a troubling symptom. A language standard is normally expected to standardize observable behavior rather than implementation mechanisms. In this case, however, standardizing such words begins to dictate the architecture of the implementation, limiting the design freedom of Forth system implementers. If we follow this principle consistently, the standard should avoid prescribing internal implementation mechanisms even within the mandatory CORE word set.</p>
<p>Let me explain this in more detail for those who may not yet see the distinction.</p>
<p>There are language users, and there are compiler and system implementers. These are different roles. Historically, Forth has often combined them, but that alone does not imply that every internal mechanism should be standardized.</p>
<p>Language users need words such as EVALUATE, POSTPONE, IMMEDIATE, and INCLUDE-FILE. The existence of SAVE-INPUT and RESTORE-INPUT, on the other hand, reflects one particular model of how the interpreter is organized internally.</p>
<p>Let me be more precise: not every implementation-related word imposes an implementation strategy. For example, POSTPONE has a profound influence on compiler design, yet it expresses language semantics. Without it, a certain class of portable programs simply cannot be expressed. SAVE-INPUT, however, does not introduce new language semantics. Instead, it describes one particular way of organizing the interpreter's internal state. That is the fundamental difference.</p>
<p>I would summarize the principle as follows:</p>
<p>"If a word exists primarily to support a particular implementation architecture rather than to express the portable semantics of application programs or language extension tools, then standardizing that word begins to restrict implementation freedom".</p>
<p>The same idea can be expressed as a simple question:</p>
<p>"If a mechanism exists primarily for the implementer, why is it standardized as part of the language's user interface?"</p>
<p>Once again, the first response on forth-standard.org came from ruv. His reply makes it clear that he completely missed the point of my questions. My concern was never the quality of the API itself—it was the level of abstraction. His response barely addressed the architectural question I had raised and therefore missed the central point entirely.</p>
<p>Anton Ertl replied once again, and once again he failed to grasp the essence of the questions I was raising. I was talking about the form of the public interface, while he was talking about the many possible internal implementation algorithms.</p>
<p>I also cannot help pointing out once again that the committee chairman's response fell short of professional standards. If you read his reply carefully, you will notice how dismissively he spoke about certain Forth implementations, effectively placing them into a category of useless systems. In my view, that was a remarkably arrogant remark toward Forth implementers who invested their time and effort in creating their implementations.</p>
<p>Looking ahead for a moment, if we set aside the emotional aspect of the discussion, I am left with the impression that my opponents on forth-standard.org simply do not possess the conceptual vocabulary needed to discuss the questions I was raising. As a result, they never really understood what I meant.</p>
<p>Later, Ertl posted another reply, but once again the subject of the discussion shifted. I never asked whether SAVE-INPUT was well designed or well implemented. My question was different: by what principles should we decide which words belong in the standard interface at all? That is a question about the architecture of the standard—not about the quality of individual words.</p>
<p>The weakest part of his argument is the absence of any general principle. Instead, he evaluates words one by one:</p>
<ul>
<li><p>Is it convenient?</p>
</li>
<li><p>Is it efficient?</p>
</li>
<li><p>Is it portable?</p>
</li>
<li><p>Is it easy to implement?</p>
</li>
</ul>
<p>But he never answers the more fundamental question: "Should this word be part of the public interface of the standard in the first place?" I asked that question repeatedly in several consecutive comments on forth-standard.org.</p>
<p>I keep catching myself thinking the same thing over and over again: I am trying to discuss the rule, while most of the replies are busy discussing exceptions to the rule. I say, "Let's first establish the principle." They reply, "Well, SAVE-INPUT can be used like this..." Honestly, it leaves me with the feeling that I am talking to children. The committee members seem unable to think at the level of language architecture. It is simply not the level at which they approach these questions.</p>
<p>A little later, another user, pda, joined the discussion. His response was yet another childish argument based on conflating two distinct concepts. My response is straightforward. Forth has never prohibited programmers from working at a low level. But the language standard is a completely different matter. Its purpose is to define what should be portable. These are two different planes of discussion. The philosophy of "hide nothing" belongs to the capabilities of the language. It does not determine the obligations of the language standard.</p>
<p>In reality, SAVE-INPUT and RESTORE-INPUT are only the beginning of a much larger discussion—one about introducing a new word set into the standard. And that naturally brings us to the fourth and final part of this article.</p>
<p>Fourth, words such as &gt;IN, SOURCE, REFILL, as well as SAVE-INPUT and RESTORE-INPUT, should be moved into a separate word set intended exclusively for implementers. Possible names include INTERPRETER, IMPLEMENTATION, SYSTEM, or ENGINE.</p>
<p>The rationale can be stated as follows:</p>
<p>"Words intended primarily to support the implementation of the text interpreter should be separated into their own word set rather than being part of the interface for portable application programs."</p>
<p>This is a question of the structure of the standard. It does not change the semantics of those words in any way.</p>
<p>The second architectural idea can be stated as follows: "Even if such words remain standardized, their specification should define only their observable behavior rather than forcing implementers toward a particular internal model."</p>
<p>And this principle is not limited to SAVE-INPUT. It applies to any word in the language.</p>
<p>Anton Ertl responded almost immediately to my comment. In my opinion, at that point he crossed the line into disingenuous argument by claiming that the words I had listed are used by application programs. Let him produce a single convincing example. I would genuinely be interested to see what kind of extraordinary application he has in mind. As someone who has developed Forth systems and has also written Forth applications, I find it difficult to imagine why an application program would need to manipulate the Forth input stream directly.</p>
<p>Then ruv swooped in, declared that the issues being raised were off-topic, and closed the discussion. As far as I'm concerned, that tells me everything I need to know about them. They are incapable of engaging in a reasoned discussion, which is why they do not even suggest an alternative venue where these issues could be debated.</p>
<p>By the way, if we dig deeper into the subject, the word set intended for Forth implementers should include not only SOURCE-ID, but also QUIT. A Forth user writing application programs does not necessarily need to know how exactly the engine of a particular implementation works internally inside the word QUIT. Of course, they may know how everything is arranged purely for general education, but in application programming the word QUIT will not be needed.</p>
<p>As someone who has developed Forth implementations, I will say more: some words such as &gt;IN, SOURCE, and SOURCE-ID have turned out to be unnecessary interfaces. Forth implementers do not need them as a standardized interface, because the standard itself has pushed them toward implementing the input stream as a separate stack, with its fields accessed directly. And Forth users do not use those words either, because they are not part of the application programming level. In other words, those words have become an unnecessary layer, needed by nobody. Yet the standard imposes them. Oh, what an architectural mistake! If we follow the proper path, the words &gt;IN, SOURCE, and SOURCE-ID should be the next candidates for removal from the standard, following TIB, #TIB, QUERY, EXPECT, SPAN, and CONVERT. In turn, the standard should not dictate to implementers through which variables words such as REFILL must be implemented. This is the proper level of abstraction.</p>
<p>To conclude, let me summarize.</p>
<p>I am not proposing to deprive programmers of access to Forth’s internal mechanisms. I am proposing that these tools should not be hidden, but properly organized. All tools should remain available, but each should have its own place. The quality of the tools themselves is a separate question. For example, in my view, BASE demonstrates an inadequate level of abstraction, but that is a different issue.</p>
<p>The members of the standardization committee simply do not possess the expertise required to reason about the language at the architectural level. They remind me of a village tractor mechanic who knows every bolt on his machine and exactly which wrench to use to keep it running. But they are incapable of rising to a higher level of abstraction and understanding what kinds of tractors should be designed for the modern world so that agricultural work can be done efficiently.</p>
<p>Today, Forth looks like an untidy child whose guts are hanging out. That should not come as a surprise. Its parents resemble overgrown children who were never taught to put their toys back into the box. If, year after year, you keep throwing tools, toys, and dishes into the same cupboard, eventually the mess begins to look normal. So, guys, don't expect EuroForth to deliver anything worth your time in the coming years. It’s all down to us.</p>
<p>Appendix: Discussion Screenshots.</p>
<p>The screenshots below are included to allow readers to judge the discussion firsthand.</p>
<p>Discussion for BASE — Screenshot 1</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a6dfde10c91fb366aa039af/4a93fad9-35c3-4bde-b873-defa9548d736.png" alt="Discussion for BASE — Screenshot  1" style="display:block;margin:0 auto" />

<p>Discussion for BASE — Screenshot 2</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a6dfde10c91fb366aa039af/a81d356b-d1e3-4d63-90c8-427e73115032.png" alt="Discussion for BASE — Screenshot 2" style="display:block;margin:0 auto" />

<p>Discussion for BASE — Screenshot 3</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a6dfde10c91fb366aa039af/46ec927b-fad9-4d24-8715-cd4c6c18a6f0.png" alt="Discussion for BASE — Screenshot 3" style="display:block;margin:0 auto" />

<p>Discussion for SAVE-INPUT — Screenshot 1</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a6dfde10c91fb366aa039af/2cd0a47f-3ac5-4742-95bf-36295702e067.png" alt="Discussion for SAVE-INPUT — Screenshot 1" style="display:block;margin:0 auto" />

<p>Discussion for SAVE-INPUT — Screenshot 2</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a6dfde10c91fb366aa039af/bb508a65-91cd-430c-bf93-0b7fc9e4bf9c.png" alt="Discussion for SAVE-INPUT — Screenshot 2" style="display:block;margin:0 auto" />

<p>Discussion for SAVE-INPUT — Screenshot 3</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a6dfde10c91fb366aa039af/538b052c-9d8e-4c34-bfcf-5ba02dd33403.png" alt="Discussion for SAVE-INPUT — Screenshot 3" style="display:block;margin:0 auto" />

<p>Discussion for SAVE-INPUT — Screenshot 4</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a6dfde10c91fb366aa039af/ee2abf73-71f4-4d27-88e3-040457edb23f.png" alt="Discussion for SAVE-INPUT — Screenshot 4" style="display:block;margin:0 auto" />

<p>Discussion for SAVE-INPUT — Screenshot 5</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a6dfde10c91fb366aa039af/37a55489-3513-4f9f-ad19-9df71faf93da.png" alt="Discussion for SAVE-INPUT — Screenshot 5" style="display:block;margin:0 auto" />

<p>Discussion for SAVE-INPUT — Screenshot 6</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a6dfde10c91fb366aa039af/54175f7a-5e7a-4891-9bca-8114e4af887a.png" alt="Discussion for SAVE-INPUT — Screenshot 6" style="display:block;margin:0 auto" />

<p>Discussion for SAVE-INPUT — Screenshot 7</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a6dfde10c91fb366aa039af/f95b95f9-d69a-485f-8881-a0650be8c3dd.png" alt="Discussion for SAVE-INPUT — Screenshot 7" style="display:block;margin:0 auto" />

<p>Discussion for &gt;IN — Screenshot 1</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a6dfde10c91fb366aa039af/173a3d4a-75ff-4b01-a4fa-3b13d2bb3302.png" alt="Discussion for &gt;IN — Screenshot 1" style="display:block;margin:0 auto" />

<p>Discussion for &gt;IN — Screenshot</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a6dfde10c91fb366aa039af/04e5c787-12ba-475f-86e4-cc5784854f20.png" alt="Discussion for &gt;IN — Screenshot 2" style="display:block;margin:0 auto" />]]></content:encoded></item></channel></rss>