Herein, macros seem to be invented from first principles, having only been exposed to imperative languages like C++. It is interesting to see macros here invented in the context of a language that is not homoiconic. I wonder how it stacks up against Rust macros.
"What is homoiconicity then? Typical definitions state that it is simply “code as data”, will point to a relationship between a program’s structure and syntax or note that the program source is expressed in a primitive data-type of the language. In the below, we will show that none of these definitions make much sense."
// If-then-else statement
if [[true]] then True else False is True
if [[false]] then True else False is False
if [[true]] then True is True
if [[false]] then True is false
// Loops
while Condition loop Body is
if Condition then
Body
while Condition loop Body
until Condition loop Body is { while not Condition loop Body }
loop Body is { Body; loop Body }
for Var in Low..High loop Body is
Var := Low
while Var < High loop
Body
Var := Var + 1
Is Forth really homoiconic? I’m asking as a recent fan of Forth. I would’ve thought to describe it as having strong, interactive metaprogramming but not necessarily homoiconic. Unless ‘code = data, data = code’ because they’re all bytes… haha.
Postscript would count as homoiconic, I’d think. Though I haven’t actually seen programs that so this.
I think Forth counts, in a "Turing-complete" sense of homoiconicity. A Forth program in a classic indirect threaded system can self-modify, reach in and change core interpreter words during execution. But it isn't obeying any formal soundness principle, since it's just a thin layer over the machine.
Compiled Forths might opt to wall off some of those options behind the compiler interface, in effect making the language slightly less far-reaching.
I could see that. Which I guess would put assembly into the homoiconic bucket. I think it fits the concept but sure isn’t the same as what people think of with Lisp, etc… lol.
Had this discussion on Discord as well. Like most things Forth it depends how you use it. If we consider the classic indirect threaded systems, then every field in a definition is an address called an execution token (XT). In most systems you can convert an XT back into a text label. This allows pretty simple de-compiling for example.
It is trivial to collect those Xts as data and execute them later.
CREATE XT-LIST ] THESE WORDS COULD BE FORTH CODE [
XT-LIST now contains six XTs. They can now be read one XT at a time and executed.
So if one accepts that those XTs are data, BUT they are also code since they can be "executed" by the Forth VM then I think we can say Forth is homoiconic.
However if that doesn't suffice it is perfectly legal to pass text strings to EVALUATE.
: TEST S" THESE WORDS COULD BE FORTH CODE" EVALUATE ;
Aha, that’s pretty awesome. I’m familiar with XT’s but hadn’t thought of using them that way. And didn’t know that you can convert back to text.
I’m going to have to do more Forth. And I have a sudden urge to go write some silly self-modifying assembly, if current processors even allow that anymore.
Herein, macros seem to be invented from first principles, having only been exposed to imperative languages like C++. It is interesting to see macros here invented in the context of a language that is not homoiconic. I wonder how it stacks up against Rust macros.