Edit 0-nouns tutorial.

This commit is contained in:
C. Guy Yarvin 2015-11-03 13:49:33 -08:00
parent 618bff849c
commit aa67631a97

View File

@ -21,16 +21,11 @@ there, mostly, if you need it.
The main disadvantage of Hoon is that its syntax and semantics
are unfamiliar. The syntax will remind too many of Perl, but
like most human languages (and unlike Perl) it combines a regular
core structure with irregular variations. Its semantic
complexity is bounded by the fact that the compiler is only 2000
lines of Hoon (admittedly an expressive language). Most peoples'
experience is that Hoon is much easier to learn than it looks.
It does not look easy to learn, though!
But let's give it a try. One style point: we'll nest design
digressions in braces. If you see a {paragraph} or two,
assume it's of interest to language nerds only. These
digressions are "guaranteed not on the test."
core structure with irregular variations. And Hoon's semantic
is bounded by the size of the compiler: type inference plus code
generation are 2000 lines of Hoon. Most peoples' experience is
that the language is much easier to learn than it looks. Not
that it looks easy!
> The name "Hoon" is from the Wallace Stevens poem, _Tea at the
Palaz of Hoon_. It also means "hooligan" in Australian.
@ -51,8 +46,9 @@ have any real fun with nouns.
> Nouns are Lisp's S-expressions, minus a lot of hacks, tricks,
and features that made sense 50 years ago. In particular,
because atoms are not tagged (an atom can encode a string, for
instance), nouns need a static type system. How do you print an
atom if you don't know whether it's a string or a number?
instance), nouns depend on a static type system at a higher
layer. How do you print an atom if you don't know whether it's a
string or a number?
## A type system for nouns
@ -66,7 +62,7 @@ no precise meaning in Hoon and can be extremely confusing.
Hoon's two kinds of "type" are `span` and `mold`. A span is both
a constructively defined set of nouns, and a semantic convention
for users in that set. A `mold` is a function whose range is
some useful span. A mold is always idempotent (for any noun x,
some useful span. A mold is always idempotent (for any noun `x`,
`f(x)` equals `f(f(x))`), and its domain is any noun.
One way to explain this is that while a span is what most
@ -88,16 +84,17 @@ anyway for prosaic software-engineering reasons. Otherwise its
typesystem solves more or less the same job, including
pattern-matching, genericity / typeclasses, etc.
{Sending a noun over the network is a good example. In a normal
modern language, you serialize and deserialize a data type by
extending your type to implement a serialization interface. In
Hoon, any value is just a noun, so we have one function (`jam`)
that converts any noun to an atom, and another (`cue`) that is
its inverse. To validate, the receiver runs its own mold on the
cued noun, and we've sent typed data over the network without any
attack surface (except `jam` and `cue`, which fit on a page). No
custom serialization methods are required, and the mold itself is
never sent; protocol agreement is out of band.}
> Sending a noun over the network is a good example of why Hoon
is different. In a normal modern language, you serialize and
deserialize a data type by extending your type to implement a
serialization interface. In Hoon, any value is just a noun, so
we have one function (`jam`) that converts any noun to an atom,
and another (`cue`) that is its inverse. To validate, the
receiver runs its own mold on the cued noun, and we've sent typed
data over the network without any attack surface (except `jam`
and `cue`, which fit on a page). No custom serialization methods
are required, and the mold itself is never sent; protocol
agreement is out of band.
## Let's make some nouns
@ -105,7 +102,7 @@ Nouns aren't even slightly hard. Let's make a noun:
```
~tasfyn-partyv:dojo> 42
```
You'll see the expression you entered, then the resulting value:
You'll see the expression you entered, then the result:
```
> 42
42
@ -128,10 +125,10 @@ interpretation. As sets, both spans here are "any number". But
semantically, `42` has a decimal span and `0x2a` hexadecimal, so
they print differently.
{It's important to note that Hoon is a statically typed language.
> It's important to remember that Hoon is a statically typed language.
We don't work with vases unless we're dynamically compiling code,
which is of course what we're doing here in the dojo. In Hoon,
dynamic type is static type plus runtime compilation.}
dynamic type equals static type plus runtime compilation.
Let's make some cells. Try these on your own urbit:
```
@ -142,11 +139,11 @@ Let's make some cells. Try these on your own urbit:
We observe that cells associate right: `[a b c]` is just another
way of writing `[a [b c]]`.
{Lisp veterans beware: Hoon `[a b]` is Lisp `(a . b)`, Lisp
> Lisp veterans beware: Hoon `[a b]` is Lisp `(a . b)`, Lisp
`(a b)` is Hoon `[a b ~]`(`~` represents nil, with a value of
atom `0`). Lisp and Hoon are both pair-oriented languages down
below, but Lisp has a layer of sugar that makes it look
list-oriented. Hoon loves its "improper lists," ie, tuples.}
list-oriented. Hoon loves its "improper lists," ie, tuples.
## Looking at spans
@ -164,12 +161,12 @@ a more compact example format:
`@ud` and `@ux` stand for "unsigned decimal" and "unsigned hex,"
obviously.
{What is this span syntax? We only derive spans through
> What is this span syntax? We only derive spans through
inference. So there's no parsing grammar for a span. We have to
be able to print spans, if only for debugging and diagnostics,
but the syntax is output-only. As in this case, it often looks
like the `mold` syntax, but the two are at opposite ends of the
type food chain.}
type food chain.
## Looking at spans, part 2
@ -181,15 +178,8 @@ concrete noun, and often we just think of the noun.
With the `?` command, we *do* use an abstract layer, by printing
our span noun in a custom syntax. But we can also look at the
noun directly, with the `??` command.
span noun directly, with the `??` command.
{Spans are an exception to the concrete principle, because we use
"manual laziness" to define recursive structures. A recursive
span contains Hoon code which is evaluated to apply it. In
practice, it often contains the entire Urbit kernel, so you
wouldn't want to try to print it in the dojo. If you find
`??` taking a weirdly long time, this may have happened; just
press ^C.}
```
~tasfyn-partyv:dojo> ?? 42
[%atom %ud]
@ -239,6 +229,14 @@ numbers we've just been using, and make them constants:
%42
```
> Spans are an exception to the concrete style, because we use
"manual laziness" to define recursive structures. A recursive
span contains Hoon code which is evaluated to apply it. In
practice, it often contains the entire Urbit kernel, so you
wouldn't want to try to print it in the dojo. If you find
`??` taking a weirdly long time, this may have happened; just
press ^C.
## Our first mold
After seeing a few span examples, are we ready to describe the
@ -260,10 +258,15 @@ we've seen so far. In English, a valid span is either:
- a cell with head `%cube`, and tail a noun-span pair.
The head of a span is essentially the tag in a variant record,
a pattern every programming language has. To use the noun, we
a pattern every programming language has. To use the span, we
look at the head and then decide what to do with the tail.
{A conventional naming strategy for simple, self-explaining
> A conventional naming strategy for simple, self-explaining
structures is to name the legs of a tuple `p`, `q`, `r`, `s` and
`t`. If you get all the way to `t`, your noun is probably not
simple or self-explaining; meaningful names are recommended.}
simple or self-explaining; meaningful names are recommended.
Believe it or not, at this point we understand nouns completely.
We don't understand spans and molds completely, but we get the
basics. In the next chapter, we'll see how Hoon expressions
(twigs) turn one noun into another.