urbit/pub/docs/dev/hoon/library/2c.md
Galen Wolfe-Pauly bb495844be doc -> docs
2015-10-20 10:51:45 -07:00

2129 lines
49 KiB
Markdown

chapter 2c, simple noun surgery
===============================
section 2cA, bit surgery
------------------------
### `++bex`
Binary exponent
++ bex :: binary exponent
~/ %bex
|= a=@
^- @
?: =(0 a) 1
(mul 2 $(a (dec a)))
Computes the result of `2^a`, producing an atom.
`a` is an [atom](atom).
~zod/try=> (bex 4)
16
~zod/try=> (bex (add 19 1))
1.048.576
~zod/try=> (bex 0)
1
------------------------------------------------------------------------
### `++xeb`
Binary logarithm
++ xeb :: binary logarithm
:: ~/ %xeb
|= a=@
^- @
(met 0 a)
Computes the base-2 logarithm of `a`, producing an atom.
`a` is an [atom](atom).
~zod/try=> (xeb 31)
5
~zod/try=> (xeb 32)
6
~zod/try=> (xeb 49)
6
~zod/try=> (xeb 0)
0
~zod/try=> (xeb 1)
1
~zod/try=> (xeb 2)
2
------------------------------------------------------------------------
### `++can`
Assemble
++ can :: assemble
~/ %can
|= [a=bloq b=(list ,[p=@ q=@])]
^- @
?~ b 0
(mix (end a p.i.b q.i.b) (lsh a p.i.b $(b t.b)))
Produces an atom from a list `b` of length-value pairs `p` and `q`,
where `p` is the length in bloqs of size `a`, and `q` is an atomic
value.
`a` is a block size (see [++bloq]()).
`b` is a [list](list) of length value pairs, `p` and `q`.
~zod/try=> `@ub`(can 3 ~[[1 1]])
0b1
~zod/try=> `@ub`(can 0 ~[[1 255]])
0b1
~zod/try=> `@ux`(can 3 [3 0xc1] [1 0xa] ~)
0xa00.00c1
~zod/try=> `@ux`(can 3 [3 0xc1] [1 0xa] [1 0x23] ~)
0x23.0a00.00c1
~zod/try=> `@ux`(can 4 [3 0xc1] [1 0xa] [1 0x23] ~)
0x23.000a.0000.0000.00c1
~zod/try=> `@ux`(can 3 ~[[1 'a'] [2 'bc']])
0x63.6261
------------------------------------------------------------------------
### `++cat`
Concatenate
++ cat :: concatenate
~/ %cat
|= [a=bloq b=@ c=@]
(add (lsh a (met a b) c) b)
Concatenates two atoms, `b` and `c`, using bloq size `a`, producing an
atom.
`a` is a block size (see [++bloq]()).
`b` is an [atom]().
`c` is an [atom]().
~zod/try=> `@ub`(cat 3 1 0)
0b1
~zod/try=> `@ub`(cat 0 1 1)
0b11
~zod/try=> `@ub`(cat 0 2 1)
0b110
~zod/try=> `@ub`(cat 2 1 1)
0b1.0001
~zod/try=> `@ub`256
0b1.0000.0000
~zod/try=> `@ub`255
0b1111.1111
~zod/try=> `@ub`(cat 3 256 255)
0b1111.1111.0000.0001.0000.0000
~zod/try=> `@ub`(cat 2 256 255)
0b1111.1111.0001.0000.0000
~zod/try=> (cat 3 256 255)
16.711.936
------------------------------------------------------------------------
### `++cut`
Slice
++ cut :: slice
~/ %cut
|= [a=bloq [b=@ c=@] d=@]
(end a c (rsh a b d))
Slices `c` blocks of size `a` that are `b` blocks from the end of `d`.
Produces an atom.
`a` is a block size (see [++bloq]()).
`b` is an [atom]().
`c` is an [atom]().
~zod/try=> (cut 0 [1 1] 2)
1
~zod/try=> (cut 0 [2 1] 4)
1
~zod/try=> `@t`(cut 3 [0 3] 'abcdefgh')
'abc'
~zod/try=> `@t`(cut 3 [1 3] 'abcdefgh')
'bcd'
~zod/try=> `@ub`(cut 0 [0 3] 0b1111.0000.1101)
0b101
~zod/try=> `@ub`(cut 0 [0 6] 0b1111.0000.1101)
0b1101
~zod/try=> `@ub`(cut 0 [4 6] 0b1111.0000.1101)
0b11.0000
~zod/try=> `@ub`(cut 0 [3 6] 0b1111.0000.1101)
0b10.0001
------------------------------------------------------------------------
### `++end`
Tail
++ end :: tail
~/ %end
|= [a=bloq b=@ c=@]
(mod c (bex (mul (bex a) b)))
Produces an atom by taking the last `b` blocks of size `a` from `c`.
`a` is a block size (see [++bloq]()).
`b` is an [atom]().
`c` is an [atom]().
~zod/try=> `@ub`12
0b1100
~zod/try=> `@ub`(end 0 3 12)
0b100
~zod/try=> (end 0 3 12)
4
~zod/try=> `@ub`(end 1 3 12)
0b1100
~zod/try=> (end 1 3 12)
12
~zod/try=> `@ux`'abc'
0x63.6261
~zod/try=> `@ux`(end 3 2 'abc')
0x6261
~zod/try=> `@t`(end 3 2 'abc')
'ab'
------------------------------------------------------------------------
### `++fil`
Fill bloqstream
++ fil :: fill bloqstream
|= [a=bloq b=@ c=@]
=+ n=0
=+ d=c
|- ^- @
?: =(n b)
(rsh a 1 d)
$(d (add c (lsh a 1 d)), n +(n))
Produces an atom by repeating `c` for `b` blocks of size `a`.
`a` is a block size (see [++bloq]()).
`b` is an [atom]().
`c` is an [atom]().
~zod/try=> `@t`(fil 3 5 %a)
'aaaaa'
~zod/try=> `@t`(fil 5 10 %ceeb)
'ceebceebceebceebceebceebceebceebceebceeb'
~zod/try=> `@t`(fil 4 10 %eced)
'ʇʇʇʇʇʇʇʇʇʇed'
~zod/try=> `@tas`(fil 4 10 %bf)
%bfbfbfbfbfbfbfbfbfbf
------------------------------------------------------------------------
### `++lsh`
Left-shift
++ lsh :: left-shift
~/ %lsh
|= [a=bloq b=@ c=@]
(mul (bex (mul (bex a) b)) c)
Produces an atom by left-shifting `c` by `b` blocks of size `a`.
`a` is a block size (see [++bloq]()).
`b` is an [atom]().
`c` is an [atom]().
~zod/try=> `@ub`1
0b1
~zod/try=> `@ub`(lsh 0 1 1)
0b10
~zod/try=> (lsh 0 1 1)
2
~zod/try=> `@ub`255
0b1111.1111
~zod/try=> `@ub`(lsh 3 1 255)
0b1111.1111.0000.0000
~zod/try=> (lsh 3 1 255)
65.280
------------------------------------------------------------------------
### `++met`
Measure
++ met :: measure
~/ %met
|= [a=bloq b=@]
^- @
=+ c=0
|-
?: =(0 b) c
$(b (rsh a 1 b), c +(c))
Computes the number of blocks of size `a` in `b`, producing an atom.
`a` is a block size (see [++bloq]()).
`b` is an [atom]().
~zod/try=> (met 0 1)
1
~zod/try=> (met 0 2)
2
~zod/try=> (met 3 255)
1
~zod/try=> (met 3 256)
2
~zod/try=> (met 3 'abcde')
5
------------------------------------------------------------------------
### `++rap`
Assemble non-zero
++ rap :: assemble nonzero
~/ %rap
|= [a=bloq b=(list ,@)]
^- @
?~ b 0
(cat a i.b $(b t.b))
Concatenate a list of atoms `b` using blocksize `a`, producing an atom.
`a` is a block size (see [++bloq]()).
`b` is a [list]() of [atoms]().
~zod/try=> `@ub`(rap 2 (limo [1 2 3 4 ~]))
0b100.0011.0010.0001
~zod/try=> `@ub`(rap 1 (limo [1 2 3 4 ~]))
0b1.0011.1001
~zod/try=> (rap 0 (limo [0 0 0 ~]))
0
~zod/try=> (rap 0 (limo [1 0 1 ~]))
3
------------------------------------------------------------------------
### `++rep`
Assemble single
++ rep :: assemble single
~/ %rep
|= [a=bloq b=(list ,@)]
^- @
=+ c=0
|-
?~ b 0
(con (lsh a c (end a 1 i.b)) $(c +(c), b t.b))
Produces an atom by assembling a list of atoms `b` using block size `a`.
`a` is a block size (see [++bloq]()).
`b` is a list of [atoms]().
~zod/try=> `@ub`(rep 2 (limo [1 2 3 4 ~]))
0b100.0011.0010.0001
~zod/try=> (rep 0 (limo [0 0 1 ~]))
4
~zod/try=> (rep 0 (limo [0 0 0 1 ~]))
8
~zod/try=> (rep 0 (limo [0 1 0 0 ~]))
2
~zod/try=> (rep 0 (limo [0 1 0 1 ~]))
10
~zod/try=> (rep 0 (limo [0 1 0 1 0 1 ~]))
42
~zod/try=> `@ub`42
0b10.1010
------------------------------------------------------------------------
### `++rip`
Disassemble
++ rip :: disassemble
~/ %rip
|= [a=bloq b=@]
^- (list ,@)
?: =(0 b) ~
[(end a 1 b) $(b (rsh a 1 b))]
Produces a list of atoms from the bits of `b` using block size `a`.
`a` is a block size (see [++bloq]()).
`b` is an [atom]().
~zod/try=> `@ub`155
0b1001.1011
~zod/try=> (rip 0 155)
~[1 1 0 1 1 0 0 1]
~zod/try=> (rip 2 155)
~[11 9]
~zod/try=> (rip 1 155)
~[3 2 1 2]
~zod/try=> `@ub`256
0b1.0000.0000
~zod/try=> (rip 0 256)
~[0 0 0 0 0 0 0 0 1]
~zod/try=> (rip 2 256)
~[0 0 1]
~zod/try=> (rip 3 256)
~[0 1]
------------------------------------------------------------------------
### `++rsh`
Right-shift
++ rsh :: right-shift
~/ %rsh
|= [a=bloq b=@ c=@]
(div c (bex (mul (bex a) b)))
Right-shifts `c` by `b` blocks of size `a`, producing an atom.
`a` is a block size (see [++bloq]()).
`b` is an [atom]().
`c` is an [atom]().
~zod/try=> `@ub`145
0b1001.0001
~zod/try=> `@ub`(rsh 1 1 145)
0b10.0100
~zod/try=> (rsh 1 1 145)
36
~zod/try=> `@ub`(rsh 2 1 145)
0b1001
~zod/try=> (rsh 2 1 145)
9
~zod/try=> `@ub`10
0b1010
~zod/try=> `@ub`(rsh 0 1 10)
0b101
~zod/try=> (rsh 0 1 10)
5
~zod/try=> `@ux`'abc'
0x63.6261
~zod/try=> `@t`(rsh 3 1 'abc')
'bc'
~zod/try=> `@ux`(rsh 3 1 'abc')
0x6362
------------------------------------------------------------------------
### `++swap`
Reverse block order
++ swap |=([a=bloq b=@] (rep a (flop (rip a b)))) :: reverse bloq order
Switches little ending to big and vice versa: produces an atom by
reversing the block order of `b` using block size `a`.
`a` is a block size (see [++bloq]()).
`b` is an [atom]()
~zod/try=> `@ub`24
0b1.1000
~zod/try=> (swap 0 24)
3
~zod/try=> `@ub`3
0b11
~zod/try=> (swap 0 0)
0
~zod/try=> (swap 0 128)
1
------------------------------------------------------------------------
section 2cB, bit logic
----------------------
### `++con`
Binary OR
++ con :: binary or
~/ %con
|= [a=@ b=@]
=+ [c=0 d=0]
|- ^- @
?: ?&(=(0 a) =(0 b)) d
%= $
a (rsh 0 1 a)
b (rsh 0 1 b)
c +(c)
d %+ add d
%^ lsh 0 c
?& =(0 (end 0 1 a))
=(0 (end 0 1 b))
==
==
Computes the bit-wise logical OR of two atoms, `a` and `b`, producing an
atom.
`a` is an [atom]()
`b` is an [atom]()
~zod/try=> (con 0b0 0b1)
1
~zod/try=> (con 0 1)
1
~zod/try=> (con 0 0)
0
~zod/try=> `@ub`(con 0b1111.0000 0b1.0011)
0b1111.0011
~zod/try=> (con 4 4)
4
~zod/try=> (con 10.000 234)
10.234
------------------------------------------------------------------------
### `++dis`
Binary AND
++ dis :: binary and
~/ %dis
|= [a=@ b=@]
=| [c=@ d=@]
|- ^- @
?: ?|(=(0 a) =(0 b)) d
%= $
a (rsh 0 1 a)
b (rsh 0 1 b)
c +(c)
d %+ add d
%^ lsh 0 c
?| =(0 (end 0 1 a))
=(0 (end 0 1 b))
==
==
Computes the bit-wise logical AND of two atoms `a` and `b`, producing an
atom.
`a` is an [atom]()
`b` is an [atom]()
~zod/try=> `@ub`9
0b1001
~zod/try=> `@ub`5
0b101
~zod/try=> `@ub`(dis 9 5)
0b1
~zod/try=> (dis 9 5)
1
~zod/try=> `@ub`534
0b10.0001.0110
~zod/try=> `@ub`987
0b11.1101.1011
~zod/try=> `@ub`(dis 534 987)
0b10.0001.0010
~zod/try=> (dis 534 987)
530
------------------------------------------------------------------------
### `++mix`
Binary XOR
++ mix :: binary xor
~/ %mix
|= [a=@ b=@]
^- @
=+ [c=0 d=0]
|-
?: ?&(=(0 a) =(0 b)) d
%= $
a (rsh 0 1 a)
b (rsh 0 1 b)
c +(c)
d (add d (lsh 0 c =((end 0 1 a) (end 0 1 b))))
==
Produces the bit-wise logical XOR of `a` and `b`, producing an atom.
`a` is an [atom]()
`b` is an [atom]()
~zod/try=> `@ub`2
0b10
~zod/try=> `@ub`3
0b11
~zod/try=> `@ub`(mix 2 3)
0b1
~zod/try=> (mix 2 3)
1
~zod/try=> `@ub`(mix 2 2)
0b0
~zod/try=> (mix 2 2)
0
------------------------------------------------------------------------
### `++not`
Binary NOT
++ not |= [a=bloq b=@ c=@] :: binary not (sized)
(mix c (dec (bex (mul b (bex a)))))
Computes the bit-wise logical NOT of the bottom `b` blocks of size `a`
of `c`.
`a` is a block size (see [++bloq]()).
`b` is an [atom]().
`c` is an [atom]().
~zod/try=> `@ub`24
0b1.1000
~zod/try=> (not 0 5 24)
7
~zod/try=> `@ub`7
0b111
~zod/try=> (not 2 5 24)
1.048.551
~zod/try=> (not 2 5 1.048.551)
24
~zod/try=> (not 1 1 (not 1 1 10))
10
------------------------------------------------------------------------
section 2cC, noun orders
------------------------
### `++aor`
Alphabetic order
++ aor :: alphabetic-order
~/ %aor
|= [a=* b=*]
^- ?
?: =(a b) &
?. ?=(@ a)
?: ?=(@ b) |
?: =(-.a -.b)
$(a +.a, b +.b)
$(a -.a, b -.b)
?. ?=(@ b) &
|-
=+ [c=(end 3 1 a) d=(end 3 1 b)]
?: =(c d)
$(a (rsh 3 1 a), b (rsh 3 1 b))
(lth c d)
Computes whether `a` and `b` are in alphabetical order, producing a
loobean.
`a` is a [noun]().
`b` is a [noun]().
~zod/try=> (aor 'a' 'b')
%.y
~zod/try=> (aor 'b' 'a')
%.n
~zod/try=> (aor "foo" "bar")
%.n
~zod/try=> (aor "bar" "foo")
%.y
~zod/try=> (aor "abcdefz" "abcdefa")
%.n
~zod/try=> (aor "abcdefa" "abcdefz")
%.y
~zod/try=> (aor 10.000 17.000)
%.y
~zod/try=> (aor 10 9)
%.n
------------------------------------------------------------------------
### `++dor`
Numeric order
++ dor :: d-order
~/ %dor
|= [a=* b=*]
^- ?
?: =(a b) &
?. ?=(@ a)
?: ?=(@ b) |
?: =(-.a -.b)
$(a +.a, b +.b)
$(a -.a, b -.b)
?. ?=(@ b) &
(lth a b)
Computes whether `a` and `b` are in ascending numeric order, producing a
loobean.
`a` is a [noun]().
`b` is a [noun]().
~zod/try=> (dor 1 2)
%.y
~zod/try=> (dor 2 1)
%.n
~zod/try=> (dor ~[1 2 3] ~[1 2 4])
%.y
~zod/try=> (dor ~[1 2 4] ~[1 2 3])
%.n
~zod/try=> (dor (limo ~[99 100 10.000]) ~[99 101 10.000])
%.y
~zod/try=> (dor ~[99 101 10.999] (limo ~[99 100 10.000]))
%.n
------------------------------------------------------------------------
### `++gor`
Hash order
++ gor :: g-order
~/ %gor
|= [a=* b=*]
^- ?
=+ [c=(mug a) d=(mug b)]
?: =(c d)
(dor a b)
(lth c d)
XX revisit
~zod/try=> (gor 'd' 'c')
%.y
~zod/try=> 'd'
'd'
~zod/try=> 'c'
~zod/try=> `@ud`'d'
100
~zod/try=> `@ud`'c'
99
~zod/try=> (mug 'd')
1.628.185.714
~zod/try=> (mug 'c')
1.712.073.811
~zod/try=> (gor 'd' 'c')
%.y
~zod/try=> (gor 'c' 'd')
%.n
~zod/try=> (gor "foo" "bar")
%.n
~zod/try=> (gor (some 10) (limo [1 2 3 ~]))
%.n
------------------------------------------------------------------------
### `++hor`
Hash order
++ hor :: h-order
~/ %hor
|= [a=* b=*]
^- ?
?: ?=(@ a)
?. ?=(@ b) &
(gor a b)
?: ?=(@ b) |
?: =(-.a -.b)
(gor +.a +.b)
(gor -.a -.b)
XX revisit
Recursive hash comparator gate.
~zod/try=> (hor . 1)
%.n
~zod/try=> (hor 1 2)
%.y
~zod/try=> (hor "abc" "cba")
%.y
~zod/try=> (hor 'c' 'd')
%.n
------------------------------------------------------------------------
### `++vor`
++ vor :: v-order
~/ %vor
|= [a=* b=*]
^- ?
=+ [c=(mug (mug a)) d=(mug (mug b))]
?: =(c d)
(dor a b)
(lth c d)
XX revisit
Double hash comparator gate.
~zod/try=> (vor 'f' 'g')
%.y
~zod/try=> (vor 'a' 'z')
%.n
~zod/try=> (vor 43.326 41.106)
%.n
section 2cD, insecure hashing
-----------------------------
### `++fnv`
++ fnv |=(a=@ (end 5 1 (mul 16.777.619 a))) :: FNV scrambler
Hashes an atom with the 32-bit FNV non-cryptographic hash algorithm.
Multiplies `a` by the prime number 16,777,619 and then takes the block
of size 5 off the product's end, producing atom.
`a` is an [atom]().
~zod/try=> (fnv 10.000)
272.465.456
~zod/try=> (fnv 10.001)
289.243.075
~zod/try=> (fnv 1)
16.777.619
------------------------------------------------------------------------
### `++mum`
++ mum :: mug with murmur3
~/ %mum
|= a=*
|^ (trim ?@(a a (mix $(a -.a) (mix 0x7fff.ffff $(a +.a)))))
++ spec :: standard murmur3
|= [syd=@ key=@]
?> (lte (met 5 syd) 1)
=+ ^= row
|= [a=@ b=@]
(con (end 5 1 (lsh 0 a b)) (rsh 0 (sub 32 a) b))
=+ mow=|=([a=@ b=@] (end 5 1 (mul a b)))
=+ len=(met 5 key)
=- =. goc (mix goc len)
=. goc (mix goc (rsh 4 1 goc))
=. goc (mow goc 0x85eb.ca6b)
=. goc (mix goc (rsh 0 13 goc))
=. goc (mow goc 0xc2b2.ae35)
(mix goc (rsh 4 1 goc))
^= goc
=+ [inx=0 goc=syd]
|- ^- @
?: =(inx len) goc
=+ kop=(cut 5 [inx 1] key)
=. kop (mow kop 0xcc9e.2d51)
=. kop (row 15 kop)
=. kop (mow kop 0x1b87.3593)
=. goc (mix kop goc)
=. goc (row 13 goc)
=. goc (end 5 1 (add 0xe654.6b64 (mul 5 goc)))
$(inx +(inx))
::
++ trim :: 31-bit nonzero
|= key=@
=+ syd=0xcafe.babe
|- ^- @
=+ haz=(spec syd key)
=+ ham=(mix (rsh 0 31 haz) (end 0 31 haz))
?.(=(0 ham) ham $(syd +(syd)))
--
::
XX document
~zod/try=> (mum 10.000)
1.232.632.901
~zod/try=> (mum 10.001)
658.093.079
~zod/try=> (mum 1)
818.387.364
~zod/try=> (mum (some 10))
1.177.215.703
~zod/try=> (mum ~[1 2 3 4 5])
1.517.902.092
### `++mug`
++ mug :: 31bit nonzero FNV1a
~/ %mug
|= a=*
?^ a
=+ b=[p=$(a -.a) q=$(a +.a)]
|- ^- @
=+ c=(fnv (mix p.b (fnv q.b)))
=+ d=(mix (rsh 0 31 c) (end 0 31 c))
?. =(0 c) c
$(q.b +(q.b))
=+ b=2.166.136.261
|- ^- @
=+ c=b
=+ [d=0 e=(met 3 a)]
|- ^- @
?: =(d e)
=+ f=(mix (rsh 0 31 c) (end 0 31 c))
?. =(0 f) f
^$(b +(b))
$(c (fnv (mix c (cut 3 [d 1] a))), d +(d))
Hashes `a` with the 31-bit nonzero FNV-1a non-cryptographic hash
algorithm, producing an atom.
~zod/try=> (mug 10.000)
178.152.889
~zod/try=> (mug 10.001)
714.838.017
~zod/try=> (mug 1)
67.918.732
~zod/try=> (mug (some 10))
1.872.403.737
~zod/try=> (mug (limo [1 2 3 4 5 ~]))
1.067.931.605
section 2cE, phonetic base
--------------------------
### `++po`
++ po
~/ %po
=+ :- ^= sis :: prefix syllables
'dozmarbinwansamlitsighidfidlissogdirwacsabwissib\
/rigsoldopmodfoglidhopdardorlorhodfolrintogsilmir\
/holpaslacrovlivdalsatlibtabhanticpidtorbolfosdot\
/losdilforpilramtirwintadbicdifrocwidbisdasmidlop\
/rilnardapmolsanlocnovsitnidtipsicropwitnatpanmin\
/ritpodmottamtolsavposnapnopsomfinfonbanporworsip\
/ronnorbotwicsocwatdolmagpicdavbidbaltimtasmallig\
/sivtagpadsaldivdactansidfabtarmonranniswolmispal\
/lasdismaprabtobrollatlonnodnavfignomnibpagsopral\
/bilhaddocridmocpacravripfaltodtiltinhapmicfanpat\
/taclabmogsimsonpinlomrictapfirhasbosbatpochactid\
/havsaplindibhosdabbitbarracparloddosbortochilmac\
/tomdigfilfasmithobharmighinradmashalraglagfadtop\
/mophabnilnosmilfopfamdatnoldinhatnacrisfotribhoc\
/nimlarfitwalrapsarnalmoslandondanladdovrivbacpol\
/laptalpitnambonrostonfodponsovnocsorlavmatmipfap'
^= dex :: suffix syllables
'zodnecbudwessevpersutletfulpensytdurwepserwylsun\
/rypsyxdyrnuphebpeglupdepdysputlughecryttyvsydnex\
/lunmeplutseppesdelsulpedtemledtulmetwenbynhexfeb\
/pyldulhetmevruttylwydtepbesdexsefwycburderneppur\
/rysrebdennutsubpetrulsynregtydsupsemwynrecmegnet\
/secmulnymtevwebsummutnyxrextebfushepbenmuswyxsym\
/selrucdecwexsyrwetdylmynmesdetbetbeltuxtugmyrpel\
/syptermebsetdutdegtexsurfeltudnuxruxrenwytnubmed\
/lytdusnebrumtynseglyxpunresredfunrevrefmectedrus\
/bexlebduxrynnumpyxrygryxfeptyrtustyclegnemfermer\
/tenlusnussyltecmexpubrymtucfyllepdebbermughuttun\
/bylsudpemdevlurdefbusbeprunmelpexdytbyttyplevmyl\
/wedducfurfexnulluclennerlexrupnedlecrydlydfenwel\
/nydhusrelrudneshesfetdesretdunlernyrsebhulryllud\
/remlysfynwerrycsugnysnyllyndyndemluxfedsedbecmun\
/lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes'
|%
Provides the phonetic syllables and name generators for the Urbit naming
system. The two faces, `sis` and `dex` are available to the arms
contained in this section.
------------------------------------------------------------------------
### `++ind`
Parse prefix
++ ind ~/ %ind :: parse prefix
|= a=@
=+ b=0
|- ^- (unit ,@)
?:(=(256 b) ~ ?:(=(a (tod b)) [~ b] $(b +(b))))
Produces the byte of the right-hand syllable `a`.
`a` is an [atom]().
~zod/try=> (ind:po 'zod')
[~ 0]
~zod/try=> (ind:po 'zam')
~
~zod/try=> (ind:po 'del')
[~ 37]
------------------------------------------------------------------------
### `++ins`
Parse suffix
++ ins ~/ %ins :: parse suffix
|= a=@
=+ b=0
|- ^- (unit ,@)
?:(=(256 b) ~ ?:(=(a (tos b)) [~ b] $(b +(b))))
Produces the byte of the left-hand phonetic syllable `b`.
`a` is an [atom]().
~zod/try=> (ins:po 'mar')
[~ 1]
~zod/try=> (ins:po 'son')
[~ 164]
~zod/try=> (ins:po 'pit')
[~ 242]
~zod/try=> (ins:po 'pok')
~
------------------------------------------------------------------------
### `++tod`
Fetch prefix
++ tod ~/ %tod :: fetch prefix
|=(a=@ ?>((lth a 256) (cut 3 [(mul 3 a) 3] dex)))
Produces the phonetic prefix syllable from index `a` within `dex` as an
atom.
`a` is an [atom]()
~zod/try=> `@t`(tod:po 1)
'nec'
~zod/try=> `@t`(tod:po 98)
'dec'
~zod/try=> `@t`(tod:po 0)
'zod'
~zod/try=> `@t`(tod:po 150)
'ryg'
~zod/try=> `@t`(tod:po 255)
'fes'
~zod/try=> `@t`(tod:po 256)
! exit
------------------------------------------------------------------------
### `++tos`
Fetch suffix
++ tos ~/ %tos :: fetch suffix
|=(a=@ ?>((lth a 256) (cut 3 [(mul 3 a) 3] sis)))
Produces the phonetic prefix syllable from index `a` within `sis` as an
atom.
~zod/try=> `@t`(tos:po 0)
'doz'
~zod/try=> `@t`(tos:po 120)
'fab'
~zod/try=> `@t`(tos:po 43)
'pid'
~zod/try=> `@t`(tos:po 253)
'mat'
------------------------------------------------------------------------
section 2cF, signed and modular ints
------------------------------------
### `++si`
++ si !: :: signed integer
|%
Container for the signed integer functions.
------------------------------------------------------------------------
### `++abs`
++ abs |=(a=@s (add (end 0 1 a) (rsh 0 1 a))) :: absolute value
Produces the absolute value of a signed integer.
`a` is a signed integer, `@s`.
~zod/try=> (abs:si -2)
2
~zod/try=> (abs:si -10.000)
10.000
~zod/try=> (abs:si --2)
2
------------------------------------------------------------------------
### `++dif`
++ dif |= [a=@s b=@s] :: subtraction
(sum a (new !(syn b) (abs b)))
Produces the difference between two signed integers `b` and `c`.
`a` is a signed integer, `@s`.
`b` is a signed integer, `@s`.
~zod/try=> (dif:si --10 -7)
--17
~zod/try=> (dif:si --10 --7)
--3
~zod/try=> (dif:si `@s`0 --7)
-7
~zod/try=> (dif:si `@s`0 `@s`7)
--4
------------------------------------------------------------------------
### `++dul`
++ dul |= [a=@s b=@] :: modulus
=+(c=(old a) ?:(-.c (mod +.c b) (sub b +.c)))
Produces the modulus of two signed integers.
`a` is a signed integer, `@s`.
`b` is an [atom]().
~zod/try=> (dul:si --9 3)
0
~zod/try=> (dul:si --9 4)
1
~zod/try=> (dul:si --9 5)
4
~zod/try=> (dul:si --9 6)
3
~zod/try=> (dul:si --90 --10)
10
------------------------------------------------------------------------
### `++fra`
++ fra |= [a=@s b=@s] :: divide
(new =(0 (mix (syn a) (syn b))) (div (abs a) (abs b)))
Produces the quotient of two signed integers.
`a` is a signed integer, `@s`.
`b` is a signed integer, `@s`.
~zod/try=> (fra:si --10 -2)
-5
~zod/try=> (fra:si -20 -5)
--4
------------------------------------------------------------------------
### `++new`
++ new |= [a=? b=@] :: [sign value] to @s
`@s`?:(a (mul 2 b) ?:(=(0 b) 0 +((mul 2 (dec b)))))
Produces a signed integer from a loobean sign value `a` and an atom `b`.
`a` is a loobean.
`b` is an [atom]().
~zod/try=> (new:si [& 10])
--10
~zod/try=> (new:si [| 10])
-10
~zod/try=> (new:si [%.y 7])
--7
------------------------------------------------------------------------
### `++old`
++ old |=(a=@s [(syn a) (abs a)]) :: [sign value]
Produces the cell `[sign value]` representations of a signed integer.
`a` is a signed integer, `@s`.
~zod/try=> (old:si 7)
! type-fail
! exit
~zod/try=> (old:si -7)
[%.n 7]
~zod/try=> (old:si --7)
[%.y 7]
~zod/try=> (old:si `@s`7)
[%.n 4]
~zod/try=> (old:si -0)
[%.y 0]
------------------------------------------------------------------------
### `++pro`
++ pro |= [a=@s b=@s] :: multiplication
(new =(0 (mix (syn a) (syn b))) (mul (abs a) (abs b)))
Produces the product of two signed integers.
`a` is a signed integer, `@s`.
`b` is a signed integer, `@s`.
~zod/try=> (pro:si -4 --2)
-8
~zod/try=> (pro:si -4 -2)
--8
~zod/try=> (pro:si --10.000.000 -10)
-100.000.000
~zod/try=> (pro:si -1.337 --0)
--0
------------------------------------------------------------------------
### `++rem`
++ rem |=([a=@s b=@s] (dif a (pro b (fra a b)))) :: remainder
Produces the remainder from a division of two signed integers.
`a` is a signed integer, `@s`.
`b` is a signed integer, `@s`.
~zod/try=> (rem:si -10 -4)
-2
~zod/try=> (rem:si --10 --4)
--2
~zod/try=> (rem:si --10 -4)
--2
~zod/try=> (rem:si --7 --3)
--1
~zod/try=> (rem:si --0 --10.000)
--0
------------------------------------------------------------------------
### `++sum`
++ sum |= [a=@s b=@s] :: addition
~| %si-sum
=+ [c=(old a) d=(old b)]
?: -.c
?: -.d
(new & (add +.c +.d))
?: (gte +.c +.d)
(new & (sub +.c +.d))
(new | (sub +.d +.c))
?: -.d
?: (gte +.c +.d)
(new | (sub +.c +.d))
(new & (sub +.d +.c))
(new | (add +.c +.d))
Sum two signed integers.
`b` is a signed integer, `@s`.
`c` is a signed integer, `@s`.
~zod/try=> (sum:si --10 --10)
--20
~zod/try=> (sum:si --10 -0)
--10
~zod/try=> (sum:si -10 -7)
-17
~zod/try=> (sum:si -10 --7)
-3
------------------------------------------------------------------------
### `++sun`
++ sun |=(a=@u (mul 2 a)) :: @u to @s
Produces a signed integer from an unsigned integer.
Note that the result must be manually cast to some @s odor to be
inferred as an unsigned integer in the type system.
`a` is an unsigned integer, `@u`.
~zod/try=> `@s`10
--5
~zod/try=> (sun:si 10)
20
~zod/try=> `@s`(sun:si 10)
--10
~zod/try=> `@sd`(sun:si 10)
--10
~zod/try=> `@sd`(sun:si 12.345)
--12.345
------------------------------------------------------------------------
### `++syn`
++ syn |=(a=@s =(0 (end 0 1 a))) :: sign test
Produce the sign of a signed integer, `&` being posiitve, `|` negative.
`a` is a signed integer, `@s`.
~zod/try=> (syn:si -2)
%.n
~zod/try=> (syn:si --2)
%.y
~zod/try=> (syn:si -0)
%.y
------------------------------------------------------------------------
### `++cmp`
++ cmp |= [a=@s b=@s] :: compare
^- @s
?: =(a b)
--0
?: (syn a)
?: (syn b)
?: (gth a b)
--1
-1
--1
?: (syn b)
-1
?: (gth a b)
-1
--1
Compare two signed integers.
`b` is a signed integer, `@s`.
`c` is a signed integer, `@s`.
~zod/try=> (cmp:si --10 --10)
--0
~zod/try=> (cmp:si --10 -0)
--1
~zod/try=> (cmp:si -10 -7)
-1
~zod/try=> (cmp:si -10 --7)
-1
### `++dif`
++ dif |=([b=@ c=@] (sit (sub (add out (sit b)) (sit c))))
Produces the difference between two atoms in the modular basis
representation.
`b` is an [atom]().
`c` is an [atom]().
~zod/try=> (~(dif fe 3) 63 64)
255
~zod/try=> (~(dif fe 3) 5 10)
251
~zod/try=> (~(dif fe 3) 0 1)
255
~zod/try=> (~(dif fe 0) 9 10)
1
~zod/try=> (~(dif fe 0) 9 11)
0
~zod/try=> (~(dif fe 0) 9 12)
1
~zod/try=> (~(dif fe 2) 9 12)
13
~zod/try=> (~(dif fe 2) 63 64)
15
------------------------------------------------------------------------
### `++inv`
++ inv |=(b=@ (sub (dec out) (sit b)))
Inverts the order of the modular field.
`b` is an [atom]().
~zod/try=> (~(inv fe 3) 255)
0
~zod/try=> (~(inv fe 3) 256)
255
~zod/try=> (~(inv fe 3) 0)
255
~zod/try=> (~(inv fe 3) 1)
254
~zod/try=> (~(inv fe 3) 2)
253
~zod/try=> (~(inv fe 3) 55)
200
------------------------------------------------------------------------
### `++net`
++ net |= b=@ ^- @
=> .(b (sit b))
?: (lte a 3)
b
=+ c=(dec a)
%+ con
(lsh c 1 $(a c, b (cut c [0 1] b)))
$(a c, b (cut c [1 1] b))
Reverse bytes within block.
`b` is an [atom]().
~zod/try=> (~(net fe 3) 64)
64
~zod/try=> (~(net fe 3) 128)
128
~zod/try=> (~(net fe 3) 255)
255
~zod/try=> (~(net fe 3) 256)
0
~zod/try=> (~(net fe 3) 257)
1
~zod/try=> (~(net fe 3) 500)
244
~zod/try=> (~(net fe 3) 511)
255
~zod/try=> (~(net fe 3) 512)
0
~zod/try=> (~(net fe 3) 513)
1
~zod/try=> (~(net fe 3) 0)
0
~zod/try=> (~(net fe 3) 1)
1
~zod/try=> (~(net fe 0) 1)
1
~zod/try=> (~(net fe 0) 2)
0
~zod/try=> (~(net fe 0) 3)
1
~zod/try=> (~(net fe 6) 1)
72.057.594.037.927.936
~zod/try=> (~(net fe 6) 2)
144.115.188.075.855.872
~zod/try=> (~(net fe 6) 3)
216.172.782.113.783.808
~zod/try=> (~(net fe 6) 4)
288.230.376.151.711.744
~zod/try=> (~(net fe 6) 5)
360.287.970.189.639.680
~zod/try=> (~(net fe 6) 6)
432.345.564.227.567.616
~zod/try=> (~(net fe 6) 7)
504.403.158.265.495.552
~zod/try=> (~(net fe 6) 512)
562.949.953.421.312
~zod/try=> (~(net fe 6) 513)
72.620.543.991.349.248
------------------------------------------------------------------------
### `++out`
++ out (bex (bex a))
The maximum integer value that the current block can store.
~zod/try=> ~(out fe 0)
2
~zod/try=> ~(out fe 1)
4
~zod/try=> ~(out fe 2)
16
~zod/try=> ~(out fe 3)
256
~zod/try=> ~(out fe 4)
65.536
~zod/try=> ~(out fe 10)
\/179.769.313.486.231.590.772.930.519.078.902.473.361.797.697.894.230.657.\/
273.430.081.157.732.675.805.500.963.132.708.477.322.407.536.021.120.113.
879.871.393.357.658.789.768.814.416.622.492.847.430.639.474.124.377.767.
893.424.865.485.276.302.219.601.246.094.119.453.082.952.085.005.768.838.
150.682.342.462.881.473.913.110.540.827.237.163.350.510.684.586.298.239.
947.245.938.479.716.304.835.356.329.624.224.137.216
\/ \/
------------------------------------------------------------------------
### `++rol`
++ rol |= [b=bloq c=@ d=@] ^- @ :: roll left
=+ e=(sit d)
=+ f=(bex (sub a b))
=+ g=(mod c f)
(sit (con (lsh b g e) (rsh b (sub f g) e)))
Roll `d` to the left by `c` `b`-sized blocks.
`b` is a block size (see [++bloq]()).
`c` is an [atom]().
`d` is an [atom]().
~zod/try=> `@ux`(~(rol fe 6) 4 3 0xabac.dedf.1213)
0x1213.0000.abac.dedf
~zod/try=> `@ux`(~(rol fe 6) 4 2 0xabac.dedf.1213)
0xdedf.1213.0000.abac
~zod/try=> `@t`(~(rol fe 5) 3 1 'dfgh')
'hdfg'
~zod/try=> `@t`(~(rol fe 5) 3 2 'dfgh')
'ghdf'
~zod/try=> `@t`(~(rol fe 5) 3 0 'dfgh')
'dfgh'
------------------------------------------------------------------------
### `++ror`
++ ror |= [b=bloq c=@ d=@] ^- @ :: roll right
=+ e=(sit d)
=+ f=(bex (sub a b))
=+ g=(mod c f)
(sit (con (rsh b g e) (lsh b (sub f g) e)))
Roll `d` to the right by `c` `b`-sized blocks.
`b` is a block size (see [++bloq]()).
`c` is an [atom]().
`d` is an [atom]().
~zod/try=> `@ux`(~(ror fe 6) 4 1 0xabac.dedf.1213)
0x1213.0000.abac.dedf
~zod/try=> `@ux`(~(ror fe 6) 3 5 0xabac.dedf.1213)
0xacde.df12.1300.00ab
~zod/try=> `@ux`(~(ror fe 6) 3 3 0xabac.dedf.1213)
0xdf12.1300.00ab.acde
~zod/try=> `@t`(~(rol fe 5) 3 0 'hijk')
'hijk'
~zod/try=> `@t`(~(rol fe 5) 3 1 'hijk')
'khij'
~zod/try=> `@t`(~(rol fe 5) 3 2 'hijk')
'jkhi'
------------------------------------------------------------------------
### `++sum`
++ sum |=([b=@ c=@] (sit (add b c))) :: wrapping add
Sum two numbers in this modular field.
`b` is an [atom]().
`c` is an [atom]().
~zod/try=> (~(sum fe 3) 10 250)
4
~zod/try=> (~(sum fe 0) 0 1)
1
~zod/try=> (~(sum fe 0) 0 2)
0
~zod/try=> (~(sum fe 2) 14 2)
0
~zod/try=> (~(sum fe 2) 14 3)
1
~zod/try=> (~(sum fe 4) 10.000 256)
10.256
~zod/try=> (~(sum fe 4) 10.000 100.000)
44.464
### `++sit`
++ sit |=(b=@ (end a 1 b)) :: enforce modulo
Produce an atom in the current modular block representation.
`b` is an [atom]().
~zod/try=> (~(sit fe 3) 255)
255
~zod/try=> (~(sit fe 3) 256)
0
~zod/try=> (~(sit fe 3) 257)
1
~zod/try=> (~(sit fe 2) 257)
1
~zod/try=> (~(sit fe 2) 10.000)
0
~zod/try=> (~(sit fe 2) 100)
4
~zod/try=> (~(sit fe 2) 19)
3
~zod/try=> (~(sit fe 2) 17)
1
~zod/try=> (~(sit fe 0) 17)
1
~zod/try=> (~(sit fe 0) 0)
0
~zod/try=> (~(sit fe 0) 1)
1
------------------------------------------------------------------------
section 2cG, floating point
---------------------------
XX awaiting interface rewrite
section 2cH, urbit time
-----------------------
Note that entering '-\<-' in the shell produces the current time in @da
format. We use this for many of our examples.
~zod/try=> -<-
~2014.8.4..19.39.59..9288
### `++year`
++ year :: date to @d
|= det=date
^- @d
=+ ^= yer
?: a.det
(add 292.277.024.400 y.det)
(sub 292.277.024.400 (dec y.det))
=+ day=(yawn yer m.det d.t.det)
(yule day h.t.det m.t.det s.t.det f.t.det)
Accept a parsed date of form `[[a=? y=@ud] m=@ud t=tarp]` and produce
its `@d`representation.
`det` is a [`++date`]()
~zod/try=> (year [[a=%.y y=2.014] m=8 t=[d=4 h=20 m=4 s=57 f=~[0xd940]]])
0x8000000d227df4e9d940000000000000
------------------------------------------------------------------------
### `++yore`
++ yore :: @d to date
|= now=@d
^- date
=+ rip=(yell now)
=+ ger=(yall d.rip)
:- ?: (gth y.ger 292.277.024.400)
[a=& y=(sub y.ger 292.277.024.400)]
[a=| y=+((sub 292.277.024.400 y.ger))]
[m.ger d.ger h.rip m.rip s.rip f.rip]
Produces a `++date` from a `@d`
`now` is a `@d`.
~zod/try=> (yore -<-)
[[a=%.y y=2.014] m=8 t=[d=4 h=20 m=17 s=1 f=~[0x700d]]]
~zod/try=> (yore -<-)
[[a=%.y y=2.014] m=8 t=[d=4 h=20 m=28 s=53 f=~[0x7b82]]]
### `++yell`
++ yell :: tarp from @d
|= now=@d
^- tarp
=+ sec=(rsh 6 1 now)
=+ ^= fan
=+ [muc=4 raw=(end 6 1 now)]
|- ^- (list ,@ux)
?: |(=(0 raw) =(0 muc))
~
=> .(muc (dec muc))
[(cut 4 [muc 1] raw) $(raw (end 4 muc raw))]
=+ day=(div sec day:yo)
=> .(sec (mod sec day:yo))
=+ hor=(div sec hor:yo)
=> .(sec (mod sec hor:yo))
=+ mit=(div sec mit:yo)
=> .(sec (mod sec mit:yo))
[day hor mit sec fan]
Produce a parsed daily time format from an atomic date.
`now` is a `@d`.
~zod/try=> (yell ~2014.3.20..05.42.53..7456)
[d=106.751.991.820.094 h=5 m=42 s=53 f=~[0x7456]]
~zod/try=> (yell ~2014.6.9..19.09.40..8b66)
[d=106.751.991.820.175 h=19 m=9 s=40 f=~[0x8b66]]
~zod/try=> (yell ~1776.7.4)
[d=106.751.991.733.273 h=0 m=0 s=0 f=~]
------------------------------------------------------------------------
### `++yule`
++ yule :: time atom
|= rip=tarp
^- @d
=+ ^= sec ;: add
(mul d.rip day:yo)
(mul h.rip hor:yo)
(mul m.rip mit:yo)
s.rip
==
=+ ^= fac =+ muc=4
|- ^- @
?~ f.rip
0
=> .(muc (dec muc))
(add (lsh 4 muc i.f.rip) $(f.rip t.f.rip))
(con (lsh 6 1 sec) fac)
Accept a [`++tarp`](/doc/hoon/library/1#++tarp), a parsed daily time, and produces a time atom,
`@d`.
`rip` is a [`++tarp`](/doc/hoon/library/1#++tarp).
~zod/try=> =murica (yell ~1776.7.4)
~zod/try=> murica
[d=106.751.991.733.273 h=0 m=0 s=0 f=~]
~zod/try=> (yule murica)
0x8000000b62aaf5800000000000000000
~zod/try=> `@da`(yule murica)
~1776.7.4
~zod/try=> `@da`(yule (yell ~2014.3.20..05.42.53..7456))
~2014.3.20..05.42.53..7456
~zod/try=> `tarp`[31 12 30 0 ~]
[d=31 h=12 m=30 s=0 f=~]
~zod/try=> `@dr`(yule `tarp`[31 12 30 0 ~])
~d31.h12.m30
------------------------------------------------------------------------
### `++yall`
++ yall :: day # to day of year
|= day=@ud
^- [y=@ud m=@ud d=@ud]
=+ [era=0 cet=0 lep=_?]
=> .(era (div day era:yo), day (mod day era:yo))
=> ^+ .
?: (lth day +(cet:yo))
.(lep &, cet 0)
=> .(lep |, cet 1, day (sub day +(cet:yo)))
.(cet (add cet (div day cet:yo)), day (mod day cet:yo))
=+ yer=(add (mul 400 era) (mul 100 cet))
|- ^- [y=@ud m=@ud d=@ud]
=+ dis=?:(lep 366 365)
?. (lth day dis)
=+ ner=+(yer)
$(yer ner, day (sub day dis), lep =(0 (end 0 2 ner)))
|- ^- [y=@ud m=@ud d=@ud]
=+ [mot=0 cah=?:(lep moy:yo moh:yo)]
|- ^- [y=@ud m=@ud d=@ud]
=+ zis=(snag mot cah)
?: (lth day zis)
[yer +(mot) +(day)]
$(mot +(mot), day (sub day zis))
Produce the date tuple of `[y=@ud m=@ud d=@ud]` of the year, month, and
day from a number of days from the beginning of time.
`day` is an unsigned decimal, `@ud`.
~zod/try=> (yall 198)
[y=0 m=7 d=17]
~zod/try=> (yall 90.398)
[y=247 m=7 d=3]
~zod/try=> (yall 0)
[y=0 m=1 d=1]
------------------------------------------------------------------------
### `++yawn`
++ yawn :: days since Jesus
|= [yer=@ud mot=@ud day=@ud]
^- @ud
=> .(mot (dec mot), day (dec day))
=> ^+ .
%= .
day
=+ cah=?:((yelp yer) moy:yo moh:yo)
|- ^- @ud
?: =(0 mot)
day
$(mot (dec mot), cah (slag 1 cah), day (add day (snag 0 cah)))
==
|- ^- @ud
?. =(0 (mod yer 4))
=+ ney=(dec yer)
$(yer ney, day (add day ?:((yelp ney) 366 365)))
?. =(0 (mod yer 100))
=+ nef=(sub yer 4)
$(yer nef, day (add day ?:((yelp nef) 1.461 1.460)))
?. =(0 (mod yer 400))
=+ nec=(sub yer 100)
$(yer nec, day (add day ?:((yelp nec) 36.525 36.524)))
(add day (mul (div yer 400) (add 1 (mul 4 36.524))))
Inverse of `yall`, computes number of days A.D. from y/m/d date as the
tuple `[yer=@ud mot=@ud day=@ud]`.
`yer` is an unsigned decimal, `@ud`.
`mon` is an unsigned decimal, `@ud`.
`day` is an unsigned decimal, `@ud`.
~zod/try=> (yawn 2.014 8 4)
735.814
~zod/try=> (yawn 1.776 7 4)
648.856
~zod/try=> (yawn 1.990 10 11)
727.116
------------------------------------------------------------------------
### `++yelp`
++ yelp :: leap year
|= yer=@ud ^- ?
&(=(0 (mod yer 4)) |(!=(0 (mod yer 100)) =(0 (mod yer 400))))
Determines whether a year contains an ISO 8601 leap week. Produces a
loobean.
`yer` is an unsigned decimal, `@ud`.
~zod/try=> (yelp 2.014)
%.n
~zod/try=> (yelp 2.008)
%.y
~zod/try=> (yelp 0)
%.y
~zod/try=> (yelp 14.011)
%.n
------------------------------------------------------------------------
### `++yo`
++ yo :: time constants
Useful constants for interacting with earth time.
### `++cet`
|% ++ cet 36.524 :: (add 24 (mul 100 365))
Days in a century. Derived by multiplying the number of days in a year
(365) by the number of years in a century (100), then adding the number
days from leap years in a century (24).
~zod/try=> cet:yo
36.524
~zod/try=> (add 365 cet:yo)
36.889
~zod/try=> (sub (add 24 (mul 100 365)) cet:yo)
0
------------------------------------------------------------------------
### `++day`
++ day 86.400 :: (mul 24 hor)
Number of seconds in a day.
~zod/try=> day:yo
86.400
~zod/try=> (add 60 day:yo)
86.460
------------------------------------------------------------------------
### `++era`
++ era 146.097 :: (add 1 (mul 4 cet))
XX Revisit
------------------------------------------------------------------------
### `++hor`
++ hor 3.600 :: (mul 60 mit)
The number of seconds in an hour. Derived by multiplying the number of
seconds in a minute by the minutes in an hour.
~zod/try=> hor:yo
3.600
~zod/try=> (div hor:yo 60)
60
------------------------------------------------------------------------
### `++jes`
++ jes 106.751.991.084.417 :: (mul 730.692.561 era)
XX Revisit
~zod/try=> jes:yo
106.751.991.084.417
------------------------------------------------------------------------
### `++mit`
++ mit 60
The number of seconds in a minute.
~zod/try=> mit:yo
60
------------------------------------------------------------------------
### `++moh`
++ moh `(list ,@ud)`[31 28 31 30 31 30 31 31 30 31 30 31 ~]
The days in each month of the Gregorian common year. A list of unsigned
decimal atoms (Either 28, 30, or 31) denoting the number of days in the
month at the year at that index.
~zod/try=> moh:yo
~[31 28 31 30 31 30 31 31 30 31 30 31]
~zod/try=> (snag 4 moh:yo)
31
------------------------------------------------------------------------
### `++moy`
++ moy `(list ,@ud)`[31 29 31 30 31 30 31 31 30 31 30 31 ~]
The days in each month of the Gregorian leap-year. A list of unsigned
decimal atoms (Either 29,30, or 31) denoting the number of days in the
month at the leap-year at that index.
~zod/try=> moy:yo
~[31 29 31 30 31 30 31 31 30 31 30 31]
~zod/try=> (snag 1 moy:yo)
29
------------------------------------------------------------------------
### `++qad`
++ qad 126.144.001 :: (add 1 (mul 4 yer))
The number of seconds in four years. Derived by adding one second to the
number of seconds in four years.
~zod/try=> qad:yo
126.144.001
------------------------------------------------------------------------
### `++yer`
++ yer 31.536.000 :: (mul 365 day)
The number of seconds in a year. Derived by multiplying the number of
seconds in a day by 365.
~zod/try=> yer:yo
31.536.000
------------------------------------------------------------------------
section 2cI, almost macros
--------------------------
### `++cury`
++ cury
|* [a=_|=(^ _*) b=*]
|* c=_+<+.a
(a b c)
Curry a gate, binding the head of its sample
`a` is a [gate]().
`b` is a noun.
~zod/try=> =mol (cury add 2)
~zod/try=> (mol 4)
6
~zod/try=> (mol 7)
9
------------------------------------------------------------------------
### `++curr`
++ curr
|* [a=_|=(^ _*) c=*]
|* b=_+<+.a
(a b c)
Right curry a gate, binding the tail of its sample
`a` is a gate.
`c` is a noun.
~zod/try=> =tep (curr scan sym)
~zod/try=> `@t`(tep "asd")
'asd'
~zod/try=> `@t`(tep "lek-om")
'lek-om'
------------------------------------------------------------------------
### `++cork`
++ cork |*([a=_,* b=gate] (corl b a)) :: compose forward
Build `f` such that `(f x) .= (b (a x))`.
`a` is a noun.
`b` is a gate.
~zod/try=> (:(cork dec dec dec) 20)
17
~zod/try=> =mal (mo (limo a/15 b/23 ~))
~zod/try=> ((cork ~(got by mal) dec) %a)
14
~zod/try=> ((cork ~(got by mal) dec) %b)
22
------------------------------------------------------------------------
### `++corl`
++ corl :: compose backwards
|* [a=gate b=_,*]
|= c=_+<.b
(a (b c))
Gate compose
XX Revisit
`a` is a gate.
`b` is a noun.
~zod/try=> ((corl (lift bex) (slat %ud)) '2')
[~ 4]
------------------------------------------------------------------------
### `++hard`
++ hard
|* han=$+(* *)
|= fud=* ^- han
~| %hard
=+ gol=(han fud)
?>(=(gol fud) gol)
Demands that a specific type be produced, crashing the program is it is
not.
~zod/try=> ((hard (list)) (limo [1 2 3 ~]))
~[1 2 3]
~zod/try=> ((hard ,@) (add 2 2))
4
~zod/try=> ((hard ,@t) (crip "Tape to cord, bro!"))
'Tape to cord, bro'
~zod/try=> ((hard tape) (crip "...Tape to cord, bro?..."))
! hard
! exit
------------------------------------------------------------------------
### `++soft`
++ soft
|* han=$+(* *)
|= fud=* ^- (unit han)
=+ gol=(han fud)
?.(=(gol fud) ~ [~ gol])
Politely requests a specific type to be produced, producing null if it
is not.
~zod/try=> ((soft ,%4) (add 2 2))
[~ %4]
~zod/try=> ((soft ,@) (add 2 2))
[~ 4]
~zod/try=> ((soft ,%5) (add 2 2))
~
~zod/try=> ((soft ,@t) (crip "Tape to cord, Woohoo!"))
[~ 'Tape to cord, Woohoo!']
~zod/try=> ((soft ,@t) (trip 'Cmon man... Tape to cord? Please?!'))
~
------------------------------------------------------------------------