10> Note: The last major revision of these sections was in 2016. They need to be rewritten: they're outdated in some respects, and also not always as clear as they could be. A rewrite is planned. There is still plenty of good information to be found, but don't bet the farm on anything you read here.
12Arvo is composed of modules called vanes:
16At a high level `%arvo` takes a mess of Unix I/O events and turns them
17into something clean and structured for the programmer.
19`%arvo` is designed to avoid the usual state of complex event networks:
20event spaghetti. We keep track of every event's cause so that we have a
21clear causal chain for every computation. At the bottom of every chain
22is a Unix I/O event, such as a network request, terminal input, file
23sync, or timer event. We push every step in the path the request takes
24onto the chain until we get to the terminal cause of the computation.
25Then we use this causal stack to route results back to the caller.
29The `%arvo` causal stack is called a `++duct`. This is represented
30simply as a list of paths, where each path represents a step in the
31causal chain. The first element in the path is the first letter of
32whichever vane handled that step in the computation, or the empty span
35Here's a duct that was recently observed in the wild:
39 /g/a/~zod/4_shell_terminal/u/time
40 /g/a/~zod/shell_terminal/u/child/4/main
41 /g/a/~zod/terminal/u/txt
47This is the duct the timer vane receives when "timer" sample app asks
48the timer vane to set a timer. This is also the duct over which the
49response is produced at the specified time. Unix sent a terminal
50keystroke event (enter), and Arvo routed it to `%dill` (our terminal),
51which passed it on to the `%gall` app terminal, which sent it to shell,
52its child, which created a new child (with process id 4), which on
53startup asked the timer vane to set a timer.
55The timer vane saves this duct, so that when the specified time arrives
56and Unix sends a wakeup event to the timer vane, it can produce the
57response on the same duct. This response is routed to the place we
58popped off the top of the duct, i.e. the time app. This app produces the
59text "ding", which falls down to the shell, which drops it through to
60the terminal. Terminal drops this down to dill, which converts it into
61an effect that Unix will recognize as a request to print "ding" to the
62screen. When dill produces this, the last path in the duct has an
63initial element of the empty span, so this is routed to Unix, which
66This is a call stack, with a crucial feature: the stack is a first-class
67citizen. You can respond over a duct zero, one, or many times. You can
68save ducts for later use. There are definitely parallels to Scheme-style
69continuations, but simpler and with more structure.
73If ducts are a call stack, then how do we make calls and produce
74results? Arvo processes "moves" which are a combination of message data
75and metadata. There are two types of moves. A `%pass` move is analogous
79[duct %pass return-path=path vane-name=@tD data=card]
82Arvo pushes the return path (preceded by the first letter of the vane
83name) onto the duct and sends the given data, a card, to the vane we
84specified. Any response will come along the same duct with the path
87A `%give` move is analogous to a return:
93Arvo pops the top path off the duct and sends the given card back to the
98As shown above, we use Arvo proper to route and control the flow of
99moves. However, Arvo proper is rarely directly responsible for
100processing the event data that directly causes the desired outcome of a
101move. This event data is contained within a card, which is simply a
102`(pair term noun)`. Instead, Arvo proper passes the card off to one of
103its vanes, which each present an interface to clients for a particular
104well-defined, stable, and general-purpose piece of functionality.
106As of this writing, we have seven vanes, which each provide the
109- `%ames`: the name of both our network and the vane that communicates over it.
110- `%behn`: a simple timer.
111- `%clay`: our version-controlled, referentially- transparent, and global filesystem.
112- `%dill`: a terminal driver. Unix sends keyboard events to `%dill` from either the console or telnet, and `%dill` produces terminal output.
113- `%eyre`: an http server. Unix sends http messages to `%eyre`, and `%eyre` produces http messages in response.
114- `%ford`: handles resources and publishing.
115- `%gall`: manages our userspace applications. `%gall` keeps state and manages subscribers.
119Cards are the vane-specific portion of a move. Each vane defines a
120protocol for interacting with other vanes (via Arvo) by defining four
121types of cards: kisses, gifts, notes, and signs.
123When one vane is `%pass`ed a card in its `++kiss`, Arvo activates the
124`++call` gate with the card as its argument. To produce a result, the
125vane `%give`s one of the cards defined in its `++gift`. If the vane
126needs to request something of another vane, it `%pass`es it a `++note`
127card. When that other vane returns a result, Arvo activates the `++take`
128gate of the initial vane with one of the cards defined in its `++sign`.
130In other words, there are only four ways of seeing a move: (1) as a
131request seen by the caller, which is a ++note. (2) that same request as
132seen by the callee, a `++kiss`. (3) the response to that first request
133as seen by the callee, a `++gift`. (4) the response to the first request
134as seen by the caller, a `++sign`.
136When a `++kiss` card is passed to a vane, Arvo calls its `++call` gate,
137passing it both the card and its duct. This gate must be defined in
138every vane. It produces two things in the following order: a list of
139moves and a possibly modified copy of its context. The moves are used to
140interact with other vanes, while the new context allows the vane to save
141its state. The next time Arvo activates the vane it will have this
142context as its subject.
144This overview has detailed how to pass a card to a particular vane. To
145see the cards each vane can be `%pass`ed as a `++kiss` or return as a
146`++gift` (as well as the semantics tied to them), each vane's public
147interface is explained in detail in its respective overview.
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list