Guest User

Untitled

a guest
Nov 4th, 2015
224
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.32 KB | None | 0 0
  1. # Hoon 101.0: nouns, spans and molds
  2.  
  3. Hoon is a strict, higher-order typed pure-functional language.
  4.  
  5. Why Hoon? Typed functional languages are known for a pleasant
  6. phenomenon: once your code compiles, it's quite likely to work.
  7. But most typed functional languages are conceptually dependent on
  8. abstract advanced math, and difficult to understand without it.
  9.  
  10. Hoon is a typed FP language for the common street programmer.
  11. Well-written Hoon is as concrete and data-oriented as possible.
  12. The less functional magic you use, the better. But the magic is
  13. there, mostly, if you need it.
  14.  
  15. The main disadvantage of Hoon is that its syntax and semantics
  16. are unfamiliar. The syntax will remind too many of Perl, but
  17. like most human languages (and unlike Perl) it combines a regular
  18. core structure with irregular variations. And Hoon's semantic
  19. complexity is bounded by the size of the compiler: type inference plus code
  20. generation are 2000 lines of Hoon. Most peoples' experience is that the
  21. language is much easier to learn than it looks.
  22.  
  23. > The name "Hoon" is from the Wallace Stevens poem, _Tea at the
  24. Palaz of Hoon_. It also means "hooligan" in Australian.
  25.  
  26. ## Nouns: data made boring
  27.  
  28. A noun is an atom or a cell. An atom is any unsigned integer. A
  29. cell is an ordered pair of nouns.
  30.  
  31. The noun is an intentionally boring data model. Nouns don't have
  32. cycles (although a noun implementation should take advantage of
  33. acyclic graph structure). Noun comparison is always by value
  34. (there is no way for the programmer to test pointer equality).
  35. Nouns are strict; there is no such thing as an infinite noun.
  36. And, of course, nouns are immutable. There's basically no way to
  37. have any real fun with nouns.
  38.  
  39. > Nouns are Lisp's S-expressions, minus a lot of hacks, tricks,
  40. and features that made sense 50 years ago. In particular,
  41. because atoms are not tagged (an atom can encode a string, for
  42. instance), nouns depend on a static type system at a higher
  43. layer. How do you print an atom if you don't know whether it's a
  44. string or a number?
  45.  
  46. ## A type system for nouns
  47.  
  48. One obstacle to learning Hoon is that it has two quite distinct
  49. concepts that might equally be called a "type." Worse, most
  50. other typed functional languages are mathy and share a basically
  51. mathematical concept of "type." Hoon does not have this concept
  52. at all. We can't avoid using the T-word occasionally, but it has
  53. no precise meaning in Hoon and can be extremely confusing.
  54.  
  55. Hoon's two kinds of "type" are `span` and `mold`. A span is both
  56. a constructively defined set of nouns, and a semantic convention
  57. for users in that set. A `mold` is a function whose range is
  58. some useful span. A mold is always idempotent (for any noun `x`,
  59. `f(x)` equals `f(f(x))`), and its domain is any noun.
  60.  
  61. One way to explain this is that while a span is what most
  62. languages call a "type," Hoon has no syntax for the programmer to
  63. define a span directly. Instead, we use inference to define it
  64. as the range of a mold function. This mold can also be used to
  65. validate or normalize untrusted, untyped data -- a common problem
  66. in modern programming, because networks.
  67.  
  68. > Sending a noun over the network is a good example of why Hoon
  69. is different. In a normal modern language, you serialize and
  70. deserialize a data type by extending your type to implement a
  71. serialization interface. A really good language can process your
  72. type definition and automatically generate this code. In Hoon,
  73. we have one function `jam` that converts any noun to an atom,
  74. and another `cue` that inverts `jam`. To validate, the receiver
  75. applies its own mold to the cued noun, and we've sent typed data
  76. over the network without any attack surface (except `jam` and
  77. `cue`, which fit on a page). No custom serialization code,
  78. manual or generated, is required. The mold itself is not sent;
  79. protocol agreement is out of band.
  80.  
  81. Hoon's inference algorithm is dumber than the unification
  82. algorithms (Hindley-Milner) used in most typed functional
  83. languages. Hoon thinks only forward, not backward. Eg, Haskell
  84. can infer the result type of a function from its argument
  85. (forward), or the argument type from the result (backward).
  86. Hoon can do the first but not the second.
  87.  
  88. So Hoon needs more manual annotations, which you usually want
  89. anyway for prosaic software-engineering reasons. Otherwise its
  90. typesystem solves more or less the same job, including
  91. pattern-matching, genericity / typeclasses, etc.
  92.  
  93. > A good test of a static higher-order typesystem is whether it can
  94. infer the product type of a grammar defined as a combinator
  95. parser. The Hoon parser passes this test; when it typechecks,
  96. the parser's range nests within the span of the expression mold.
  97.  
  98. ## Let's make some nouns
  99.  
  100. Let's make a noun:
  101. ```
  102. ~tasfyn-partyv:dojo> 42
  103. ```
  104. You'll see the expression you entered, then the result:
  105. ```
  106. > 42
  107. 42
  108. ```
  109. Let's try a different noun. Or is it different?
  110. ```
  111. ~tasfyn-partyv:dojo> 0x2a
  112. ```
  113. You'll see:
  114. ```
  115. > 0x2a
  116. 0x2a
  117. ```
  118. `42` and `0x2a` are actually *the same noun*, because they're the
  119. same number. But we don't just have the noun to print - we have
  120. a `[span noun]` cell (sometimes called a `vase`).
  121.  
  122. As you recall, a span defines a set of nouns and a semantic
  123. interpretation. As sets, both spans here are "any number". But
  124. semantically, `42` has a decimal span and `0x2a` hexadecimal, so
  125. they print differently.
  126.  
  127. > It's important to remember that Hoon is a statically typed language.
  128. We don't work with vases unless we're dynamically compiling code,
  129. which is of course what we're doing here in the dojo. In Hoon,
  130. dynamic type equals static type plus runtime compilation.
  131.  
  132. Let's make some cells. Try these on your own urbit:
  133. ```
  134. ~tasfyn-partyv:dojo> [42 0x2a]
  135. ~tasfyn-partyv:dojo> [42 [0x2a 420]]
  136. ~tasfyn-partyv:dojo> [42 0x2a 420]
  137. ```
  138. We observe that cells associate right: `[a b c]` is just another
  139. way of writing `[a [b c]]`.
  140.  
  141. Lisp masters beware: Hoon `[a b]` is Lisp `(a . b)`, Lisp
  142. `(a b)` is Hoon `[a b ~]`. `~` means nil, with value zero. Lisp
  143. and Hoon are both pair-oriented languages down below, but Lisp
  144. has a layer of sugar that makes it look list-oriented. Hoon
  145. loves its "improper lists," ie, tuples.
  146.  
  147. ## Looking at spans
  148.  
  149. What are these mysterious spans? We can see them with the `?`
  150. prefix, which prints the span along with the result. Moving to
  151. a more compact example format:
  152. ```
  153. ~tasfyn-partyv:dojo> ? 42
  154. @ud
  155. 42
  156. ~tasfyn-partyv:dojo> ? 0x2a
  157. @ux
  158. 0x2a
  159. ```
  160. `@ud` and `@ux` stand for "unsigned decimal" and "unsigned hex,"
  161. obviously.
  162.  
  163. > What is this span syntax? We only derive spans through
  164. inference. So there's no parsing grammar for a span. We have to
  165. be able to print spans, if only for debugging and diagnostics,
  166. but the syntax is output-only. As in this case, it often looks
  167. like the `mold` syntax, but the two are at opposite ends of the
  168. type food chain.
  169.  
  170. ## Looking at spans, part 2
  171.  
  172. Usually, good style in Hoon is concrete style. When a Hoon
  173. programmer defines an abstract semantic value in terms of a noun,
  174. we rarely put a conceptual layer of abstraction between value and
  175. noun. We think of the value as an interpretation of the noun.
  176. We don't think of the noun as an implementation of the noun.
  177.  
  178. But rules are made to be broken. With the `?` command, we *do*
  179. use an abstract layer, by printing our span noun in that custom
  180. syntax. But we can also look at the span noun directly, with the
  181. `??` command. As we'll see, `??` is mainly for newbies, but
  182. newbies love it.
  183.  
  184. ```
  185. ~tasfyn-partyv:dojo> ?? 42
  186. [%atom %ud]
  187. 42
  188. ~tasfyn-partyv:dojo> ?? [42 0x2a]
  189. [%cell [%atom %ud] [%atom %ux]]
  190. [42 0x2a]
  191. ```
  192. What is this `%atom` syntax? Is it a real noun? Can anyone
  193. make one?
  194. ```
  195. ~tasfyn-partyv:dojo> %atom
  196. %atom
  197. ~tasfyn-partyv:dojo> %foo
  198. %foo
  199. ~tasfyn-partyv:dojo> [%foo %bar]
  200. [%foo %bar]
  201. ```
  202. What's the span of one of these symbols?
  203. ```
  204. ~tasfyn-partyv:dojo> ? %foo
  205. %foo
  206. %foo
  207. ~tasfyn-partyv:dojo> ?? %foo
  208. [%cube 7.303.014 [%atom %tas]]
  209. %foo
  210. ```
  211. This takes a little bit of explaining. `7.303.014` is just the
  212. Urbit (and German) way of writing the English number `7,303,014`,
  213. or the Urbit hex number `0x6f.6f66`, or the string "foo" as an
  214. unsigned integer with least-significant byte first.
  215.  
  216. A `%cube` span is a constant -- a set of one noun, the atom
  217. `7.303.014`. But we still need to know how to print that noun.
  218. In this case, it's an `[%atom %tas]`, ie, a text symbol.
  219.  
  220. Cubes don't have to be symbols -- in fact, we can take the
  221. numbers we've just been using, and make them constants:
  222. ```
  223. ~tasfyn-partyv:dojo> %42
  224. %42
  225. ~tasfyn-partyv:dojo> ? %42
  226. %42
  227. %42
  228. ~tasfyn-partyv:dojo> ?? %42
  229. [%cube 42 [%atom %ud]]
  230. %42
  231. ```
  232.  
  233. > Why `??`? Spans are an exception to concrete style, because they
  234. use "manual laziness" to define logically recursive structures.
  235. A recursive span contains Hoon code which is evaluated to apply
  236. it. In practice, this noun often contains the entire Urbit
  237. kernel, so you wouldn't want to try to print it in the dojo. If
  238. you find `??` taking a weirdly long time, this may have happened;
  239. press ^C.
  240.  
  241. ## Our first mold
  242.  
  243. After seeing a few span examples, are we ready to describe the
  244. set of all spans with a Hoon mold? Well, no, but let's try it
  245. anyway. Ignore the syntax (which we'll explain later; this is a
  246. tutorial, not a reference manual), and you'll get the idea:
  247. ```
  248. ++ span
  249. $% [%atom p=@tas]
  250. [%cell p=span q=span]
  251. [%cube p=* q=span]
  252. ==
  253. ```
  254. This mold is not the entire definition of `span`, just the cases
  255. we've seen so far. In English, a valid span is either:
  256.  
  257. - a cell with head `%atom`, and tail some symbol.
  258. - a cell with head `%cell`, and tail some pair of spans.
  259. - a cell with head `%cube`, and tail a noun-span pair.
  260.  
  261. The head of a span is essentially the tag in a variant record,
  262. a pattern every programming language has. To use the span, we
  263. look at the head and then decide what to do with the tail.
  264.  
  265. > A conventional naming strategy for simple, self-explaining
  266. structures is to name the legs of a tuple `p`, `q`, `r`, `s` and
  267. `t`. If you get all the way to `t`, your noun is probably not
  268. simple or self-explaining; meaningful names are recommended.
  269.  
  270. Believe it or not, at this point we understand nouns completely.
  271. We don't understand spans and molds completely, but we get the
  272. basics. In the next chapter, we'll see how Hoon expressions
  273. (twigs) turn one noun into another.
Advertisement
Add Comment
Please, Sign In to add comment