+++ title = "4n: Virtualization" weight = 41 template = "doc.html" +++ ## `++mack` Nock subject to unit Accepts a nock subject-formula cell and wraps it into a `unit`. `fol` is pure nock, meaning that nock `11` operations result in a block, producing a `~`. #### Accepts `sub` is a subject noun. `fol` is a formula noun, which is generally a `nock`. #### Produces The `unit` of a noun. #### Source ```hoon ++ mack |= [sub=* fol=*] ^- (unit) =/ ton (mink [sub fol] |~(^ ~)) ?.(?=(%0 -.ton) ~ `product.ton) ``` #### Examples ``` > (mack [[1 2 3] [0 1]]) [~ [1 2 3]] > (mack [41 4 0 1]) [~ 42] > (mack [4 0 4]) ~ > (mack [[[0 2] [1 3]] 4 4 4 4 0 5]) [~ 6] > ;;((unit @tas) (mack [[1 %yes %no] 6 [0 2] [0 6] 0 7])) [~ %no] ``` --- ## `++mink` Mock interpreter Bottom-level mock (virtual nock) interpreter. Produces a `tone`, a nock computation result. If nock 12 is invoked, `scry` computes on the subject and produces a `(unit (unit))` result. An empty result becomes a `%1` `tone`, indicating a block. #### Accepts `subject` is the subject as a noun. `formula` is the formula as a noun. `scry` is an `%iron` gate invoked with nock operator 12. #### Produces A `tone`. #### Source ```hoon ++ mink !. ~/ %mink |= $: [subject=* formula=*] scry=$-(^ (unit (unit))) == =| trace=(list [@ta *]) |^ ^- tone ?+ formula [%2 trace] [^ *] =/ head $(formula -.formula) ?. ?=(%0 -.head) head =/ tail $(formula +.formula) ?. ?=(%0 -.tail) tail [%0 product.head product.tail] :: [%0 axis=@] =/ part (frag axis.formula subject) ?~ part [%2 trace] [%0 u.part] :: [%1 constant=*] [%0 constant.formula] :: [%2 subject=* formula=*] =/ subject $(formula subject.formula) ?. ?=(%0 -.subject) subject =/ formula $(formula formula.formula) ?. ?=(%0 -.formula) formula %= $ subject product.subject formula product.formula == :: [%3 argument=*] =/ argument $(formula argument.formula) ?. ?=(%0 -.argument) argument [%0 .?(product.argument)] :: [%4 argument=*] =/ argument $(formula argument.formula) ?. ?=(%0 -.argument) argument ?^ product.argument [%2 trace] [%0 .+(product.argument)] :: [%5 a=* b=*] =/ a $(formula a.formula) ?. ?=(%0 -.a) a =/ b $(formula b.formula) ?. ?=(%0 -.b) b [%0 =(product.a product.b)] :: [%6 test=* yes=* no=*] =/ result $(formula test.formula) ?. ?=(%0 -.result) result ?+ product.result [%2 trace] %& $(formula yes.formula) %| $(formula no.formula) == :: [%7 subject=* next=*] =/ subject $(formula subject.formula) ?. ?=(%0 -.subject) subject %= $ subject product.subject formula next.formula == :: [%8 head=* next=*] =/ head $(formula head.formula) ?. ?=(%0 -.head) head %= $ subject [product.head subject] formula next.formula == :: [%9 axis=@ core=*] =/ core $(formula core.formula) ?. ?=(%0 -.core) core =/ arm (frag axis.formula product.core) ?~ arm [%2 trace] %= $ subject product.core formula u.arm == :: [%10 [axis=@ value=*] target=*] ?: =(0 axis.formula) [%2 trace] =/ target $(formula target.formula) ?. ?=(%0 -.target) target =/ value $(formula value.formula) ?. ?=(%0 -.value) value =/ mutant=(unit *) (edit axis.formula product.target product.value) ?~ mutant [%2 trace] [%0 u.mutant] :: [%11 tag=@ next=*] =/ next $(formula next.formula) ?. ?=(%0 -.next) next :- %0 .* subject [11 tag.formula 1 product.next] :: [%11 [tag=@ clue=*] next=*] =/ clue $(formula clue.formula) ?. ?=(%0 -.clue) clue =/ next =? trace ?=(?(%hunk %hand %lose %mean %spot) tag.formula) [[tag.formula product.clue] trace] $(formula next.formula) ?. ?=(%0 -.next) next :- %0 .* subject [11 [tag.formula 1 product.clue] 1 product.next] :: [%12 ref=* path=*] =/ ref $(formula ref.formula) ?. ?=(%0 -.ref) ref =/ path $(formula path.formula) ?. ?=(%0 -.path) path =/ result (scry product.ref product.path) ?~ result [%1 product.path] ?~ u.result [%2 [%hunk product.ref product.path] trace] [%0 u.u.result] == :: ++ frag |= [axis=@ noun=*] ^- (unit) ?: =(0 axis) ~ |- ^- (unit) ?: =(1 axis) `noun ?@ noun ~ =/ pick (cap axis) %= $ axis (mas axis) noun ?-(pick %2 -.noun, %3 +.noun) == :: ++ edit |= [axis=@ target=* value=*] ^- (unit) ?: =(1 axis) `value ?@ target ~ =/ pick (cap axis) =/ mutant %= $ axis (mas axis) target ?-(pick %2 -.target, %3 +.target) == ?~ mutant ~ ?- pick %2 `[u.mutant +.target] %3 `[-.target u.mutant] == -- ``` #### Examples ``` > (mink [20 [4 0 1]] ,~) [%0 product=21] > (mink [[[4 5] [6 14 15]] [0 7]] ,~) [%0 product=[14 15]] > (mink [42 12 [0 1] [1 73]] |=(a=^ ``(add (,[@ @] a)))) [%0 product=115] > (mink [0 12 [1 0] [1 0]] |=(* ~)) [%1 block=0] > (mink [42 0 2] ,~) [%2 trace=~] ``` --- ## `++mock` Compute formula on subject with hint Produces a `toon`, which is either a sucessful, blocked, or crashed result. If nock 11 is invoked, `gul` computes on the subject and produces a `(unit (unit))` result. An empty result becomes a `%1` `tune`, indicating a block. #### Accepts `sub` is the subject as a noun. `fol` is the formula as a noun. `gul` is an %iron gate invoked with nock operator 11. #### Produces The `unit` of a noun. #### Source ```hoon ++ mock |= [[sub=* fol=*] gul=$-(^ (unit (unit)))] (mook (mink [sub fol] gul)) ``` #### Examples ``` > (mock [5 4 0 1] ,~) [%0 p=6] > (mock [0 12 [0 1] [0 1]] |=(* ``999)) [%0 p=999] > (mock [42 12 [0 1] [0 1]] |=(* ~)) [%1 p=42] > (mock [42 0 2] ,~) [%2 p=~] ``` --- ## `++mook` Intelligently render crash annotation Converts a `%2` `tone` nock stack trace to a list of `tank`. Each may be a `tank`, `cord`, `spot`, or trapped `tank`. #### Accepts `ton` is a `tone`. #### Produces A `toon`. #### Source ```hoon ++ mook |= ton=tone ^- toon ?. ?=([%2 *] ton) ton |^ [%2 (turn skip rend)] :: ++ skip ^+ trace.ton =/ yel (lent trace.ton) ?. (gth yel 1.024) trace.ton %+ weld (scag 512 trace.ton) ^+ trace.ton :_ (slag (sub yel 512) trace.ton) :- %lose (crip "[skipped {(scow %ud (sub yel 1.024))} frames]") :: :: +rend: raw stack frame to tank :: :: $% [%hunk ref=* path] :: failed scry ([~ ~]) :: [%lose cord] :: skipped frames :: [%hand *] :: mug any :: [%mean $@(cord (trap tank))] :: ~_ et al :: [%spot spot] :: source location :: == :: ++ rend |= [tag=@ta dat=*] ^- tank ?+ tag :: leaf+"mook.{(rip 3 tag)}" :: %hunk ?@ dat leaf+"mook.hunk" =/ sof=(unit path) ((soft path) +.dat) ?~ sof leaf+"mook.hunk" (smyt u.sof) :: %lose ?^ dat leaf+"mook.lose" leaf+(rip 3 dat) :: %hand leaf+(scow %p (mug dat)) :: %mean ?@ dat leaf+(rip 3 dat) =/ mac (mack dat -.dat) ?~ mac leaf+"####" =/ sof ((soft tank) u.mac) ?~ sof leaf+"mook.mean" u.sof :: %spot =/ sof=(unit spot) ((soft spot) dat) ?~ sof leaf+"mook.spot" :+ %rose [":" ~ ~] :~ (smyt p.u.sof) =* l p.q.u.sof =* r q.q.u.sof =/ ud |=(a=@u (scow %ud a)) leaf+"<[{(ud p.l)} {(ud q.l)}].[{(ud p.r)} {(ud q.r)}]>" == == -- ``` #### Examples ``` > (mook [%0 5 4 5 1]) [%0 p=[5 4 5 1]] > (mook [%2 ~[[%hunk %rose ["<" "," ">"] ~[[%leaf "err"]]]]]) [%2 p=~[[%leaf p="mook.hunk"]]] > (mook [%2 ~[[%mean |.(>(add 5 6)<)]]]) [%2 p=~[[%leaf p="11"]]] > (mook [%2 ~[[%spot /b/repl [1 1]^[1 2]] [%mean |.(!!)]]]) [ %2 p ~[ [ %rose p=[p=":" q="" r=""] q [ i [ %rose p=[p="/" q="/" r=""] q=[i=[%leaf p="b"] t=[i=[%leaf p="repl"] t=~]] ] t=[i=[%leaf p="<[1 1].[1 2]>"] t=~] ] ] [%leaf p="####"] ] ] ``` --- ## `++mole` Typed unitary virtual Kicks a `trap`, producing its result in a `unit` if successful, or a null `unit` if it crashed. Unitized version of [`++mule`](#mule). #### Accepts `tap` is a `trap`. #### Produces A `(unit *)`, where the `*` will be the type produced by the expression. #### Source ```hoon ++ mole ~/ %mole |* tap=(trap) ^- (unit _$:tap) =/ mur (mure tap) ?~(mur ~ `$:tap) ``` #### Examples ``` > (mole |.(`@t`(add 50 47))) [~ 'a'] > (mole |.(~|('Error!' !!))) ~ ``` --- ## `++mong` Slam gate with sample Produces a `toon` computation result from slamming `gat` with `sam`, using `gul` to compute or block on nock 11 when applicable. #### Accepts `gat` is a noun that is generally a `gate`. `sam` is a sample noun. `gul` is an `%iron` gate invoked with nock operator 11. #### Produces A `toon`. #### Source ```hoon ++ mong |= [[gat=* sam=*] gul=$-(^ (unit (unit)))] ^- toon ?. ?=([* ^] gat) [%2 ~] (mock [gat(+< sam) %9 2 %0 1] gul) ``` #### Examples ``` > (mong [|=(@ 20) ~] ,~) [%0 p=20] > (mong [|=(@ !!) ~] ,~) [%2 p=~] > (mong [|=(a=@ (add 20 a)) ~] ,~) [%0 p=20] > (mong [|=(a=[@ @] (add 20 -.a)) ~] ,~) [%2 p=~] > (mong [|=(a=[@ @] (add 20 -.a)) [4 6]] ,~) [%0 p=24] > (mong [|=(a=@ .^(* a)) 99] |=(^ ``+<)) [%0 p=[[140 1.853.189.998] 99]] > (mong [|=(a=@ .^(@ a)) 99] |=([* a=*] ``+((,@ a)))) [%0 p=100] ``` --- ## `++mule` Typed virtual Kicks a `trap`, producing its results or any errors that occur along the way. Used to lazily compute stack traces. #### Accepts `tap` is a `trap`, generally producing a list of `tank`s. #### Produces An `(each * (list tank))` - `%.y` indicates success and `%.n` indicates a crash. #### Source ```hoon ++ mule ~/ %mule |* tap=(trap) =/ mud (mute tap) ?- -.mud %& [%& p=$:tap] %| [%| p=p.mud] == ``` #### Examples ``` > (mule |.((add 1 1))) [%.y p=2] > (mule |.(~|(%error !!))) [%.n p=~[[%leaf p="%error"]]] ``` --- ## `++mure` Untyped unitary virtual Kicks a `trap`, producing its results in a `unit` which is null if it crashed. The result is just a noun, no type information is preserved. #### Accepts A `trap`. #### Produces A `(unit *)`. #### Source ```hoon ++ mure |= tap=(trap) ^- (unit) =/ ton (mink [tap %9 2 %0 1] |=((pair) ``.*(~ [%12 1+p 1+q]))) ?.(?=(%0 -.ton) ~ `product.ton) ``` #### Examples ``` > (mure |.(~|(%error !!))) ~ > (mure |.((add 1 1))) [~ 2] > (mure |.('foo')) [~ 7.303.014] > ((unit @t) (mure |.('foo'))) [~ 'foo'] ``` --- ## `++mute` Untyped virtual Kicks a `trap`, producing its result as a noun or the tanks of any error that occurs. Similar to [`++mule`](#mule), but preserves no type information. #### Accepts `tap` is a `trap`. #### Produces A `(each * (list tank))`, where `%.y` indicates success and `%.n` indicates failure. #### Source ```hoon ++ mute |= tap=(trap) ^- (each * (list tank)) =/ ton (mock [tap %9 2 %0 1] |=((pair) ``.*(~ [%12 1+p 1+q]))) ?- -.ton %0 [%& p.ton] :: %1 =/ sof=(unit path) ((soft path) p.ton) [%| ?~(sof leaf+"mute.hunk" (smyt u.sof)) ~] :: %2 [%| p.ton] == ``` #### Examples ``` > (mute |.(leaf+"hello")) [%.y p=[1.717.658.988 104 101 108 108 111 0]] > (mute |.(!!)) [%.n p=~] > (mute |.(~|(%error !!))) [%.n p=~[[%leaf p="%error"]]] > (mute |.((cat 3 'foo' 'bar'))) [%.y p=125.762.588.864.358] ``` --- ## `++slum` Slam a gate on a sample using raw nock, untyped Slam `gat` with `sam`. Uses a raw `.*` nock expression internally and does not preserve type information for the result. This will crash if evaluation crashes. #### Examples ``` > (slum |=([a=@ b=@] (add a b)) [7 9]) 16 > (slum (cury cat 3) ['foo' 'bar']) 125.762.588.864.358 > (@t (slum (cury cat 3) ['foo' 'bar'])) 'foobar' > (slum |=(* !!) 42) dojo: hoon expression failed ``` --- ## `++soft` Virtual clam Clam (mold) noun `fud` with `mold` `han`, producing a `unit` of the result. The `unit` is null if clamming failed. This is curried, so the soft-clamming gate can be stored and called repeatedly. #### Accepts `han` is a `mold`. `fud` is a noun. #### Produces A `(unit *)`, where the `*` will be the type produced by the mold. #### Source ```hoon ++ soft |* han=$-(* *) |=(fud=* (mole |.((han fud)))) ``` #### Examples ``` > ((soft @t) 97) [~ 'a'] > ((soft @t) [1 2]) ~ > ((soft ,[@ux @ux]) ['a' 'b']) [~ [0x61 0x62]] ``` ---