Examples
Essentials
You might notice the lack of quotation marks on the arguments, which are the parenthesized parts of commands: Hello, world!
(the only one in the first program), A
, and B
. This is because Ė does not make a distinction between names (variables) and literal values in the usual way. We will come back to this.
Otherwise, these two are self-explanatory:
Loops ex machina
Here, we might want to imagine breaking up write(A) write(B) write(A)
into two bigrams: write(A) write(B)
, and write(B) write(A)
. They independently describe the permitted courses of action for the program (here, two of them: “B after A“ and “A after B”), but do not otherwise interact, hence the loop:
Use a modifying apostrophe '
to turn the write(A)
s into to two distinct commands. This prevents the loop, but the write(A)
commands are still identically behaved, by virtue of invoking the same action:
Expecting failure
An action can result in success or failure.
Note that the standard library’s read()
is unusually literal-minded. It must know in advance what has to be read:
1) read(Something to be read.)
All of them produced failing outcomes.
Cool! I won't tell anyone. :)
1) read(yes)
All of them produced failing outcomes.
Reacting to different outcomes
Before tackling the next program, let’s reiterate the bigram-related semantics of Ė.
On each line, commands (each referring to an action) inevitably follow one another. Let’s say that a line contains X Y, two hypothetical commands, juxtaposed. Ė takes it to mean that anytime an X is done, following up with a Y is a permitted course of action.
In fact, the order of commands bears no other meaning than that.
For lines, the order is even less relevant. It serves merely to introduce priorities when two conflicting courses of action are possible.
Concretely, the program knows two ways of proceeding after a write(Well, do you? )
. First, it tries read(yes)
and fails, and because of that, it tries read(no)
next.
write(Well, do you? ) read(no) write(Dear diary, I guess an interrogator's job is just not for me.)
Dear diary, I guess an interrogator's job is just not for me.
To avoid typing write(Well, do you? )
or an even longer string all over again, as we did above, we can splice in another command, like -r
.
Any command that starts with a hyphen (the default “dash” character) is perfectly valid, but does nothing on its own, in order to serve this “pivoting” purpose.
-r read(yes) write(Who doesn't, though?)
-r read(no) write(You might want to try it.)
You might want to try it.
Negotiation
Variables and literal values are not distinguished in Ė.
One can, but need not, also construe it this way: all word-like tokens are variables, but they come pre-initialized to themselves, that is, their names.
In the following, this pre-initialization is just passively maintained, which is why all tokens will behave as literal values:
3 might or might not be a number.
1) read(3)
All of them produced failing outcomes.
Now, we place an asterisk before read(3)
, so that it spells *read(3)
.
This tells the read
action not to fail early, but to “try harder”, in case negotiating the token 3
would allow it to succeed.
Negotiating 3
to XXI means that as the program proceeds, 3
ceases to mean 3, and starts meaning XXI instead:
XXI might or might not be a number.
In a way, everything is a variable here, or, rather, a negotiable.
However, new negotiations are never made if there is no asterisk. Also, to be negotiable, a token has to start with a capital letter, or to be numeric.
This dog thing, it might or might not be a number.
A token is never negotiated to a non-token, such as a (space-separated) sequence of tokens:
1) *read(Thing)
All of them produced failing outcomes.
When negotiable tokens have numbers in them (like Chapter1
, Chapter2
), arranging such tokens in pairs or longer sequences will exhibit some additional specifics of behavior. Specifically, that happens when the tokens are otherwise identical (as in Chapter
, plus a number), except for the numbers (as in 1
and 2
).
The sequences are automatically shortened or lengthened to make the negotiation possible, and the upper bound number (here: 3) is negotiated as well:
While "a fierce pack of exactly one dog" is correct, your time was already up. Sorry.
You put it in 1 word(s). Try fewer.
Grouping multiple tokens with balanced parentheses ()
, square brackets []
or curly brackets {}
turns them into a single token, which has sub-tokens:
(be dragons) + there = ???
Standard library
The highly preliminary standard library can read, write, spell, split, pick, calculate, interpret, (check if the tokens in the argument are) all-equal, (check if a date/time string holds) now, (check if a number is) round. Note that if we add an asterisk, “checking if X” comes to mean “making necessary negotiations so that X”.
The examples below illustrate the behavior of some of the actions. First, spell
and all-equal
:
We lost the original, so from now on it will be B, repeated 7 times. Thank you.
1) all-equal(L1 L2 L3)
All of them produced failing outcomes.
If one need not report a number like the 7 in “repeated 7 times”, then the following also accomplishes the above task. It makes use of the fact that *spell(Alphabet -> L L L)
cannot negotiate the repeated L
tokens to different values.
Also, spell
, as well as some other actions, will scan the tokens in their arguments left-to-right, oblivious to anything past the previous token, in the same way that commands are treated in an Ė program. Consequently, -> L L L
means the same as, say, -> L L L L L
.
We lost the original, so from now on it will be Z, any number of identical copies of Z, in any order. Thank you.
Oh, the memories. I was particularly fond of 8.
For completeness, we bring loops back into the picture, as well as introduce calculate
:
Recall that -dash-commands
are always valid, and always do nothing. This way, we can split up the program into lines easier:
-gonna-make-it calculate(1950 < 2020) *calculate(1950 + 1 -> 1950) write(1950 )
-gonna-make-it write(I'm home!)
It might be worth noting that now(2020)
is the same as *now(2020)
, as long as it is still 2020. Past that date, only the “asterized” version will succeed, and will negotiate 2020
to actually mean the present year.
It's likely that you were born in 1932.
And that is it. Thank you for your interest!
This is the Ė interpreter. (Open a blank interpreter window.) Version 0.1.5 by Ignas Rudaitis, 2020-2021 Enter a program, then push Ctrl + Enter (or the preceding link) to run. Use Escape to stop one that is running.