on 65048fe help sign in
127 lines 3.9 kB history raw
1---
2next: true
3sort: 5
4title: Marks
5---
7We've used predefined marks already, but we haven't yet created
8our own marks. Let's write a sample mark of our own, then chain
9it together with some preexisting ones to have fun with type
10conversions.
12Let's make a small "cord" mark. "Cord" is a name we use for `@t`
13text, but there's no predefined mark for it. This is
14`/mar/cord.hoon`:
16```
17/? 314
18|_ cod/@t
19++ grab
20 |%
21 ++ atom |=(arg/@ `@t`(scot %ud arg))
22 --
23++ grow
24 |%
25 ++ md cod
26 --
27--
28```
30Let's go through this line by line. `/? 314` is the required
31version number, just like in apps. After that everything's in a
32`|_`, which is a `|%` core, but with input arguments. In our
33case, the argument is the marked data.
35There are three possible top-level arms in the `|_` core,
36`++grab`, `++grow`, and `++grad`. `++grad` is used for revision
37control, and is covered elsewhere. `++grab` specifies
38functions to convert from another mark to the current mark.
39`++grow` specifies how to convert from the current mark to
40another one.
42In our case, we only define one arm in `++grab`, namely `++atom`.
43This allows us to convert any atom to a cord. `++scot` is a
44standard library function in `hoon.hoon` which pretty-prints
45atoms of various types. We want to treat the atom as an
46unsigned decimal number, so we give `%ud` and the given argument
47to `++scot`. Thus, the form of an arm in `++grab` is
48`|=(other-mark-type this-mark-value)`.
50In `++grow`, we just convert to the `md` mark, which is just a
51`@t` internally, but it has fancy conversion functions to things
52like html. `++md` isn't a function because the "argument" is already a `@t`, so we can just produce the new value directly.
54Let's play around a bit with this mark. First, let's take a
55marked atom and convert it to our new mark.
57```
58~fintud-macrep:dojo> &atom 9
60~fintud-macrep:dojo> &cord &atom 9
61'9'
62~fintud-macrep:dojo> &cord &atom &cord &atom 9
63'57'
64```
66ASCII 9 is 57. There's no requirement, implicit or otherwise,
67that conversions back and forth between marks be inverses of each
68other. These are semantic conversions, in that they refer to the
69same concept. They're not isomorphisms.
71Let's play around a little more:
73```
74~fintud-macrep:dojo> &md &cord &atom 17
75'17'
76~fintud-macrep:dojo> &hymn &md &cord &atom 17
77[ [%html ~]
78 [[%head ~] [[%title ~] [[%~. [%~. "Untitled"] ~] ~] ~] ~]
79 [ [%body ~]
80 [ i=[g=[n=%meta a=~[[n=%value v="{}"] [n=%name v="frontmatter"] [n=[%urb %front] v=""]]] c=~]
81 t=[i=[g=[n=%p a=~] c=~[[g=[n=%$ a=~[[n=%$ v="17"]]] c=~]]] t=~]
82 ]
83 ]
84 ~
86```
88That was exciting. If you squint at that, it looks an
89awful lot like html. Our value `17` is still in there, in the
90body. `urb` is the mark we render most web pages to. It makes
91sure you have a complete skeleton of a web page. Of course, by
92the time this gets to the web page, it's plain html. Let's do
93the final step in the conversion.
95```
96~fintud-macrep:dojo> &mime &hymn &md &cord &atom 17
97[ [%text %html ~]
98 p=121
99 q='<html><head><title>Untitled</title></head><body><meta value="{}" name="frontmatter" urb:front="" /><p>17</p></body></html>'
101```
103This is a mime-typed octet stream with type `/text/html`, length
104121 bytes, and our lowly number `17` rendered to a web page.
105`cord` was just one step in the chain.
107Of course, arvo can infer some parts of this chain:
109```
110~fintud-macrep:dojo> &cord 17
111'17'
112```
114Likewise, `md` is the only way to get from `cord` to `hymn`, so
115that can be omitted. If we omit the `hymn`, though, we get:
117```
118~fintud-macrep:dojo> &mime &cord 17
119[[%text %x-markdown ~] p=1 q='7']
120```
122Here, we converted straight from `cord` to `md` to `mime`. Arvo
123decided that was the most straightforward conversion, but it
124gives a different result than passing it through the `hymn`
125mark.
127The minimal correct input, then, is `&mime &hymn &cord &atom 17`.