mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-09-21 23:47:35 +03:00
Edit 0-nouns tutorial.
This commit is contained in:
parent
618bff849c
commit
aa67631a97
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user