Until seen in area
Realtalk statements typically represent the "current state of the world", such as an object being at a position. We also use (or abuse) statements to represent (much rarer) impulse-like events, such as a keyboard event or a wish for a side-effect such as printing. A claim about a keyboard event, for example, lasts for one tick, which is fine for handling within the local area. But to "send" the event to another area, an ordinary directed statement such as:
Claim [in area (area)] keyboard at address (address) emits event (event).
is unsuitable, because areas run asynchronously and have different ticks. You don't know how long to "hold" the statement so the recipient area sees it.
Instead, use this:
Remember [until seen in area (area)] keyboard at address (address) emits event (event).
The sender remembers that it is trying to send the statement. Once received, the claim appears in the recipient area for exactly one tick, after which it goes away and an acknowledgement is sent back. Upon receiving the acknowledgement, the sender automatically forgets the memory.
The Remember can be combined with some of the usual adverbial phrases:
Remember [transiently] [until seen in area (area)]...
Remember [locally] [until seen in area (area)]...
Remember [for (2) seconds] [until seen in area (area)]...
The latter gives up trying to send after 2 seconds, in case the recipient is unreachable.
I'm currently using [until seen in area] for making keyboards work across areas, and for making "Remember" and "Forget" work on web clients.
Ordered matches
You can now specify how you want your matches ordered:
With all /matches/ for /p/ has title /ascending title/, /p/ has page number /descending n/:
Your (matches) will be sorted by ascending title, and then by descending page number. (The priority is currently just left-to-right, because I don't have a good idea for syntax. Maybe something like "ascending-1", "descending-2"? Let me know if you have ideas.)
Ordering "with all" matches is generally useful.
You can also order "when" matches, which is only useful in the realm where time-ordering matters, such as events and side-effects:
Wish (you) runs command (command) at timestamp (next_timestamp()).
When /someone/ wishes (you) runs command /command/ at timestamp /ascending timestamp/ [converging with priority (-100)]:
During convergence, if there is a set of new matches for a rule, they will be evaluated in the specified order.
This is especially useful for sending events across areas, when you want to ensure that they are evaluated in the order produced, even if they are produced over multiple ticks of the sender:
-- sender
Remember [until seen in area (area)] event (e) happened at timestamp (next_timestamp()).
-- recipient
When event /e/ happened at timestamp /ascending timestamp/:
next_timestamp() returns a monotonically-increasing number (even across reboots) which is based on the clock time.
Implementation of [until seen in area]
This is based on a pattern that I used in memory syncing, where an area would "subscribe" to updates by making the claim:
Claim [in area (upstream_area)] area (your_area) is at revision (rev).
And then, in the upstream area:
When area (your_area) is at revision /rev/, area /downstream_area/ is at revision /downstream_rev/, downstream_rev < rev:
for p, text in revised_memories(downstream_rev+1, rev) do
Claim [in area (downstream_area)] (p) has memory text (text) at revision (rev).
end
End
I really like how "autonomous" this is. The downstream area simply claims to be at some revision number. When the upstream area sees a downstream area at a lower revision than its own, it simply claims what needs to be updated to get to its own revision. Once downstream receives the claims and updates its own revision claim, upstream's claims go away automatically. It can take as long as it needs to, and it's robust to either party going offline or rebooting anywhere. It feels very different than "message sending".
The implementation of [until seen in area] is basically the same pattern, using timestamps instead of revision numbers. This is it in its entirety: