-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsystem-prompt.txt
7716 lines (6085 loc) · 242 KB
/
system-prompt.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
You are an expert Hoon programmer. Read the given problem, and produce a Hoon gate that compiles successfully, meets the specification, and outputs the correct result. Provide the entire code, without any explanations or clarifications.
# Hoon School Complete Documentation
---
## Pronouncing Hoon
Hoon uses {% tooltip label="runes" href="/glossary/rune" /%}, or
two-character ASCII symbols, to describe its structure. (These are
analogous to keywords in other programming languages.) Because there
has not really been a standard way of pronouncing, say, `#` (hash,
pound, number, sharp, hatch) or `!` (exclamation point, bang, shriek,
pling), the authors of Urbit decided to adopt a one-syllable mnemonic to
uniquely refer to each.
{% table %}
- Name
- Character
- Name
- Character
- Name
- Character
---
- `ace`
- `␣`
- `gap`
- `␣␣`, `\n`
- `pat`
- `@`
---
- `bar`
- `|`
- `gar`
- `>`
- `sel`
- `[`
---
- `bas`
- `\`
- `hax`
- `#`
- `ser`
- `]`
---
- `buc`
- `$`
- `hep`
- `-`
- `sig`
- `~`
---
- `cab`
- `_`
- `kel`
- `{`
- `soq`
- `'`
---
- `cen`
- `%`
- `ker`
- `}`
- `tar`
- `*`
---
- `col`
- `:`
- `ket`
- `^`
- `tic`
- `` ` ``
---
- `com`
- `,`
- `lus`
- `+`
- `tis`
- `=`
---
- `doq`
- `"`
- `mic`
- `;`
- `wut`
- `?`
---
- `dot`
- `.`
- `pal`
- `(`
- `zap`
- `!`
---
- `fas`
- `/`
- `pam`
- `&`
- `gal`
- `<`
---
- `par`
- `)`
{% /table %}
Note that the list includes two separate whitespace forms: `ace` for a
single space `␣`; `gap` is either two or more spaces `␣␣` or a line
break `\n`. In Hoon, the only whitespace significance is the
distinction between `ace` and `gap`—i.e., the distinction between one
space and more than one.
# B-syntax.md
---
+++
title = "1. Hoon Syntax"
objectives = ["Distinguish nouns, cells, and atoms.", "Apply auras to transform an atom.", "Identify common Hoon molds, such as cells, lists, and tapes.", "Pin a face to the subject.", "Make a decision at a branch point.", "Distinguish loobean from boolean operations.", "Slam a gate (call a function)."]
+++
_This module will discuss the fundamental data concepts of Hoon and how
programs handle control flow._
## Hoon Elements
An
[**expression**](https://en.wikipedia.org/wiki/Expression_%28computer_science%29)
is a combination of characters that a language interprets and evaluates
to produce a value. All Hoon programs are built of expressions, rather
like mathematical equations. Hoon expressions are built along a
backbone of {% tooltip label="runes" href="/glossary/rune" /%}, which
are two-character symbols that act like keywords in other programming
languages to define the syntax, or grammar, of the expression.
Runes are the building blocks of all Hoon code, represented as a pair of
non-alphanumeric ASCII characters. Runes form expressions; runes are
used how keywords are used in other languages. In other words, all
computations in Hoon ultimately require runes. Runes and other Hoon
expressions are all separated from one another by either two spaces or a
line break.
All runes take a fixed number of “children” or “daughters”. Children
can themselves be runes with children, and Hoon programs work by
chaining through these until a value—not another rune—is arrived at.
For this reason, we very rarely need to close expressions. Keep this
scheme in mind when examining Hoon code.
Hoon expressions can be either basic or complex. Basic expressions of
Hoon are fundamental, meaning that they can’t be broken down into
smaller expressions. Complex expressions are made up of smaller
expressions (which are called **subexpressions**).
The Urbit operating system hews to a conceptual model wherein each
expression takes place in a certain context (the {% tooltip
label="subject" href="/glossary/subject" /%}). While sharing a lot of
practicality with other programming paradigms and platforms, Urbit's
model is mathematically well-defined and unambiguously specified. Every
expression of Hoon is evaluated relative to its subject, a piece of data
that represents the environment, or the context, of an expression.
At its root, Urbit is completely specified by {% tooltip label="Nock"
href="/glossary/nock" /%}, sort of a machine language for the Urbit
virtual machine layer and event log. However, Nock code is basically
unreadable (and unwriteable) for a human. [One worked
example](/language/nock/examples/decrement) yields, for decrementing a
value by one, the Nock formula:
```hoon
[8 [1 0] 8 [1 6 [5 [0 7] 4 0 6] [0 6] 9 2 [0 2] [4 0 6] 0 7] 9 2 0 1]
```
This is like reading binary machine code: we mortals need a clearer vernacular.
Hoon serves as Urbit's practical programming language. Everything in
Urbit OS is written in Hoon, and many of the ancillary tools as well.
Any operation in Urbit ultimately results in a value. Much like machine
language designates any value as a command, an address, or a number, a
Hoon value is interpreted per the Nock rules and results in a basic data
value at the end. So what are our data values in Hoon, and how do they
relate to each other?
## Nouns
Think about a child persistently asking you what a thing is made of. At
first, you may respond, “plastic”, or “metal”. Eventually, the child
may wear you down to a more fundamental level: atoms and molecules
(bonded atoms).
In a very similar sense, everything in a Hoon program is an atom or a
bond. Metaphorically, a Hoon program is a complex molecule, a digital
chemistry that describes one mathematical representation of data.
The most general data category in Hoon is a {% tooltip label="noun"
href="/glossary/noun" /%}. This is just about as broad as saying
“thing”, so let's be more specific:
> A noun is an atom or a cell.
Progress? We can say, in plain English, that
- An {% tooltip label="atom" href="/glossary/atom" /%} is a non-negative
integer number (0 to +∞), e.g. `42`.
- A {% tooltip label="cell" href="/glossary/cell" /%} is a pair of two
nouns, written in square brackets, e.g. `[0
1]`.
_Everything_ in Hoon (and Nock, and Urbit) is a noun. The Urbit OS
itself is a noun. So given any noun, the Urbit VM simply applies the
Nock rules to change the noun in well-defined mechanical ways.
### Atoms
If an atom is a non-negative number, how do we represent anything else?
Hoon provides each atom an {% tooltip label="aura" href="/glossary/aura"
/%} , a tag which lets you treat a number as text, time, date, Urbit
address, IP address, and much more.
An aura always begins with `@` pat, which denotes an atom (as opposed to
a cell, `^` ket, or the general noun, `*` tar). The next letter or
letters tells you what kind of representation you want the value to
have.
For instance, to change the representation of a regular decimal number
like `32` to a binary representation (i.e. for 2⁵), use `@ub`:
```hoon
> `@ub`32
0b10.0000
```
(The tic marks are a shorthand which we'll explain later.)
Aura values are all designed to be
[URL-safe](https://developers.google.com/maps/url-encoding), so the
European-style thousands separator `.` dot is used instead of the
English `,` com. `1.000` is one thousand, not `1.0` one with a
fractional part of zero.
While there are dozens of auras for specialized applications, here are
the most important ones for you to know:
| Aura | Meaning | Example | Comment |
| ---- | ------- | ------- | ------- |
| `@` | Empty aura | `100` | (displays as `@ud`) |
| `@da` | Date (absolute) | ~2022.2.8..16.48.20..b53a | Epoch calculated from 292 billion B.C. |
| `@p` | Ship name | `~zod` | |
| `@rs` | Number with fractional part | `.3.1415` | Note the preceding `.` dot. |
| `@t` | Text (“cord”) | `'hello'` | One of Urbit's several text types; only UTF-8 values are valid. |
| `@ub` | Binary value | `0b1100.0101` | |
| `@ud` | Decimal value | `100.000` | Note that German-style thousands separator is used, `.` dot. |
| `@ux` | Hexadecimal value | `0x1f.3c4b` | |
Hearkening back to our discussion of interchangeable representations in
Lesson -1, you can see that these are all different-but-equivalent ways
of representing the same underlying data values.
There's a special value that recurs in many contexts in Hoon: `~` sig
is the null or zero value.
The `^-` {% tooltip label="kethep"
href="/language/hoon/reference/rune/ket#--kethep" /%} rune is useful for
ensuring that everything in the second child matches the type (aura) of
the first, e.g.
```hoon
^- @ux 0x1ab4
```
We will use `^-` kethep extensively to enforce type constraints, a very
useful tool in Hoon code.
### Cells
A {% tooltip label="cell" href="/glossary/cell" /%} is a pair of nouns.
Cells are traditionally written using square brackets: `[]`. For now,
just recall the square brackets and that cells are always _pairs_ of
values.
```hoon
[1 2]
[@p @t]
[[1 2] [3 4]]
```
This is actually a shorthand for a rune as well, `:-` {% tooltip
label="colhep" href="/language/hoon/reference/rune/col#--colhep" /%}
```hoon
:- 1 2
```
produces a cell `[1 2]`. You can chain these together:
```hoon
:- 1 :- 2 3
```
to produce `[1 [2 3]]` or `[1 2 3]`.
We deal with cells in more detail below.
{% callout %}
**Hoon as Noun**
We mentioned earlier that everything in Urbit is a noun, including the
program itself. This is true, but getting from the rune expression in
Hoon to the numeric expression requires a few more tools than we
currently are prepared to introduce.
For now, you can preview the structure of the Urbit OS as a noun by
typing `.` dot at the Dojo prompt. This displays a summary of the
structure of the operating function itself as a noun.
## Verbs (Runes)
The backbone of any Hoon expression is a scaffolding of {% tooltip
label="runes" href="/glossary/rune" /%} , which are essentially
mathematical relationships between daughter components. If nouns are
nouns, then runes are verbs: they describe how nouns relate. Runes
provide the structural and logical relationship between noun values.
A rune is just a pair of ASCII characters (a digraph). We usually {%
tooltip label="pronounce runes" href="/glossary/aural-ascii" /%} by
combining their characters’ names, e.g.: {% tooltip label="\"kethep\""
href="/language/hoon/reference/rune/ket#--kethep" /%} for `^-`, {%
tooltip label="\"bartis\""
href="/language/hoon/reference/rune/bar#-bartis" /%} for `|=`, and {%
tooltip label="\"barcen\""
href="/language/hoon/reference/rune/bar#-barcen" /%} for `|%`.
For instance, when we called a function earlier (in Hoon parlance, we
_slammed a gate_), we needed to provide the `%-` {% tooltip
label="cenhep" href="/language/hoon/reference/rune/cen#-cenhep" /%} rune
with two bits of information, a function name and the values to
associate with it:
```hoon {% copy=true %}
%-
add
[1 2]
```
The operation you just completed is straightforward enough: `1 + 2`, in
many languages, or `(+ 1 2)` in a [Lisp
dialect](https://en.wikipedia.org/wiki/Lisp_%28programming_language%29)
like [Clojure](https://en.wikipedia.org/wiki/Clojure). Literally, we
can interpret `%- add [1 2]` as “evaluate the `add` core on the input
values `[1 2]`”.
The {% tooltip label="++add"
href="/language/hoon/reference/stdlib/1a#add" /%} function expects
precisely two values (or _arguments_), which are provided by {% tooltip
label="%-" href="/language/hoon/reference/rune/cen#-cenhep" /%} in the
neighboring child expression as a cell. There's really no limit to the
complexity of Hoon expressions: they can track deep and wide. They
also don't care much about layout, which leaves you a lot of latitude.
The only hard-and-fast rule is that there are single spaces (`ace`s) and
everything else (`gap`s).
```hoon {% copy=true %}
%-
add
[%-(add [1 2]) 3]
```
(Notice that inside of the `[]` cell notation we are using a slightly
different form of the `%-` rune call. In general, there are several
ways to use many runes, and we will introduce these gradually. We'll
see more expressive ways to write Hoon code after you're comfortable
using runes.)
For instance, here are some of the standard library functions which have
a similar architecture in common:
- [`++add`](/language/hoon/reference/stdlib/1a#add) (addition)
- [`++sub`](/language/hoon/reference/stdlib/1a#sub) (subtraction, positive results only—what happens if you subtract past zero?)
- [`++mul`](/language/hoon/reference/stdlib/1a#mul) (multiplication)
- [`++div`](/language/hoon/reference/stdlib/1a#div) (integer division, no remainder)
- [`++pow`](/language/hoon/reference/stdlib/2g#pow) (power or exponentiation)
- [`++mod`](/language/hoon/reference/stdlib/1a#mod) (modulus, remainder after integer division)
- [`++dvr`](/language/hoon/reference/stdlib/1a#dvr) (integer division with remainder)
- [`++max`](/language/hoon/reference/stdlib/1a#max) (maximum of two numbers)
- [`++min`](/language/hoon/reference/stdlib/1a#min) (minimum of two numbers)
### Rune Expressions
Any Hoon program is architected around runes. If you have used another
programming language, you can see these as analogous to keywords,
although they also make explicit what most language syntax parsers leave
implicit. Hoon aims at a parsimony of representation while leaving
latitude for aesthetics. In other words, Hoon strives to give you a
unique characteristic way of writing a correct expression, but it leaves
you flexibility in how you lay out the components to maximize
readability.
We are only going to introduce a handful of runes in this lesson, but by
the time we're done with Hoon School, you'll know the twenty-five or so
runes that yield 80% of the capability.
Most runes are used at the beginning of a complex expression, but there
are exceptions. For example, the runes `--` {% tooltip label="hephep"
href="/language/hoon/reference/rune/terminators#---hephep" /%} and
`==` {% tooltip label="tistis"
href="/language/hoon/reference/rune/terminators#-tistis" /%} are used at
the end of certain expressions.
#### Aside: Writing Incorrect Code
At the Dojo, you can attempt to operate using the wrong values; for
instance, `++add` doesn't know how to add three numbers at the same
time.
```hoon
> %- add [1 2 3]
-need.@
-have.[@ud @ud]
nest-fail
dojo: hoon expression failed
```
So this statement above is _syntactically_ correct (for the `%-` rune)
but in practice fails because the expected input arguments don't match.
Any time you see a `need`/`have` pair, this is what it means.
### Rune Families
Runes are classified by family (with the exceptions of `--` hephep and
`==` tistis). The first of the two symbols indicates the family—e.g.,
the `^-` kethep rune is in the `^` {% tooltip label="ket"
href="/language/hoon/reference/rune/ket" /%} family of runes, and the
`|=` bartis and `|%` barcen runes are in the `|` {% tooltip label="bar"
href="/language/hoon/reference/rune/bar" /%} family. The runes of
particular family usually have related meanings. Two simple examples:
the runes in the `|` bar family are all used to create cores, and the
runes in the `:` {% tooltip label="col"
href="/language/hoon/reference/rune/col" /%} family are all used to
create cells.
Rune expressions are usually complex, which means they usually have one
or more subexpressions. The appropriate syntax varies from rune to
rune; after all, they’re used for different purposes. To see the syntax
rules for a particular rune, consult the rune reference. Nevertheless,
there are some general principles that hold of all rune expressions.
Runes generally have a fixed number of expected children, and thus do
not need to be closed. In other languages you’ll see an abundance of
terminators, such as opening and closing parentheses, and this way of
doing this is largely absent from Urbit. That’s because all runes take
a fixed number of children. Children of runes can themselves be runes
(with more children), and Hoon programs work by chaining through these
series of children until a value—not another rune—is arrived at. This
makes Hoon code nice and neat to look at.
### Tall and Wide Forms
We call rune expressions separated by `gap`s **tall form** and those
using parentheses **wide form**. Tall form is usually used for
multi-line expressions, and wide form is used for one-line expressions.
Most runes can be used in either tall or wide form. Tall form
expressions may contain wide form subexpressions, but wide form
expressions may not contain tall form.
The spacing rules differ in the two forms. In tall form, each rune and
subexpression must be separated from the others by a `gap`: two or more
spaces, or a line break. In wide form the rune is immediately followed
by parentheses `( )`, and the various subexpressions inside the
parentheses must be separated from the others by an `ace`: a single
space.
Seeing an example will help you understand the difference. The `:-`
colhep rune is used to produce a cell. Accordingly, it is followed by
two subexpressions: the first defines the head of the cell, and the
second defines the tail. Here are three different ways to write a `:-`
colhep expression in tall form:
```hoon
> :- 11 22
[11 22]
> :- 11
22
[11 22]
> :-
11
22
[11 22]
```
All of these expressions do the same thing. The first example shows
that, if you want to, you can write tall form code on a single line.
Notice that there are two spaces between the `:-` colhep rune and `11`,
and also between `11` and `22`. This is the minimum spacing necessary
between the various parts of a tall form expression—any fewer will
result in a syntax error.
Usually one or more line breaks are used to break up a tall form
expression. This is especially useful when the subexpressions are
themselves long stretches of code. The same `:-` colhep expression in
wide form is:
```hoon
> :-(11 22)
[11 22]
```
This is the preferred way to write an expression on a single line. The
rune itself is followed by a set of parentheses, and the subexpressions
inside are separated by a single space. Any more spacing than that
results in a syntax error.
Nearly all rune expressions can be written in either form, but there are
exceptions. `|%` {% tooltip label="barcen"
href="/language/hoon/reference/rune/bar#-barcen" /%} and `|_` {%
tooltip label="barcab" href="/language/hoon/reference/rune/bar#_-barcab"
/%} expressions, for example, can only be written in tall form. (Those
are a bit too complicated to fit comfortably on one line anyway.)
### Nesting Runes
Since runes take a fixed number of children, one can visualize how Hoon
expressions are built by thinking of each rune being followed by a
series of boxes to be filled—one for each of its children. Let us
illustrate this with the `:-` {% tooltip label="colhep"
href="/language/hoon/reference/rune/col#--colhep" /%} rune.
![Colhep rune with two empty boxes for children.](https://media.urbit.org/docs/hoon-syntax/cell1.png)
Here we have drawn the `:-` colhep rune followed by a box for each of
its two children. We can fill these boxes with either a value or an
additional rune. The following figure corresponds to the Hoon expression
`:- 2 3`.
![Colhep rune with two boxes for children containing 2 and 3.](https://media.urbit.org/docs/hoon-syntax/cell2.png)
This, of course, evaluates to the cell `[2 3]`.
The next figure corresponds to the Hoon expression `:- :- 2 3 4`.
![Colhep rune with two boxes for children, one containing a colhep rune with two boxes for children containing 2 and 3, and 4.](https://media.urbit.org/docs/hoon-syntax/cell3.png)
This evaluates to `[[2 3] 4]`, and we can think of the second `:-`
colhep as being “nested” inside of the first `:-` colhep.
What Hoon expression does the following figure correspond to, and what
does it evaluate to?
![Colhep rune with two boxes for children containing 2 and a colhep rune with two boxes for children containing 3 and 4.](https://media.urbit.org/docs/hoon-syntax/cell4.png)
This represents the Hoon expression `:- 2 :- 3 4`, and evaluates to
`[2 [3 4]]`. (If you input this into dojo it will print as `[2 3 4]`,
which we'll consider later.)
Thinking in terms of such “LEGO brick” diagrams can be a helpful
learning and debugging tactic.
## Preserving Values with Faces
A Hoon expression is evaluated against a particular subject, which
includes Hoon definitions and the standard library, as well as any
user-specified values which have been made available. Unlike many
procedural programming languages, a Hoon expression only knows what it
has been told explicitly. This means that as soon as we calculate a
value, it returns and falls back into the ether.
```hoon
%- sub [5 1]
```
Right now, we don't have a way of preserving values for subsequent use
in a more complicated Hoon expression.
We are going to store the value as a variable, or in Hoon, “pin a face
to the subject”. Hoon faces aren't exactly like variables in other
programming languages, but for now we can treat them that way, with the
caveat that they are only accessible to daughter or sister expressions.
When we used {% tooltip label="++add"
href="/language/hoon/reference/stdlib/1a#add" /%} or {% tooltip
label="++sub" href="/language/hoon/reference/stdlib/1a#sub" /%}
previously, we wanted an immediate answer. There's not much more to say
than `5 + 1`. In contrast, pinning a face accepts three daughter
expressions: a name (or face), a value, and the rest of the expression.
```hoon {% copy=true %}
=/ perfect-number 28
%- add [perfect-number 10]
```
This yields `38`, but if you attempt to refer to `perfect-number` again
on the next line, the Dojo fails to locate the value.
```hoon
> =/ perfect-number 28
%- add [perfect-number 10]
38
> perfect-number
-find.perfect-number
dojo: hoon expression failed
```
This syntax is a little bit strange in the Dojo because subsequent
expressions, although it works quite well in long-form code. The Dojo
offers a workaround to retain named values:
```hoon
> =perfect-number 28
> %- add [perfect-number 10]
38
> perfect-number
28
```
The difference is that the Dojo “pin” is permanent until deleted:
```hoon {% copy=true %}
=perfect-number
```
rather than only effective for the daughter expressions of a `=/` tisfas
rune. (We also won't be able to use this Dojo-style pin in a regular
Hoon program.)
## Containers & Basic Data Structures
Atoms are well and fine for relatively simple data, but we already know
about cells as pairs of nouns. How else can we think of collections of
data?
### Cells
A cell is formally a pair of two objects, but as long as the second
(right-hand) object is a cell, these can be written stacked together:
```hoon
> [1 [2 3]]
[1 2 3]
> [1 [2 [3 4]]]
[1 2 3 4]
```
This convention keeps the notation from getting too cluttered. For now,
let's call this a “running cell” because it consists of several cells
run together.
Since almost all cells branch rightwards, the pretty-printer (the
printing routine that the Dojo uses) prefers to omit `[]` brackets
marking the rightmost cells in a running cell. These read to the
right—that is, `[1 2 3]` is the same as `[1 [2 3]]`.
### Lists
A running cell which terminates in a `~` sig (null) atom is a list.
- What is `~`'s value? Try casting it to another aura.
`~` is the null value, and here acts as a list terminator.
Lists are ubiquitous in Hoon, and many specialized tools exist to work
with them. (For instance, to apply a gate to each value in a list, or
to sum up the values in a list, etc.) We'll see more of them in a
future lesson.
### Exercise: Making a List from a Null-Terminated Cell
You can apply an aura to explicitly designate a null-terminated running
cell as a list containing particular types of data. Sometimes you have
to clear the aura using a more general aura (like `@`) before the
conversion can work.
```hoon
> `(list @ud)`[1 2 3 ~]
~[1 2 3]
> `(list @ux)`[1 2 3 ~]
mint-nice
-need.?(%~ [i=@ux t=it(@ux)])
-have.[@ud @ud @ud %~]
nest-fail
dojo: hoon expression failed
> `(list @)`[1 2 3 ~]
~[1 2 3]
> `(list @ux)``(list @)`[1 2 3 ~]
~[0x1 0x2 0x3]
```
### Text
There are two ways to represent text in Urbit: cords (`@t` {% tooltip
label="aura" href="/glossary/aura" /%} atoms) and {% tooltip
label="tapes" href="/glossary/tape" /%} (lists of individual
characters). Both of these are commonly called
[“strings”](https://en.wikipedia.org/wiki/String_%28computer_science%29).
Why represent text? What does that mean? We have to have a way of
distinguishing words that mean something to Hoon (like `list`) from
words that mean something to a human or a process (like `'hello
world'`).
Right now, all you need to know is that there are (at least) two valid
ways to write text:
- `'with single quotes'` as a cord.
- `"with double quotes"` as text.
We will use these incidentally for now and explain their characteristics
in a later lesson. Cords and text both use
[UTF-8](https://en.wikipedia.org/wiki/UTF-8) representation, but all
actual code is [ASCII](https://en.wikipedia.org/wiki/ASCII).
```hoon
> "You can put ½ in quotes, but not elsewhere!"
"You can put ½ in quotes, but not elsewhere!"
> 'You can put ½ in single quotes, too.'
'You can put ½ in single quotes, too.'
> "Some UTF-8: ἄλφα"
"Some UTF-8: ἄλφα"
```
### Exercise: ASCII Values in Text
A {% tooltip label="cord" href="/glossary/cord" /%} (`@t`) represents
text as a sequence of characters. If you know the
[ASCII](https://en.wikipedia.org/wiki/ASCII) value for a particular
character, you can identify how the text is structured as a number.
(This is most easily done using the hexadecimal `@ux` representation due
to bit alignment.)
![](https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/ASCII-Table-wide.svg/1024px-ASCII-Table-wide.svg.png)
If you produce a text string as a cord, you can see the internal
structure easily in Hoon:
```hoon
> `@ux`'Mars'
0x7372.614d
```
that is, the character codes `0x73` = `'s'`, `0x72` = `'r'`, `0x61` =
`'a'`, and `0x4d` = `'M'`. Thus a cord has its first letter as the
smallest (least significant, in computer-science parlance) byte.
## Making a Decision
The final rune we introduce in this lesson will allow us to select
between two different Hoon expressions, like picking a fork in a road.
Any computational process requires the ability to distinguish options.
For this, we first require a basis for discrimination: truthness.
Essentially, we have to be able to decide whether or not some value or expression evaluates as `%.y` _true_ (in which case we will do one thing) or `%.n` _false_ (in which case we do another). At this point, our basic expressions are always mathematical; later on we will check for existence, for equality of two values, etc.
- [`++gth`](/language/hoon/reference/stdlib/1a#gth) (greater than `>`)
- [`++lth`](/language/hoon/reference/stdlib/1a#lth) (less than `<`)
- [`++gte`](/language/hoon/reference/stdlib/1a#gte) (greater than or equal to `≥`)
- [`++lte`](/language/hoon/reference/stdlib/1a#lte) (less than or equal to `≤`)
If we supply these with a pair of numbers to a `%-` cenhep call, we can
see if the expression is considered `%.y` true or `%.n` false.
```hoon
> %- gth [5 6]
%.n
> %- lth [7 6]
%.n
> %- gte [7 6]
%.y
> %- lte [7 7]
%.y
```
Given a test expression like those above, we can use the `?:` wutcol
rune to decide between the two possible alternatives. `?:` wutcol
accepts three children: a true/false statement, an expression for the
`%.y` true case, and an expression for the `%.n` false case.
[Piecewise mathematical
functions](https://en.wikipedia.org/wiki/Piecewise) require precisely
this functionality. For instance, the Heaviside function is a piecewise
mathematical function which is equal to zero for inputs less than zero
and one for inputs greater than or equal to zero.
{% math block=true %}
H(x)
=
\begin{cases} 1, & x > 0 \\\ 0, & x \le 0 \end{cases}
{% /math %}
_However_, we don't yet know how to represent a negative value! All of
the decimal values we have used thus far are unsigned (non-negative)
values, `@ud`. For now, the easiest solution is to just translate the
Heaviside function so it activates at a different value:
{% math block=true %}
H_{10}(x)
=
\begin{cases} 1, & x > 10 \\\ 0, & x \le 10 \end{cases}
{% /math %}
Thus equipped, we can evaluate the Heaviside function for particular
values of `x`:
```hoon {% copy=true %}
=/ x 10
?: %- gte [x 10]
1
0
```
We don't know yet how to store this capability for future use on
as-yet-unknown values of `x`, but we'll see how to do so in a future
lesson.
Carefully map how the runes in that statement relate to each other, and
notice how the taller structure makes it relatively easier to read and
understand what's going on.
# C-azimuth.md
---
+++
title = "2. Azimuth (Urbit ID)"
objectives = ["Understand the role of the public-key infrastructure in Urbit.", "Describe the high-level architecture of the Urbit ID address space and distinguish types of points.", "Interpret and apply the Azimuth point naming scheme.", "Identify point features such as activity.", "List at least two services/roles provided by a galaxy for the network.", "List at least two services provided by a star for its planets.", "Use Hoon to map the Azimuth address space domains and boundaries.", "Identify points, sponsors, neighbors, etc. from `@p` identifiers and simple operations."]
+++
_This module introduces how Urbit ID is structured and provides practice
in converting and working with `@p` identity points. It may be
considered optional and skipped if you are speedrunning Hoon School._
## A Public-Key Infrastructure
What is the purpose of a [public-key
infrastructure](https://en.wikipedia.org/wiki/Public_key_infrastructure)?
Essentially a PKI defines a protocol for asymmetrically revealing a
public key (which anyone can use to check that a message came from where
it says it came) and retaining a private key, used by the owner as a
cryptographically secure tool for signing electronic transactions. {%
tooltip label="Azimuth" href="/glossary/azimuth" /%} functions as a PKI
so that Urbit ID points can be uniquely controlled, transferred, and
used to work with instances of Urbit OS (ships).
Urbit ID (=Azimuth) provides persistent and stable futureproof identity
to its users through a hierarchical address space. Any particular Urbit
ID plays a particular role in the overall Urbit system which is
determined by its point number and classified into ranks.
### The Urbit Address Space
Each Urbit ID point is a 128-bit address. Urbit is structured with a
hierarchy of addressable points, and bands of smaller values (preceded
by many zeroes) have more “weight” in the system and broker access for
higher-addressed points.
- **Galaxies** represent the “governing council” of Urbit, primarily
concerned with peer discovery and packet routing as well as network
protocol governance. Galaxies allocate star address space.
- **Stars** provide peer discovery services, handle distribution of
software updates, and allocate planet address space.
- **Planets** are the primary single-user identities.
- **Moons** are intended to represent devices and associated accounts
for the owning planet, but are currently only rarely used. Each planet
has 2³² moons available to it.
- **Comets** are zero-reputation instances, in principle spammers or
bots. Comets require a star sponsor to access the network, but once
online they are persistent. They are also free to spin up.
In total there are 2¹²⁸ addressable points, of which the vast majority
are available as unclaimed “comet space.”
#### Naming
Urbit uses a system of mnemonic syllables to uniquely identify each
address point. These mnemonic names, called “`patp`s” after their Hoon
representation `@p`, occur in a set of 256 suffixes (such as “zod”) and
256 prefixes (such as “lit”). They were selected to be memorable and
pronounceable but not meaningful.
| Number | Prefix | Suffix |
| -----: | :----: | :----: |
| 0 | doz | zod |
| 1 | mar | nec |
| 2 | bin | bud |
| 3 | wan | wes |
| 4 | sam | sev |
| … | … | … |
| 254 | mip | nev |
| 255 | fip | fes |
Many points may be determined from the prefix and suffix alone, but
planet names are obfuscated, meaning that they are scrambled so that the
sponsor is not readily apparent to a peer.
#### Galaxy
The {% tooltip label="Galaxies" href="/glossary/galaxy" /%} span the
first 2⁸ addresses of Azimuth. There are 255 (`0xff` - 1) associated
stars; counting the galaxy yields 256 points (not counting moons).
Galaxy names are suffix-only.
| | First Address | Last Address |
| ------------ | ------------- | ------------ |
| Decimal | `0` | `255` |
| Hexadecimal | `0x0` | `0xff` |
| `@p` | ~zod | ~fes |
As galaxies have no sponsors, they instead have an IP address determined
by `gal.urbit.org` at port `13337`+galaxy number.
At the current time, galaxies play the role of network peer discovery,
but at some future time this will fall to the stars instead.
#### Star
Peer discovery, the primary role of stars besides planet allocation, is
an important step in responsibly controlling network traffic. “The basic
idea is, you need someone to sponsor your membership on the network. An
address that can’t find a sponsor is probably a bot or a spammer”
([docs](https://urbit.org/understanding-urbit/)).
The {% tooltip label="Stars" href="/glossary/star" /%} span the
remaining addresses to 2¹⁶. There are thus 65,536 - 256 = 65,280 stars.
Star names have prefix and suffix. They share the suffix with their
sponsoring galaxy.
| | First Address | Last Address |
| ------------ | ------------- | ------------ |
| Decimal | `256` | `65.535` |
| Hexadecimal | `0x100` | `0xffff` |
| `@p` | ~marzod | ~fipfes |
A star's sponsor can be calculated as modulo 2⁸. The first star of ~zod
is `0x100` ~marzod. The last star of ~zod is `0xffff` - `0xff` =
`0xff00` ~fipzod. The last star (of ~fes) is `0xffff` ~fipfes.
#### Planet
The {% tooltip label="Planets" href="/glossary/planet" /%} span the
remaining addresses to 2³². There are thus 4,294,967,296 - 65,536 =
4,294,901,760 planets. Planet names occur in pairs separated by a
single hyphen. A planet's name is obfuscated so it is not immediately
apparent who its sponsor is.
| | First Address | Last Address |
| ------------ | ------------- | ------------ |
| Decimal | `65.536` | `4.294.967.295` |
| Hexadecimal | `0x1.0000` | `0xffff.ffff` |
| `@p` | ~dapnep-ropmyl | ~dostec-risfen |
A planet's sponsor can be calculated as modulo 2¹⁶.
Galaxy planets occupy points beginning with `0x1.0000` ~dapnep-ronmyl
(for ~zod); ~zod's last galaxy planet is `0xffff.ffff` - `0xffff` =
`0xffff.0000` ~lodnyt-ranrud. The last galaxy planet (of ~fes) is
`0xffff.ffff` - `0xffff` + `0x00ff` = `0xffff.00ff` ~hidwyt-mogbud.
Star planets span the remaining space. The first star planet (of
~marzod) is `0x1.000` + `0x100` = `0x1.0100` ~wicdev-wisryt. The last
star planet (of ~fipfes) is `0xffff.ffff` ~dostec-risfen. Remember that
star planet recur module 2¹⁶.
#### Moon
The {% tooltip label="Moons" href="/glossary/moon" /%} occupy the block
to 2⁶⁴, with 2³² moons for each planet. Moon names have more than two
blocks (three or four) separated by single hyphens.
| | First Address | Last Address |
| ------------ | ------------- | ------------ |
| Decimal | `4.294.967.296` | `18.446.744.073.709.551.615` |
| Hexadecimal | `0x1.0000.0000` | `0xffff.ffff.ffff.ffff` |
| `@p` | ~doznec-dozzod-dozzod | ~fipfes-fipfes-dostec-risfen |
Moons recur modulo 2³² from their sponsor. Thus dividing a moon's
address by 2³² and taking the remainder yields the address of the
sponsor.
Any moon that begins with the prefix ~dopzod-dozzod-doz___ is a
galaxy moon, but not every galaxy moon begins with that prefix. The
first galaxy moon of ~zod is 0x1.0000.0000 ~doznec-dozzod-dozzod; the
last is `0xffff.ffff.ffff.ffff` - `0xffff.ffff` = `0xffff.ffff.0000.0000` ~fipfes-fipfes-dozzod-dozzod.
Any moon that begins with the prefix ~dopzod-dozzod-______ is a
star moon (other than galaxy moons), but not every star moon begins with
that prefix. The first star moon of ~marzod is `0x1.0000.0000.0100`
~doznec-dozzod-dozzod-marzod; the last is `0xffff.ffff.ffff.ffff` -
`0xffff.ffff` + `0x100` = `0xffff.ffff.0000.0100`