@@ -1,495 +0,0 @@
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?