Nowadays people — although maybe not everyone — imagine information processing as commands in memory, data in memory, and all of it stationary and unmoving, while the program counter moves and process command after command, the exception being jumps, and moves. I don't claim this is a complete description.
Now imagine a data stream that moves, which I will call the input worm, or Iworm. It passes through three types of "folks" for lack of a more descriptive word, each of which can modify the worm or send it home. I almost forgot! The worm initially starts out from its home, passes through the folks, and as mentioned some folks send it home.
The Iworm moves around until, well, until it feels bored. It feels bored when there is nothing left to do, and the program is finished for the day.
There are three kinds of folks, contrary to what Scout Finch would have you believe. The "Robber" or "Taker" folks, the "Giver" folks and finally the "Dealer" or "Trader" folks.
The Robber folks try to take from the Iworm, and if they manage to get their grubby mitts on something, they send the poor Iworm home crying. Otherwise, they don't do anything.
The Giver folks are very rare and are not found in every program. They always give something and thus may cause the program to continue forever. The Givers always send the Iworm back home.
The Dealer folks give the Iworm stuff when they can get what they want. They take always what they want and give the Iworm something in return, whatever they think is best for the Iworm. After they have what they wanted they always send the Iworm back home.
The Stuff could be termed "primes", which is what they are in FRACTRAN. In the mathematical world of Turing machines, there are an infinite number of distinct types of stuff. The stuff is the input, and the Iworm consists of it. What if there is no input, you ask, or all the stuff has been taken from the Iworm? Could there be an empty Iworm? It doesn't bear thinking about: we do not want it if the process is to work.
Input must consist of Stuff used in the world/program. If it is to be used it must be part of what the folks give, take or exchange.
The Stuff is explained further in the implementation section.
Of course, the program can be 2D, and even 3D or higher, but in the basic model we have only one dimension. That means one direction to go forward, the other dimension being straight home. When the Iworm reaches the end, it continues from the beginning. (Even though there is one direction, we are not limited to only five folks.)
I know syntax is widely hated, but it's used every day, so our language has to have some syntax in it.
The basic model requires symbols. All text processors support the classic top to bottom layout of a program. For this to work as imagined, we need a worm and a world for it.
The worm must also have a home (and only one home) in the world file or things will not be entirely satisfactory. I really needn't mention that. After all, you wouldn't put your sausage or your mustard in the... well, where it shouldn't be.
The implementation defines what symbols are allowed. If it isn't mentioned, suppose the O (which looks like a hole) is the Iworm's home. Then comes a newline and/or carriage return and a definition of the folks who the Iworm is going to meet first. A separator, which we'll call a "path" is required. On the left side is written what the Iworm should receive, while on the other side of the separator or "path" should be written what the Iworm should take home. Let us define the "path" or separator as II, for reasons that will become apparent.
Already we have two special symbols that the worm cannot consist of. They are special and cannot be Stuff, but the Iworm must only comprise stuff, so O and II can be neither a worm nor part of a worm.
The Iworm is defined in a worm file. The world is defined in a world file. The following would make a working world file.
At least, according to the specification up to now. But wait, why should one be forced to write @@@ when @3 is easier on the fingers? In fact, why bother with the old syntax at all? We'll make @@@ and $$ a syntax error. Thus the previous example is no longer a valid world file.
This would be a working world file.
To write @0 or @1 should also not be allowed, because they better be replaced with nothing and @, respectively. A collection of zero pears look identical to zero apples, but @0 does not look like $0. Why make things unnecessary difficult. Furthermore, there is no need to write @1 and so on. @ is long enough.
@4$ would make a working worm file while @@@@$1, @@$@@ and so on would not.
In the same vein, the following would also be a valid world file.
@3II$2 O II$
What if we had something to mark the end of the file? How about adding II on its own? After all, any folk who neither give nor take would not make sense here. It would unconditionally send the Iworm home, because it does not depend on the worm's content/stuff.
Now II can not be confused with I2 or I and so I can be used for Stuff and thus be part of an Iworm.
Wormholes! I want them, you like them, Star Trek likes them, so why not define them, but leave them out of our basic implementation so they are optional. There can be multiple holes in the world file Valid holes are O or O followed by a number, consisting of the digits 0-9, except O0 and O1, which I do not like for the aforementioned reasons.
However if you care to make an implementation where a world file contains something like OHappyDay, then OMyGod etc would be valid. It depends on what is considered a symbol.
It could be required to include where the folks send the worm. It could/should look like @3II$2O2 or perhaps in your implementation $1000IIU2OMyGod.
The Working Sample
O @3II$2 II Hey, there's room for comments down here!
So far only symbols can be of a single ASCII or Unicode character, depending on implementation. If we want more, we'll need to continue defining. We define ' as an indicator for larger symbols. A larger symbol consists of more than one character, is prefixed with ' and has to be followed with either ' or a valid number. Valid numbers consist of the digits 0-9 and may not start with zero. Also only 1 as a number is illegal and has to be replaced with '.
Thus 'hello' , 'hello2 and so on are valid larger symbols, but 'hello1 and 'hello0 are not. There needs to be a way to write ' which will be ''. For compatibility reasons this should be supported by all implementations.
The Cool Implementation
Allows graphical output. Stuff will be presented as graphical objects, like birds and bees, flowers and trees, dogs and fleas, and so on. There will be sound effects, blinking and other cool stuff from the early 2000s. Maybe also some cool error messages, animations and even also stereoscopic effects by adding the magic eye. Of course, larger symbols will be implemented.
The Full Fantasy Implementation
This is what you can expect from me. It will only implement basics, with only light commitment to the syntax, omitting most, if not all, syntax checks. You may find some comments like "its up to u" and others comments like, "you can add it ,if you really want". At least the code will not be too long and will not contain most of the unnecessary and unexplanatory, and even irritating, comments which you sometimes found in source code.
Details will be contained in the source code file of the F.F.I. such as how output will be dealt with, which was not even discussed anywhere on this page.
The language can be trivially reduced to Fractran, which should be obvious if you know its inspiration. It's Turing complete.
Just in case you aren't a genius programmer who can understand why this is similar to Fractran, let me explain one way that this language could be similar:
- In Fractran, the input number goes through a list of fractions. If one of the fractions results in a integer when multiplied by the input number, the input number is replaced with that integer and goes back to the beginning of the fraction list. If it reaches the end of the list, it halts.
- Pretend that the worm represents the input number in Fractran. Each string within the worm is a prime number, and the number behind each string represents the power of the number. The worm is the product of all these prime numbers.
- Pretend that each folk is actually a fraction, with the right side being the numerator (number on top) and the left side being the denominator (number underneath). The strings on either side of the folk are, once again, prime numbers being multiplied with each other. If there are no strings / prime numbers on one side, assume that side is 1.
- A robber is the same as 1/n for some number n in Fractran. The robber stealing the strings from the worm is the same as 1/n dividing the input number by n while multiplying it by 1, resulting in an integer due to "taking" some of the primes from it by division.
- Givers are the same as n/1, or multiplying the number by n, which always results in an integer.
- The end-of-file person (just II with nothing on either side) is the same as 1/1.
- Dealers are every other kind of fraction.
This assumes that:
- All of the folks always do the things they are supposed to do (no "may continue forever" or "if they manage to get... something").
- The folks do not gain the things they take or lose the things they give.
- The robbers / dealers only take things from the worm if they can take all of the things from the worm.
- The dealers give all they have to the worm just like the givers.
- The text to the left, which the worm "receives", is actually text that the worm retrieves from itself to give to the folk or something.
- The code halts once all of the folks have been queried if none of them change the worm instead of "continuing from the beginning".
- The folks don't modify the worm or send it home. They send the worm home if and only if they modify the worm.
Overall, a language similar to .mOdMoDwOrM can be trivially reduced to FRACTRAN, but the more complicated and loose the interpretation is - the more humanlike the folks are - the less it can be reduced to FRACTRAN.