diff --git a/main/pub/src/doc/ref/hoon/morphology.md b/main/pub/src/doc/ref/hoon/morphology.md index 31969b4dfd..5ee7d641d8 100644 --- a/main/pub/src/doc/ref/hoon/morphology.md +++ b/main/pub/src/doc/ref/hoon/morphology.md @@ -1,42 +1,98 @@ Morphology ========== -Hoon is a statically typed language that compiles to Nock. +Hoon is a statically typed language that compiles to Nock. You can test out +most of the compilation routines in the REPL, so we'll point out some of those +as we go along. At the highest level, there is `++make`, which turns text into +nock. -A type is a function whose domain is the set of all nouns and whose range is the set of all nouns that are members of that type. + ~hoclur-bicrel/try=> (make '|= [@ @ud] +<') + [%8 p=[%1 p=[0 0]] q=[p=[%1 p=[0 6]] q=[%0 p=1]]] -The compilation process is as follows: +If you want to know how Hoon code is compiled, start your investigation in +`++make`. -First, a runic expression is parsed into an abstact syntax-tree, called a `twig` +At a high level, the compilation process is as follows: - expression => twig +First, a runic expression is parsed into an abstact syntax tree, called a +`twig`: -A subject type is generated from the twig. This type describes the subject -of the Nock formula that the twig compiles to. + text => twig - twig => [subject-type twig] +This can be tested at the command line with `++ream`: -The twig is then compiled into nock formula, and the type of the product of -the formula is inferred. + ~hoclur-bicrel/try=> (ream '|= [@ @ud] +<') + [ %brts + p=[p=[%axil p=[%atom p=~.]] q=[%axil p=[%atom p=~.ud]]] + q=[%cnts p=~[[%.y p=6]] q=~] + ] + +Next, we get into the real meat of the compiler. In the compiler proper, which +is `++mint` in `++ut`, we take a twig and a subject type and turn it into a +product type and a blob of nock. [subject-type twig] => [product-type nock-formula] -As long as subject-type is a correct description of some subject, you can -take any twig and compile it against subject-type, producing a formula such -that +A "type" is simply a set of possible values. These are defined in Hoon as one +of the ten kinds of type found in `++type`. At its most general, the `noun` +type contains all Hoon nouns. Everything in Hoon is a noun. The `%void` type +contains no values at all. The `%atom` type contains only atoms. The other +types are documented elsewhere. - *[subject formula] +During compilation, as we compile each twig, we compile it against a subject +type. During the compilation of a twig, we obviously don't have access to the +value of the subject (else compilation would include running the code). We do, +however, have some guarantees about its value. We have its type. -is a product correctly described by product-type. +Most runes don't change the subject type, but some do. In the most simple +example, consider `=> p q`, which means to evaluate `q` with a subject of +`p`. Here, the subject type of `q` is simply the type of `p`. + +In a slightly more complicated example, consider `?: p q r`, which means simply +to evaluate `q` if `p` is true, else evaluate `r`. When compiling `q`, we get +to assume in the subject type that `p` is true while when compiling `r`, we get +to assume in the subject type that `p` is false. This is used to great +practical purpose, for example, when handling lists. If `p` is a test whether +the list is empty (which would be `?=(~ l)`), then in `q` we can assume that +the list is empty while in `r` we know that the list has a head and a tail. +Without that test, if you attempt to refer to the head of the list, the +compiler will complain that it cannot verify there is even a head to refer to +(which will be a `find-limb` error). + +Recapping, when compiling Hoon code, we compile each individual twig against +the subject with which it will eventually be called. The product is a nock +formula and the type of value that it may produce. Thus, both the nock formula +and the product type may depend on the both the subject type and the twig in +question. + +It's obvious that the product type will usually depend on the subject type, but +it's less obvious when the nock formula will depend on the type. It does +happen occasionally, though. When resolving the a face, for example, the axis +that ends up in the nock formula depends on the where the face is in the +subject. We only know this because faces are in the subject type. Thus, in +`=> [p=42 q=1.337] p`, the `p` twig compiles to nock `[0 2]` while in `=> +[q=42 p=1.337] p`, the `p` twig compiles to nock `[0 3]`. This is true even +though the actual nock produced by `[p=42 q=1.337]` is the same as that +produced by `[q=42 p=1.337]`. Thus, the nock formula may depend on the subject +type. + +As long as some value is in the subject type, you can run it against the +produced nock formula as `*[subject formula]` and get a value in the product +type. + +We've ignored one question thus far: it's all well and good once we've started +compiling, for we know the subject type. But what subject type do we start +with? We could, of course, put some restrictions on the subject type of +compiled Hoon code, but (1) there's no reason to do that, and (2) since this +will be returned as nock, and nock is untyped, the compiler cannot actually +make any guarantees about what subject it will be called with. Thus, we start +the compilation with a subject type of all nouns. This works well enough that in Hoon there is no direct syntax for defining or declaring a type. There is only a syntax for constructing twigs. Types are always produced by inference. -Let's look at a simple example of the above proc - - Hoon has 120 [XX count] digraph runes. The choice of glyph is not random. The first defines a semantic category (with some exceptions). These categories are: