on 3fee830 help sign in
686 lines 15 kB history raw
1Odors
2=====
4Overview
5--------
7Since Everything in Hoon is a natural number, the interpreter needs to
8know both how to render them and subject them to type enforcement.
9Odors, which are just ASCII spans beginning with a `@`, carry all of the
10information necessary for the interpreter to do this. For instance, the
11interpreter knows to render an atom of odor `@t` as UTF-8 text.
13The span composing the Odor consists of two parts: a lowercase prefix
14carrying type information, and an upper-case suffix containing
15information about its size. The prefix is a taxonomy that grows more
16specific to the right. For example, atoms of the odor `@ta` are URL-safe
17ASCII text, and Atoms of the odor `@tas` are the more specific subset of
18ASCII text that is acceptable in hoon.
20The general principle of type enforcement is that atoms change freely
21either up or down the taxonomy, but not across. You can treat a `@tas`
22as a `@t`, as in a strong type system; but you can also treat a `@t` as
23a `@tas`, or an `@` as anything. However, passing a `@t` to a function
24that expects an `@ux` is a type error.
26XXDIAGRAMXX
28For example, you can cast a `@t` to a `@tas`, or vice-versa:
30 ~zod/try=> =a `@t`'permitted'
31 ~zod/try=> a
32 'permitted'
33 ~zod/try=> `@tas`a
34 %permitted
36However, you cannot pass a `@ux` to a function that expects a `@t`
37without casting it to a `@` first:
39 ~zod/try=> (|=(a=@t [%foo a]) 0x20)
40 ! type-fail
41 ! exit
42 ~zod/try=> =a 0x21
43 ~zod/try=> (|=(a=@t [%foo a]) `@t`a)
44 [%foo '!']
46Note that when explicitly casting a `@ux` to a `@t`, the interpreter
47automatically casts the `@ux` to a `@` first.
49Comprehensive list of the Hoon Odors
50------------------------------------
52 @c UTF-32 codepoint
53 @d date
54 @da absolute date
55 @dr relative date (ie, timespan)
56 @f yes or no (inverse boolean)
57 @n nil
58 @p phonemic base
59 @r IEEE floating-point
60 @rd double precision (64 bits)
61 @rh half precision (16 bits)
62 @rq quad precision (128 bits)
63 @rs single precision (32 bits)
64 @s signed integer, sign bit low
65 @sb signed binary
66 @sd signed decimal
67 @sv signed base32
68 @sw signed base64
69 @sx signed hexadecimal
70 @t UTF-8 text (cord)
71 @ta ASCII text (span)
72 @tas ASCII symbol (term)
73 @u unsigned integer
74 @ub unsigned binary
75 @ud unsigned decimal
76 @uv unsigned base32
77 @uw unsigned base64
78 @ux unsigned hexadecimal
80Odor Size Suffixes
81------------------
83The suffix of an odor, if present, is a single upper-case character A-Z
84`c`, which indicates the size of an atom. This is possible, because in
85Hoon, a letter maps to an ASCII code number, thus a number.
87Size is specified in bits in the form of `1 << (c - 'A')` resp. `2^c`,
88since most data aligns to the power of 2 or can be composed of such
89blocks.
91The size of a block of size `N` can be calculated for example using
92`(bex (sub 'N' 'A'))` in bits or `(div (bex (sub 'N' 'A')) 8)` in bytes.
94Thus, `@tD` is one UTF-8 byte (whatever that means) and `@tN` is 1
95kilobyte or less of UTF-8.
97For reference:
99 A 1 bit
100 B 2 bits
101 C 4 bits
102 D 1 byte
103 E 2 bytes
104 F 4 bytes
105 G 8 bytes
106 H 16 bytes
107 I 32 bytes
108 J 64 bytes
109 K 128 bytes
110 L 256 bytes
111 M 512 bytes
112 N 1K
113 O 2K
114 P 4K
115 Q 8K
116 R 16K
117 S 32K
118 T 64K
119 U 128K
120 V 256K
121 W 512K
122 X 1MB
123 Y 2MB
124 Z 4MB
126It is possible to construct an atom bigger than 4Mb in size, but the
127type system would not be able to express an odor size for it.
129There is also the datatype `++bloq` to hold a to-the-power-of block size
130(though it is just an alias for `@`).
132------------------------------------------------------------------------
134### @c
136UTF-32 codepoint
138Atoms of the odor `@c` represent Unicode text, constructed with a UTF-32
139bytestream, with the lowest-significant bit first. Although we usually
140use a UTF-8 bytestream, sometimes it's useful to build atoms of one or
141more UTF-32 words.
143##### Forms
145`~-[text]`
147##### Examples
149 ~zod/try=> ? ~-foo
150 ~-foo
151 @c
152 ~zod/try=> ~-i~2764.u
153 ~-i~2764.u
154 ~zod/try=> (tuft ~-i~2764.u)
155 'i❤u'
156 ~zod/try=> `@ux`~-foo
157 0x6f.0000.006f.0000.0066
158 ~zod/try=> `@ux`~-i~2764.u
159 0x75.0000.2764.0000.0069
160 ~zod/try=> `@ux`(tuft ~-i~2764.u)
161 0x75.a49d.e269
163------------------------------------------------------------------------
165### @d
167Date
169#### @da
171Absolute date
173Atoms of the odor `@da` represent absolute Urbit dates. Urbit dates
174represent 128-bit chronological time, with 2\^64 seconds from the start
175of the universe. For example, 2\^127 is 3:30:08 PM on December 5, AD
176226. The time of day and/or second fragment is optional. As the last
177example shows, BC times are also possible.
179##### Forms
181`~~[year].[month].[date]..[hour].[minute].[second]..[millisecond]`
183Note: the time of day and/or millisecond fragment is optional.
185##### Examples
187 ~zod/try=> ~2014.1.1
188 ~2014.1.1
189 ~zod/try=> ? ~2014.1.1
190 ~2014.1.1
191 @da
192 ~zod/try=> ~2014.1.1..01.01.01
193 ~2014.1.1..01.01.01
194 ~zod/try=> ? ~2014.1.1..01.01.01
195 ~2014.1.1..01.01.01
196 @da
197 ~zod/try=> ~2014.1.1..01.01.01..1234
198 ~2014.1.1..01.01.01..1234
199 ~zod/try=> `@da`(bex 127)
200 ~226.12.5..15.30.08
201 ~zod/try=> `@da`(dec (bex 127))
202 ~226.12.5..15.30.07..ffff.ffff.ffff.ffff
203 ~zod/try=> `@ux`~2013.12.7
204 0x8000.000d.2140.7280.0000.0000.0000.0000
205 ~zod/try=> `@ux`~2013.12.7..15.30.07
206 0x8000.000d.2141.4c7f.0000.0000.0000.0000
207 ~zod/try=> `@ux`~2013.12.7..15.30.07..1234
208 0x8000.000d.2141.4c7f.1234.0000.0000.0000
209 ~zod/try=> `@ux`~2013.12.7..15.30.07..1234
210 0x8000.000d.2141.4c7f.1234.0000.0000.0000
212------------------------------------------------------------------------
214#### @dr
216Relative date (ie, timespan)
218Atoms of the odor `@dr` atoms represent basic time intervals in
219milliseconds. There are no `@dr` intervals under a second or over a day
220in length.
222##### Forms
224`~d[day].h[hour]m[minute].s[second]..[fractionals]`
226Note: Every measurement is optional, so long as those that are present
227are in order. The largest measurement is preceded by a `~`.
229##### Examples
231 ~zod/try=> ~d1.h19.m5.s29
232 ~d1.h19.m5.s29
233 ~zod/try=> ? ~d1.h19.m5.s29
234 ~d1.h19.m5.s29
235 @dr
236 ~zod/try=> `@dr`(div ~s1 1.000)
237 ~.s0..0041.8937.4bc6.a7ef
238 ~zod/try=> ~d1.h19.m5.s29..0041
239 ~d1.h19.m5.s29..0041
240 ~zod/try=> `@ux`~s1
241 0x1.0000.0000.0000.0000
242 ~zod/try=> `@ux`~m1
243 0x3c.0000.0000.0000.0000
244 ~zod/try=> `@dr`(div ~d1 5)
245 ~h4.m48
246 ~zod/try=> (div ~m1 ~s1)
247 60
248 ~zod/try=> (div ~h1 ~m1)
249 60
250 ~zod/try=> (div ~h1 ~s1)
251 3.600
252 ~zod/try=> (div ~d1 ~h1)
253 24
254 ~zod/try=> `@da`(add ~2013.11.30 ~d1)
255 ~2013.12.1
257------------------------------------------------------------------------
259#### @f
261Loobean(inverse boolean)
263Atoms of the odor `@f` represent loobeans, where `0` is yes and `1` is
264no. Loobeans are often represented in their cubic and runic forms shown
265below.
267##### Forms
269`0`, `1` as numbers. `%.y`, `%.n` as [`%cube`]()s. `&`, `|` as short
270forms.
272##### Examples
274 ~zod/try=> `@ud`.y
275 0
276 ~zod/try=> ? .y
277 %.y
278 {%.y %.n}
279 ~zod/try=> `@ud`.n
280 1
281 ~zod/try=> .y
282 %.y
283 ~zod/try=> &
284 %.y
285 ~zod/try=> |
286 %.n
288------------------------------------------------------------------------
290### @n
292Nil
294Atoms of the odor `@n` indicate an absence of information, as in a list
295terminator. The only value is `~`, which is just `0`.
297 ~zod/try=> ? ~
298 ~
299 %~
300 ~zod/try=> `@ud`%~
301 0
302 ~zod/try=> `@ud`~
303 0
305------------------------------------------------------------------------
307### @p
309Phonemic base
311Atoms of `@p` are primarily used to represent ships names, but they can
312be used to optimize any short number for memorability. For example, it
313is great for checksums.
315##### Forms
317`~[phonemic]`
319Every syllable is a byte. Pairs of two bytes are separated by `-`, and
320phrases of four pairs are separated by `--`.
322 ~zod/try=> ~pasnut
323 ~pasnut
324 ~zod/try=> ? ~pasnut
325 ~pasnut
326 @p
327 ~zod/try=> `@p`0x4321
328 ~pasnut
329 ~zod/try=> `@p`0x8765.4321
330 ~famsyr-dirwes
331 ~zod/try=> `@p`0x8766.4321
332 ~lidlug-maprec
333 ~zod/try=> `@p`(shaf %foo %bar)
334 ~ralnyl-panned-tinmul-winpex--togtux-ralsem-lanrus-pagrup
336------------------------------------------------------------------------
338### @r
340IEEE floating-points
342Hoon does not yet support floating point, so these syntaxes don't work
343yet. But the syntax for a single-precision float is the normal English
344syntax, with a `.` prefix:
346------------------------------------------------------------------------
348### @s
350Signed integer, sign bit low
352Without finite-sized integers, the sign extension trick obviously does
353not work. A signed integer in Hoon is a different way to use atoms than
354an unsigned integer; even for positive numbers, the signed integer
355cannot equal the unsigned.
357The prefix for a negative signed integer is a single `-` before the
358unsigned syntax. The prefix for a positive signed integer is `--`. The
359least significant represents the sign. The representation is similar to
360a folded number line.
362#### @sb
364Signed binary
366Atoms of the odor `@sb` represent signed binary numbers.
368#### Forms
370`-0b[negative_binary]` `--0b[postive_binary]`
372#### Examples
374 ~zod/try=> ? -0b1
375 -0b1
376 @sb
377 ~zod/try=> `@sd`-0b1
378 -1
379 ~zod/try=> `@sd`--0b1
380 --1
381 ~zod/try=> `@sd`--0b11
382 --3
383 ~zod/try=> `@sb`(sum:si -0b10 -0b10)
384 -0b100
386------------------------------------------------------------------------
388#### @sd
390Signed decimal
392Atoms of odor `@sd` represent signed decimal numbers.
394#### Forms
396`-[negative[decimal]()]` `--[postive_[decimal]()]`
398#### Examples
400 ~zod/try=> -234
401 -234
402 ~zod/try=> ? -234
403 -234
404 @sd
405 ~zod/try=> ? --234
406 --234
407 @sd
408 ~zod/try=> (sum:si -234 --234)
409 --0
411------------------------------------------------------------------------
413#### @sv
415Signed base32
417Atoms of odor `@sv` represent signed base32 numbers.
419##### Forms
421`-0v[negative_base32]` The digits are, in order, `0-9`, `a-v`.
422`--0v[positive_base32]`
424##### Examples
426 ~zod/try=> -0vv
427 -0vv
428 ~zod/try=> ? -0vv
429 -0vv
430 @sv
431 ~zod/try=> --0vb
432 --0vb
433 ~zod/try=> `@sd`-0vv
434 -31
435 ~zod/try=> `@sd`--0vb
436 --11
437 ~zod/try=> `@sd`(sum:si -0vv --0vb)
438 -20
440------------------------------------------------------------------------
442#### @sw
444Signed base64
446Atoms of odor `@sw` represent base64 numbers.
448##### Forms
450`-0w[negative_base64]` The digits are, in order, `0-9`, `a-z`,
451`A-Z`,`-`, and `~`. `--0w[positive_base64]` The digits are, in order,
452`0-9`
454##### Examples
456 ~zod/try=> -0w--
457 -0w--
458 ~zod/try=> ? -0w--
459 -0w--
460 @sw
461 ~zod/try=> `@sd`(sum:si -0w-A -0w--)
462 -8.034
464#### @sx
466Signed hexadecimal
468Atoms of odor `@sx` represent signed hexadecimal numbers.
470##### Forms
472`-[negative_hexadecimal]` `--[positive_hexadecimal]`
474##### Examples
476 ~~zod/try=> -0x0
477 --0x0
478 ~zod/try=> `@sd`--0x17
479 --23
480 ~zod/try=> `@ux`(bex 20)
481 0x10.0000
482 ~zod/try=> 0x10. 0000
483 0x10.0000
484 ~zod/try=> `@sd`(sum:si --0x17 -0x0)
485 --23
486 ~zod/try=> `@sd`(sum:si --0x17 -0xa)
487 --13
489------------------------------------------------------------------------
491### @t
493UTF-8 text (cord)
495Atoms of the odor `@t` represent a
496[cord](http://en.wikipedia.org/wiki/Rope_data_structure), sequence of
497UTF-8 bytes, LSB first. It is sometimes called a cord.
499##### Forms
501`~~[text]` `'[text]'`
503##### Examples
505 ~zod/try=> ~~foo
506 'foo'
507 ~zod/try=> ? 'foo'
508 'foo'
509 @t
510 ~zod/try=> ? ~~foo
511 'foo'
512 @t
514------------------------------------------------------------------------
516#### @ta
518ASCII text (span)
520Atoms of the odor `@ta` represent the ASCII text subset used in hoon
521literals: `a-z`, `0-9`, `~`, `-`, `.`, `_`.
523##### Forms
525`~.[text]` There are no escape sequences.
527##### Examples
529 ~zod/try=> ~..asdf
530 ~..asdf
531 ~zod/try=> ? ~.asdf
532 ~.asdf
533 @ta
534 ~zod/try=> `@t`~.asdf
535 'asdf'
537------------------------------------------------------------------------
539#### @tas
541ASCII symbol (term)
543Atoms of `@tas` represent [`++term`]()s, the most exclusive text odor.
544The only characters permitted are lowercase ASCII, except as the first
545or last character, and 0-9, except as the first character.
547##### Forms
549`%[text]` This means a term is always [cubical]().
551##### Examples
553 ~zod/try=> %dead-fish9
554 %dead-fish9
555 ~zod/try=> -:!>(%dead-fish9)
556 [%cube p=271.101.667.197.767.630.546.276 q=[%atom p=%tas]]
558------------------------------------------------------------------------
560### @u
562Unsigned integer
564------------------------------------------------------------------------
566#### @ub
568Unsigned binary
570Atoms of the odor `@ub` represent unsigned binary numbers.
572#### Forms
574`0b[number]` Numbers are least-significant bit first.
576##### Examples
578 ~zod/try=> `@`0b1
579 1
580 ~zod/try=> ? 0b1
581 0b1
582 @ub
583 ~zod/try=> `@`0b10
584 2
585 ~zod/try=> `@`0b100
586 4
588------------------------------------------------------------------------
590#### @ud
592Unsigned decimal
594Atoms of `@ud` represent unsigned decimal numbers. It is the default
595print format for both `@u` and and `@u`, namely unsigned numbers with no
596printing preference, as well as opaque atoms.
598##### Forms
600Numbers of more than three digits must be delimited by `.`s. Whitespace
601and linebreaks can appear between the dot and the next group.
603 ~zod/try=> 0
604 0
605 ~zod/try=> 19
606 19
607 ~zod/try=> ? 19
608 19
609 @ud
610 ~zod/try=> 1.024
611 1.024
612 ~zod/try=> 65.536
613 65.536
614 ~zod/try=> (bex 20)
615 1.048.576
617------------------------------------------------------------------------
619#### @uv
621Unsigned base32
623Atoms of the odor `@uv` represent unsigned base64 numbers.
625##### Forms
627`0v[number]` The digits are, in order, `0-9`, `a-v`.
629##### Examples
631 ~zod/try=> `@ud`0vv
632 31
633 ~zod/try=> ? 0vv
634 0vv
635 @uv
636 ~zod/try=> `@ud`(add 0vv 0v9)
637 40
639------------------------------------------------------------------------
641#### @uw
643Unsigned base64
645##### Forms
647`ow[number]` The digits are, in order, `0-9`, `a-z`, `A-Z`,`-`, and `~`.
649##### Examples
651 ~zod/try=> 0w~
652 0w~
653 ~zod/try=> ? 0w~
654 0w~
655 @uw
656 ~zod/try=> `@uv`(add 0w~ 0wZ)
657 0v3s
658 ~zod/try=> `@ud``@uv`(add 0w~ 0wZ)
659 124
661------------------------------------------------------------------------
663#### @ux
665Unsigned hexadecimal
667Atoms of the odor `@ux` represent hexadecimal numbers.
669##### Forms
671`0x`number. Numbers with more than four digits must be delimited by
672`.`s. Hex digits are lowercase only.
674 ~zod/try=> 0x0
675 0x0
676 ~zod/try=> ? 0x0
677 0x0
678 @ux
679 ~zod/try=> `@ud`0x17
680 23
681 ~zod/try=> `@ux`(bex 20)
682 0x10.0000
683 ~zod/try=> 0x10. 0000
684 0x10.0000
686------------------------------------------------------------------------