--- navhome: /docs sort: 3 next: false title: Subject-oriented programming --- # Urbyte 2: subject-oriented programming Thanks for reading Urbytes 0 and 1! In Urbyte 2, we'll take nouns for granted and have some real fun with them. Let's restart our engines: ``` $ urbit -FI ~zod myship [...] ames: on localhost, UDP 31337. http: live (insecure, public) on 8080 http: live ("secure", public) on 8443 http: live (insecure, loopback) on 12321 ~zod:dojo> ``` ## Welcome to the dojo Wait, where are we? We're playing in the Urbit `:dojo`. The dojo is sort of like a cross between a Lisp REPL and the Unix shell. (If you know the Unix shell, the Urbit command line has the same history model and Emacs editing commands.) The dojo has its own command language, which is a superset of Hoon. Any Hoon expression is a command. But not all commands are expressions. (The dojo is not the only command-line app on your Urbit. By default there is one other, `:talk`. Since you're on a fakezod, you can only talk to yourself. If you accidentally press `^X`, it will put you into `:talk`; press `^X` again to switch back.) ### Dojo variables Like the Unix shell, the dojo has command variables. Type ``` > =a 42 ``` You've set the dojo variable `a` to the value `42`. The dojo puts this binding in the Hoon subject for expressions to use. So you can write: ``` > a 42 > [4 a] [4 42] > ? [4 a] {@ud @ud} [4 42] ``` To unbind `a`, just omit the value: ``` > =a ``` You removed `a` from the subject. (We can bind it again later, or bind over it without removing it.) ``` > [4 a] -find.a ``` Now trying to use `a` is an error. ## Subject-oriented programming What is this *subject* thing, anyway? We put `a` in what? Most programming languages have something called a *scope* or an *environment* or a *context*. This is a data structure that contains the variables and functions an expression can use. In a normal language, the environment is not a first-class value. You cannot save an environment in a variable, compute an expression against the environment in the variable, etc, etc. In Hoon or any "subject-oriented" language, an expression is executed against one normal value, the *subject*. In Hoon, of course, the subject is a noun. ## First experiments Up to now, we've only built constants. By definition, a constant doesn't use the subject. It would be nice to start with the subject every dojo expression gets. But that subject is pretty complex. Instead, let's make a simple noun from the kinds of atoms we've already learned about: ``` > =a [42 [%foo .6.28 ~m45] 0xdead.beef] > ? a {@ud {$foo @rs @dr} @ux} [42 [%foo .3.14 ~m45] 0xdead.beef] > 420:a 420 ``` The syntax `expression:expression` uses the product of the second expression as the subject of the first. So we're using `a` as the subject of the expression `420`. Of course, `420` is a constant expression. It doesn't care what the subject is. But: ``` > (add 2 2):a -find.add ``` We can't use `a` as the subject of even a simple addition. How could we? There's no `add` function in our `a`. It sometimes takes new Hoon programmers a little while before they realize that there really isn't a scope or environment in Hoon. ## Tree geometry So what can we do with this subject? How can we get data out of it? Let's keep working with our little test subject `a`. The most basic way to access the subject is *tree geometry*. Every noun is a binary tree; every noun in the tree has a number which is its address. The root of the tree is `1`; if the address of a cell is `n`, its head is `2n` and its tail is `2n+1`. A picture might help:: ``` 1 / \ 2 3 / \ / \ 4 5 6 7 / \ 14 15 ``` The syntax for a fragment of the subject at a tree address, or *axis*, is just `+axis`. So: ``` > +3:a [[%foo .3.14 ~m45] 0xdead.beef] > ? +7:a @ux 0xdead.beef > ? +13:a {@rs @dr} [.3.14 ~m45] ``` Of course, the fragment retains the type it had when we built it. ## Labeled surfaces We can obviously get anything we want out of the subject by tree geometry. But it's not really how we'd like to program. We'd much rather *label* subtrees with convenient, memorable symbols. For example, suppose our tree looked like: ``` 1 / \ x=2 3 / \ y=6 z=7 / \ p=14 15 / \ q=30 r=31 ``` Then instead of writing `+2`, we could write `x`, and so on. Let's replace our test subject `a` with a new noun built around this tree of *labeled surfaces*. ``` > =a [x=42 y=[p=%foo q=.6.28 r=~m45] z=0xdead.beef] > ? x:a @ud 42 > ? y:a {p/$foo q/@rs r/@dr} [p=%foo q=.6.28 r=~m45] > ? q.y:a @rs .6.28 ``` Surfaces might remind you of attributes in an object. But again, attributes in an object are a symbol table. There is no symbol table here -- just a tree search. An expression like the label `x` or the axis `+2`, which designates a fragment or feature of the subject, is called a *limb*. Limbs can be connected with a `.`, making a *wing*. To remind you that you're not in Kansas anymore, the syntax for a wing, like `q.y` above, means means "q inside y." In a classic object-oriented system, of course, this would be written `y.q`, that is, attribute `q` within object `y`. In Hoon, `q.y` means "find limb `q`, then find limb `y` inside that." ## Surfaces versus fragments Once again, Hoon has no symbol tables. When we put a surface on a noun, the surface label is part of that noun's type. It's not part of the cell or other structure that contains the noun. For example: ``` > ? x:a @ud 42 > ? +2:a x/@ud x=42 ? x.+2:a @ud 42 ``` When we take fragment 2 of the labeled subject the *surface comes with it *. `+2` is not `42` but rather `x=42`. We can take the surface off with `x.+2`. ## The search algorithm In resolving a label to a fragment axis, we search the subject type in a depth-first traverse. If we find a surface that matches the limb, we succeed. If we find a surface that doesn't match the limb, we fail. If we find a cell, we search first head, then tail. ## Skipping What if the same label appears twice in one noun? Let's modify our subject slightly as a test case: ``` > ? +7:a z/@ux z=0xdead.beef > =a a(+7 x=z:a) > ? a {x/@ud y/{p/$foo q/@rs r/@dr} x/@ux} [x=42 y=[p=%foo q=.6.28 r=~m45] x=0xdead.beef] > ? x:a @ud 42 > ? ^x:a @ux 0xdead.beef ``` We don't want to hide any part of the noun from an expression. So the modified limb `^x` *skips* the first match with a surface `x`, getting us to our `0xdead.beef`. This is a unary notation: `^^x` would skip the first two matches. ## Editing Above, we mutated our first noun with the flashy `a(+7 x=z:a)`. Of course we are not really "modifying" a noun. Hoon is a pure language. We are making an edited copy. `a(+7 x=z:a)` means "a copy of `a`, with limb `+7` replaced by the product of `x=z:a`." We can edit multiple (disjoint) wings in one expression: ``` > ? a(+7 [%hello %world], q.y .3.14) {x/@ud y/{p/$foo q/@rs r/@dr} $hello $world} [x=42 y=[p=%foo q=.3.14 r=~m45] %hello %world] ``` Notice that nothing stopped us from changing `+7` from `x=0xdead.beef` to `[%hello %world]`. Since the mutated copy is a different noun, it has a different type. (And remember that since `[x y z]` means `[x [y z]]`, `[x y [%hello %world]]` means `[x y %hello %world]`.) ## Cores and arms It should be reasonably clear how Hoon's system of fragments and surfaces parallels variables, records or structures in a classical language. But where is Hoon's equivalent of objects: values which bind code to data? The Hoon equivalent of an object is a *core*. As usual in Hoon, the resemblance isn't exact. A core has a set of computed attributes, or *arms*. Each arm is an expression whose subject is the core. There is no argument, so an arm is not a method. Physically, a core is always a cell `[battery payload]`, where the *payload* is any noun, and the *battery* is a tree of formulas in Nock (Hoon's functional assembly language) that implements the arms. As you'd expect with a computed attribute, an expression which uses a label can't know whether the subject will resolve it to a surface fragment (a *leg*) or to an arm. If we're searching a core and the label matches one of the core's arms, we compute the arm against the core. If the label is not found, we search into the payload of the core. ## Some core examples When you type these examples, make sure you get the number of spaces exactly right. Hoon syntax is not whitespace-sensitive in general, except that "one space" is always a different token from "two or more spaces." ``` > ? x:a @ud 42 > ? :per a x @ud 42 > =b :per a :core ++ foo x ++ bar [q.y foo] -- > b <2.spy {x/@ud y/{p/$foo q/@rs r/@dr} x/@ux}> > ? foo:b @ud 42 > ? bar:b {@rs @ud} [.6.28 42] ? x:b @ud 42 > ? +2:b * [[0 6] [0 58] 9 4 0 1] ``` We're seeing some Hoon regular forms for the first time. `x:a` turns out to be an irregular relative of the regular `:per` form. (We'll get more into syntax in a later Urbyte. If some of these examples seem syntactically a little funky, this isn't usually way we'd do them in "real life." We don't normally write cores on one line in the dojo, for instance.) And when we print `b`, or any core, we see that typed noun printing can't be an invertible function in Hoon. We actually can read the battery (with `+2:b` above), but it's just Nock code, not typed data. We don't even print the payload data, though we print the payload type. The `<2.spy>` just shows a core with two arms, for which `spy` is a hash code. ## The dojo subject Now that we've made a test subject which is a core, we can look directly at the real dojo subject: ``` > +1 [ [ [ a=[x=42 y=[p=%foo q=.6.28 r=~m45] x=0xdead.beef] b=<2.spy {x/@ud y/{p/$foo q/@rs r/@dr} x/@ux}> ] our=~zod now=~2016.7.18..08.05.15..0b5c eny=0vl.hsfrh.tg642.g5o21.1n80b.0h141.0vuan.pm8o4.77ovg.96rk0.n26nn ] ~ <283.xzp 42.ajz 407.xtr 110.xht 1.ztu $151> ] ``` We see a bunch of surfaces: our custom `a` and `b`; standard surfaces for identity, date, and entropy; and a ginormous core stack with almost a thousand total arms. To be exact, the syntax `<283.xzp 42.ajz 407.xtr 110.xht 1.ztu $151>` denotes a system of six cores, each of whose payload is another core, until the innermost payload `%151` (the Hoon version). This stack is our standard library, from which comes `add` and other fine functions. (We don't know how to define a Hoon function yet, but we're getting close.) Let's clean up our subject, just to be hygienic: ``` > =a > =b > +1 [ [ our=~zod now=~2016.7.18..08.10.42..36a0 eny=0vf.8j71j.hlqim.k340u.q0ual.v2cd8.cfa65.vkbte.e733g.ehihg.e8aog ] ~ <283.xzp 42.ajz 407.xtr 110.xht 1.ztu $151> ] ``` Again, remember that `=a` is not Hoon syntax, but `:dojo` syntax. How the dojo assembles this subject remains a mystery. But it's not a particularly interesting mystery. ## And we're done And we're done! Press `^D` to exit: ``` ~zod:dojo> ^D $ ``` ## Questions and/or exercises As always, these questions are optional and only for fun. What's the best way to construct a core which acts as a function? How do you call the function? Why don't any other languages use subject-oriented programming? Which languages are most similar to it?