(Last Updated 07/22/2017 , 18h20 ; See Below.)
When I was a child, I used to subscribe to a magazine called “Byte Magazine”. In it, every few months a different programming language was featured, each for several magazine issues, and each a language that had markedly different semantics. Among those languages were:
I do not really recall everything I read about some of the languages, such as about Pascal or Smalltalk. But certain languages stood out, among those LISP, FORTH and Prolog, and later in life, I studied C++ – which did not exist yet in those earlier years – in depth.
What I also learned, was that the way in which Byte ‘taught’ those languages was sometimes flawed, and I eventually saw no urgent need to hold on to the old magazines, say as souvenirs.
The sum-total of what I really learned from that magazine, about FORTH specifically, can be summarized in these two Web-articles:
What I noticed yesterday, was that when I install ‘GNU-ish Forth’ on one of my 64-bit Linux systems, the cells of data become 64-bit cells and not 32-bit cells, and the following code-snippet demonstrates that:
dirk@Klystron:~$ gforth Gforth 0.7.2, Copyright (C) 1995-2008 Free Software Foundation, Inc. Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license' Type `bye' to exit 1 cells . 8 ok bye dirk@Klystron:~$
The FORTH-word ‘
cells‘ multiplies its input by the (fixed) number of bytes each cell of data occupies, which is useful for computing byte-aligned addresses. The FORTH-word ‘
.‘ prints the top object on the stack, and consumes it.
This 64-bit and GNU support can actually stand in the way of using FORTH, as the language will sometimes be embedded into devices that only have very rudimentary CPUs. When embedded, the language has as main advantage, being able to carry out complex tasks with very compact code, and to do so very fast. But, in order really to be Linux-compatible, some of its low-level words have been redefined, to take into account the fact that busy-wait loops are not an acceptable form of I/O-control, and to take memory-management into account. When embedded, a 32-bit CPU is assumed at max that has no protected-memory features. Here, busy-wait loops are the way to go…
But of course, my interest in Forth has been awakened briefly, because I did read that it gets used in Bitcoin Script. One of the facts about a scripting language, that will generally make it different from mainstream programming languages, is that single instructions – in this case FORTH-words – can be made to stand for complex operations, that they would not stand for when the syntax is used in the programming language, which a scripting language was derived from. This goes beyond what an SDK does. I wanted to add a few words on that last detail.
In order to work as Bitcoin Script, FORTH needs to have single words, that also do complex things, such as:
- Decrypt the top item on the stack, using the second item as the public key, with the intention of generation a 256-bit Transaction-Hash.
- Hash the top item on the stack, with the intention of generating a public address, on the assumption that the input was a public key…
All the above words require a much-wider cell, or register-width, than 64-bit. And I can think of 3 hypothetical reasons, for which this would work:
- Each word to be used in Bitcoin Script could have been defined in FORTH itself, as subroutines and data-structures,
- Each word could exist as highly-optimized machine-language, written in Assembler,
- The server on which these transactions are processed, could be treating the FORTH-like words as a means of ‘Markup’, to denote what the transaction is supposed to do, but without actually executing them.
And yet, while running on servers with powerful (presumably 64-bit) CPUs, Bitcoin supports 4-byte integers. ( :1 )
In any case, it is not allowed for a subroutine-definition, or a data-structure definition, or a loop, to appear in a Transaction Script. This is only logical.
And as it stands, my interest in this subject are academic in nature, which makes me a very different animal, from people who might be deeply interested in Bitcoin mining, or other Bitcoin / money-related pursuits. To me, a hash-code is an accidental thing a computer is capable of generating as output, and of reusing as input. There exist numerous hashing algorithms, and the computer happens to be able to compute any of them.
To a person who is serious about mining, specialized hardware with hundreds of physical cores, has been optimized to execute one specific hashing-algorithm, hundreds of millions of times per second if not billions, as the main purpose for that device.
I find this twist in the evolution of Computing, ‘Stranger Than Strange’.
(Edit 07/18/2017 : )
If the reader truly wanted to embed FORTH, then the only way to go, would be to download the C source-code for the so-called ‘kernel’ (the bytecode interpreter), and cross-compile that for the embedded CPU. In principle, any portable version will do, but the following seems suitable: