@@ -0,0 +1,495 @@
4+title: Subject-oriented programming
7+# Urbyte 2: Subject-oriented programming
9+Thanks for reading Urbytes 0 and 1! In Urbyte 2, we'll take
10+nouns for granted and have some real fun with them.
12+Let's restart our engines:
17+ames: on localhost, UDP 31337.
18+http: live (insecure, public) on 8080
19+http: live ("secure", public) on 8443
20+http: live (insecure, loopback) on 12321
24+## Welcome to the dojo
28+We're playing in the Urbit `:dojo`. The dojo is sort of like a
29+cross between a Lisp REPL and the Unix shell. (If you know the
30+Unix shell, the Urbit command line has the same history model and
31+Emacs editing commands.)
33+The dojo has its own command language, which is a superset of
34+Hoon. Any Hoon expression is a command. But not all commands
37+(The dojo is not the only command-line app on your Urbit. By
38+default there is one other, `:talk`. Since you're on a fakezod,
39+you can only talk to yourself. If you accidentally press `ctrl-x`,
40+it will put you into `:talk`; press `ctrl-x` again to switch back.)
44+Like the Unix shell, the dojo has command variables. Type
50+You've set the dojo variable `a` to the value `42`. The dojo
51+puts this binding in the Hoon subject for expressions to use.
66+To unbind `a`, just omit the value:
72+You removed `a` from the subject. (We can bind it again later, or
73+bind over it without removing it.)
80+Now trying to use `a` is an error.
82+## Subject-oriented programming
84+What is this *subject* thing, anyway? We put `a` in what?
86+Most programming languages have something called a *scope* or an
87+*environment* or a *context*. This is a data structure that
88+contains the variables and functions an expression can use.
90+In a normal language, the environment is not a first-class value.
91+You cannot save an environment in a variable, compute an
92+expression against the environment in the variable, etc, etc.
94+In Hoon or any "subject-oriented" language, an expression is
95+executed against one normal value, the *subject*. In Hoon, of
96+course, the subject is a noun.
100+Up to now, we've only built constants. By definition, a constant
101+doesn't use the subject.
103+It would be nice to start with the subject every dojo expression
104+gets. But that subject is pretty complex. Instead, let's make a
105+simple noun from the kinds of atoms we've already learned about:
108+> =a [42 [%foo .6.28 ~m45] 0xdead.beef]
111+ {@ud {$foo @rs @dr} @ux}
112+[42 [%foo .3.14 ~m45] 0xdead.beef]
118+The syntax `expression:expression` uses the product of the second
119+expression as the subject of the first. So we're using `a` as
120+the subject of the expression `420`.
122+Of course, `420` is a constant expression. It doesn't care what
130+We can't use `a` as the subject of even a simple addition. How
131+could we? There's no `add` function in our `a`. It sometimes
132+takes new Hoon programmers a little while before they realize
133+that there really isn't a scope or environment in Hoon.
137+So what can we do with this subject? How can we get data out of
138+it? Let's keep working with our little test subject `a`.
140+The most basic way to access the subject is *tree geometry*.
141+Every noun is a binary tree; every noun in the tree has a number
142+which is its address. The root of the tree is `1`; if the
143+address of a cell is `n`, its head is `2n` and its tail is
146+A picture might help:
157+The syntax for a fragment of the subject at a tree address, or
158+*axis*, is just `+axis`. So:
162+[[%foo .3.14 ~m45] 0xdead.beef]
173+Of course, the fragment retains the type it had when we built it.
177+We can obviously get anything we want out of the subject by tree
178+geometry. But that's not really how we'd like to program. We'd
179+much rather *label* subtrees with convenient, memorable symbols.
181+For example, suppose our tree looked like:
195+Then instead of writing `+2`, we could write `x`, and so on.
197+Let's replace our test subject `a` with a new noun built around
198+this tree of *labeled surfaces*.
201+> =a [x=42 y=[p=%foo q=.6.28 r=~m45] z=0xdead.beef]
208+ {p/$foo q/@rs r/@dr}
209+[p=%foo q=.6.28 r=~m45]
216+Surfaces might remind you of attributes in an object. But again,
217+attributes in an object are a symbol table. There is no symbol
218+table here -- just a tree search.
220+An expression like the label `x` or the axis `+2`, which
221+designates a fragment or feature of the subject, is called a
222+*limb*. A list of limbs connected with `.` is a *wing*.
224+To remind you that you're not in Kansas anymore, the syntax for a
225+wing, like `q.y` above, means means "q inside y." In a classic
226+object-oriented system, of course, this would be written `y.q`,
227+that is, attribute `q` within object `y`. In Hoon, `q.y` means
228+"find limb `y`, then find limb `q` inside that."
230+## Surfaces versus fragments
232+Once again, Hoon has no symbol tables. When we put a surface
233+on a noun, the surface label is part of that noun's type. It's
234+not part of the cell or other structure that contains the noun.
235+This will take a little getting used to:
251+When we take fragment 2 of the labeled subject, the *surface
252+comes with it*. `+2` is not `42` but rather `x=42`. We can
253+take the surface off with `x.+2`.
255+## The search algorithm
257+In resolving a label to a fragment axis, we search the subject
258+type in a depth-first traverse.
260+If we find a surface that matches the limb, we succeed. If we
261+find a surface that doesn't match the limb, we fail. If we find
262+a cell, we search first head, then tail.
266+What if the same label appears twice in one noun? Let's modify
267+our subject slightly as a test case:
277+ {x/@ud y/{p/$foo q/@rs r/@dr} x/@ux}
278+[x=42 y=[p=%foo q=.6.28 r=~m45] x=0xdead.beef]
289+We don't want to hide any part of the noun from an expression.
290+So the modified limb `^x` *skips* the first match with a surface
291+`x`, getting us to our `0xdead.beef`. This is a unary notation:
292+`^^x` would skip the first two matches.
296+Above, we mutated our first noun with the flashy `a(+7 x=z:a)`.
298+Of course we are not really "modifying" a noun. Hoon is a pure
299+language. We are making an edited copy. `a(+7 x=z:a)` means "a
300+copy of `a`, with limb `+7` replaced by the product of `x=z:a`."
302+We can edit multiple (disjoint) wings in one expression:
305+> ? a(+7 [%hello %world], q.y .3.14)
306+ {x/@ud y/{p/$foo q/@rs r/@dr} $hello $world}
307+[x=42 y=[p=%foo q=.3.14 r=~m45] %hello %world]
310+Notice that nothing stopped us from changing `+7` from
311+`x=0xdead.beef` to `[%hello %world]`. Since the mutated
312+copy is a different noun, it has a different type.
314+(And remember that since `[x y z]` means `[x [y z]]`,
315+`[x y [%hello %world]]` means `[x y %hello %world]`.)
319+It should be reasonably clear how Hoon's system of fragments and
320+surfaces parallels variables, records or structures in a
321+classical language. But where is Hoon's equivalent of objects:
322+values which bind code to data?
324+The Hoon equivalent of an object is a *core*. As usual in Hoon,
325+the resemblance is inexact. A core has a set of computed
326+attributes, or *arms*. Each arm is an expression whose subject
327+is the core. There is no argument, so an arm is not a method.
329+Physically, a core is always a cell `[battery payload]`, where
330+the *payload* is any noun, and the *battery* is a tree of
331+formulas in Nock (Hoon's functional assembly language) that
332+implements the arms. (A battery is like a C++ vtable, sort of.)
334+## The search algorithm
336+As you'd expect with a computed attribute, there is only one
337+namespace and one search algorithm. We just extend the algorithm
338+described above. And an expression which uses a label can't know
339+whether the subject will resolve it to a surface fragment (a
342+If we're searching a core and the label matches one of the core's
343+arms, we compute the arm against the core. If the label is not
344+found, we search into the payload of the core.
346+## Some core examples
348+When you type these examples, make sure you get the number of
349+spaces exactly right. Hoon syntax is not whitespace-sensitive
350+in general, except that "one space" is always a different token
351+from "two or more spaces."
362+> =b :per a :core ++ foo x ++ bar [q.y foo] --
365+We're seeing some Hoon regular forms for the first time. `x:a`
366+turns out to be an irregular relative of the regular `:per` form.
368+We'll get more into syntax in a later Urbyte. If some of these
369+examples seem syntactically a little funky, this isn't usually
370+way we'd do them in "real life." We don't normally write cores
371+on a single command line. In a file this would be:
381+which is much more readable, at least once you get used to it.
382+Let's look at the core itself:
386+<2.spy {x/@ud y/{p/$foo q/@rs r/@dr} x/@ux}>
390+[[0 6] [0 58] 9 4 0 1]
393+ {x/@ud y/{p/$foo q/@rs r/@dr} x/@ux}
394+[x=42 y=[p=%foo q=.6.28 r=~m45] x=0xdead.beef]
397+When we print `b`, or any core, we see that typed noun printing
398+can't be an invertible function in Hoon.
400+We actually can read the battery (with `+2:b` above), but it's
401+just Nock code, not typed data. `<2.spy>` tells us the battery
402+has two arms and hashes to the three-letter code `spy`.
404+When printing a full core, we don't even print the payload data,
405+just its type. But our `+3:b` confirms the `[battery payload]`
406+structure of the core. Remember, `+2` is the head and `+3` is
409+Finally, let's use this thing:
429+Now that we've made a test subject which is a core, we can look
430+directly at the real dojo subject:
434+[ [ [ a=[x=42 y=[p=%foo q=.6.28 r=~m45] x=0xdead.beef]
435+ b=<2.spy {x/@ud y/{p/$foo q/@rs r/@dr} x/@ux}>
437+ now=~2016.7.18..08.05.15..0b5c
438+ eny=0vl.hsfrh.tg642.g5o21.1n80b.0h141.0vuan.pm8o4.77ovg.96rk0.n26nn
439+ our=~palnul-wolmev-bonfex-danred--tilwen-midlux-bolfus-nocser
442+ <283.xzp 42.ajz 407.xtr 110.xht 1.ztu $151>
446+We see a bunch of surfaces: our custom `a` and `b`; standard
447+surfaces for identity, date, and entropy; and a ginormous core
448+stack with *over eight hundred* total arms.
450+To be exact, the syntax `<283.xzp 42.ajz 407.xtr 110.xht 1.ztu
451+$151>` denotes a stack of six cores, each of whose payload is
452+another core, until the innermost payload `%151` (the Hoon
453+version number). This stack is our standard library, from which
454+comes `add` and other fine functions. (We don't know how to
455+write a Hoon function yet, but we're getting way closer.)
457+Let's clean up our subject, just to be hygienic:
464+ now=~2016.7.18..08.10.42..36a0
465+ eny=0vf.8j71j.hlqim.k340u.q0ual.v2cd8.cfa65.vkbte.e733g.ehihg.e8aog
466+[ [ our=~palnul-wolmev-bonfex-danred--tilwen-midlux-bolfus-nocser
469+ <283.xzp 42.ajz 407.xtr 110.xht 1.ztu $151>
473+Again, remember that `=a` is not Hoon syntax, but `:dojo` syntax.
474+How the dojo assembles this subject remains a mystery. But it's
475+not a particularly interesting mystery.
479+And we're done! Type `|exit` to exit:
482+~palnul_nocser:dojo> |exit
487+## Questions and/or exercises
489+As always, these questions are optional and only for fun.
491+What's the best way to construct a core which acts as a function?
492+What do you do to call the function?
494+Why don't any other languages use subject-oriented programming?
495+Which languages are most similar to it?