Documented below are the many useful functions in the /lib/strandio.hoon
helper library.
Send Cards
send-raw-cards
Send a list of card
s.
Accepts
A (list card:agent:gall)
.
Produces
~
Source
++ send-raw-cards|= cards=(list =card:agent:gall)=/ m (strand ,~)^- form:m|= strand-input:strand[cards %done ~]
Example
;~ now=@da bind:m get-time=/ cards=(list card):~ [%pass /foo %agent [~zod %foo] %poke %noun !>(~)][%pass /bar %arvo %b %wait now]==;< ~ bind:m (send-raw-cards cards)
send-raw-card
Send a single card
.
Accepts
A card:agent:gall
Produces
~
Source
++ send-raw-card|= =card:agent:gall=/ m (strand ,~)^- form:m(send-raw-cards card ~)
Example
=/ card [%pass /foo %agent [~zod %foo] %poke %noun !>(~)];< ~ bind:m (send-raw-card card)
Bowl
get-bowl
Get the bowl.
Accepts
Nothing.
Produces
A bowl:rand
.
Source
++ get-bowl=/ m (strand ,bowl:strand)^- form:m|= tin=strand-input:strand`[%done bowl.tin]
Example
;< =bowl:rand bind:m get-bowl
get-beak
Get the beak.
Accepts
Nothing.
Produces
A beak
.
Source
++ get-beak=/ m (strand ,beak)^- form:m|= tin=strand-input:strand`[%done [our q.byk da+now]:bowl.tin]
Example
;< =beak bind:m get-beak
get-time
Get the current date-time.
Accepts
Nothing.
Produces
A @da
.
Source
++ get-time=/ m (strand ,@da)^- form:m|= tin=strand-input:strand`[%done now.bowl.tin]
Example
;< now=@da bind:m get-time
get-our
Get our ship.
Accepts
Nothing.
Produces
A @p
.
Source
++ get-our=/ m (strand ,ship)^- form:m|= tin=strand-input:strand`[%done our.bowl.tin]
Example
;< our=@p bind:m get-our
get-entropy
Get some entropy.
Accepts
Nothing.
Produces
A @uvJ
.
Source
++ get-entropy=/ m (strand ,@uvJ)^- form:m|= tin=strand-input:strand`[%done eny.bowl.tin]
Example
;< eny=@uvJ bind:m get-entropy
Misc
install-domain
Install a domain in Eyre, triggering the setup of an SSL certificate.
Accepts
A turf
.
Produces
~
Source
++ install-domain|= =turf=/ m (strand ,~)^- form:m(send-raw-card %pass / %arvo %e %rule %turf %put turf)
Example
;< ~ bind:m (install-domain 'com' 'example' ~)
check-online
Require that a peer respond before timeout.
The peer is pinged with a "hi" and must ack the poke before the timeout.
Accepts
A pair of [ship @dr]
. The @dr
is the amount of time the peer has to respond before failure.
Produces
~
Source
++ check-online|= [who=ship lag=@dr]=/ m (strand ,~)^- form:m%+ (map-err ,~) |=(* [%offline *tang])%+ (set-timeout ,~) lag;< ~ bind:m(poke [who %hood] %helm-hi !>(~))(pure:m ~)
Example
;< ~ bind:m (check-online ~zod ~s10)
take-sign-arvo
Wait for a sign from Arvo.
Accepts
Nothing.
Produces
A pair of [wire sign-arvo]
.
Source
++ take-sign-arvo=/ m (strand ,[wire sign-arvo])^- form:m|= tin=strand-input:strand?+ in.tin `[%skip ~]~`[%wait ~]::[~ %sign *]`[%done [wire sign-arvo]:u.in.tin]==
Example
;< [=wire =sign-arvo] bind:m take-sign-arvo
Pokes
poke
Poke an agent, then await a positive ack.
Accepts
A pair of [dock cage]
, where the dock
is the ship and agent you want to poke, and the cage
is the data.
Produces
~
Source
++ poke|= [=dock =cage]=/ m (strand ,~)^- form:m=/ =card:agent:gall [%pass /poke %agent dock %poke cage];< ~ bind:m (send-raw-card card)(take-poke-ack /poke)
Example
;< ~ bind:m (poke [~zod %foo] %noun !>(~))
raw-poke
Poke an agent then await a (n)ack.
This doesn't care whether the ack is positive or negative, unlike the ordinary poke.
Accepts
A pair of [dock cage]
, where the dock
is the ship and agent to poke, and the cage
is the data.
Produces
~
Source
++ raw-poke|= [=dock =cage]=/ m (strand ,~)^- form:m=/ =card:agent:gall [%pass /poke %agent dock %poke cage];< ~ bind:m (send-raw-card card)=/ m (strand ,~)^- form:m|= tin=strand-input:strand?+ in.tin `[%skip ~]~`[%wait ~]::[~ %agent * %poke-ack *]?. =(/poke wire.u.in.tin)`[%skip ~]`[%done ~]==
Example
;< ~ bind:m (raw-poke [~zod %foo] %noun !>(~))
raw-poke-our
Poke a local agent then await a (n)ack.
This doesn't care whether the ack is positive or negative, unlike the ordinary poke-our.
Accepts
A pair of [app=term =cage]
, where app
is the local agent to poke and cage
is the data.
Produces
~
Source
++ raw-poke-our|= [app=term =cage]=/ m (strand ,~)^- form:m;< =bowl:spider bind:m get-bowl(raw-poke [our.bowl app] cage)
Example
;< ~ bind:m (raw-poke-our %foo %noun !>(~))
poke-our
Poke a local agent then await an ack.
Note this fails if it gets a nack back.
Accepts
A pair of [=term =cage]
where term
is the name of a local agent and cage
is the data.
Produces
~
Source
++ poke-our|= [=term =cage]=/ m (strand ,~)^- form:m;< our=@p bind:m get-our(poke [our term] cage)
Example
;< ~ bind:m (poke-our %foo %noun !>(~))
take-poke-ack
Take a poke ack on the given wire.
If the ack is a nack, the strand fails.
Accepts
A wire
.
Produces
~
Source
++ take-poke-ack|= =wire=/ m (strand ,~)^- form:m|= tin=strand-input:strand?+ in.tin `[%skip ~]~ `[%wait ~][~ %agent * %poke-ack *]?. =(wire wire.u.in.tin)`[%skip ~]?~ p.sign.u.in.tin`[%done ~]`[%fail %poke-fail u.p.sign.u.in.tin]==
Example
;< ~ bind:m (take-poke-ack /foo)
take-poke
Wait for a poke with a particular mark.
Accepts
A mark
.
Produces
A vase
.
Source
++ take-poke|= =mark=/ m (strand ,vase)^- form:m|= tin=strand-input:strand?+ in.tin `[%skip ~]~`[%wait ~]::[~ %poke @ *]?. =(mark p.cage.u.in.tin)`[%skip ~]`[%done q.cage.u.in.tin]==
Example
;< =vase bind:m (take-poke %noun)
Subscriptions
watch
Watch a subscription path on an agent, then await a positive watch ack.
Note this fails if it gets a watch nack back.
Accepts
A triple of [=wire =dock =path]
where dock
is the ship and agent, and path
is the subscription path.
Produces
~
Source
++ watch|= [=wire =dock =path]=/ m (strand ,~)^- form:m=/ =card:agent:gall [%pass watch+wire %agent dock %watch path];< ~ bind:m (send-raw-card card)(take-watch-ack wire)
Example
;< ~ bind:m (watch /foo [~zod %foo] /some/path)
watch-one
Subscribe to a watch path on an agent, take a single fact, then await a kick.
Accepts
A triple of [=wire =dock =path]
where dock
is a ship and agent, and path
is the subscription path.
Produces
The cage
of the received fact.
Source
++ watch-one|= [=wire =dock =path]=/ m (strand ,cage)^- form:m;< ~ bind:m (watch wire dock path);< =cage bind:m (take-fact wire);< ~ bind:m (take-kick wire)(pure:m cage)
Example
;< [=mark =vase] bind:m (watch-one /foo [~zod %foo] /some/path)
watch-our
Subscribe to a watch path on a local agent, then wait for a positive ack.
This will fail if it gets a watch nack.
Accepts
A triple of [=wire =term =path]
where term
is the name of the agent and path
is the subscription path.
Produces
~
Source
::++ watch-our|= [=wire =term =path]=/ m (strand ,~)^- form:m;< our=@p bind:m get-our(watch wire [our term] path)
Example
;< ~ bind:m (watch-our /foo %foo /some/path)
leave
Leave a subscription.
Accepts
A pair of [=wire =dock]
where dock
is the ship and agent in question.
Produces
~
Source
++ leave|= [=wire =dock]=/ m (strand ,~)^- form:m=/ =card:agent:gall [%pass watch+wire %agent dock %leave ~](send-raw-card card)
Example
;< ~ bind:m (leave /foo ~zod %foo)
leave-our
Unsubscribe from a local agent.
Accepts
A pair of [=wire =term]
where term
is the local agent.
Produces
~
Source
++ leave-our|= [=wire =term]=/ m (strand ,~)^- form:m;< our=@p bind:m get-our(leave wire [our term])
Example
;< ~ bind:m (leave-our /foo %foo)
rewatch
Resubscribe on kick.
This waits for a kick on a given wire, then rewatches the given ship, agent and path on the same wire. It then waits for a positive watch ack.
Accepts
A triple of [=wire =dock =path]
where dock
is the ship and agent, and path
is the subscription path.
Produces
~
Source
++ rewatch|= [=wire =dock =path]=/ m (strand ,~);< ~ bind:m ((handle ,~) (take-kick wire));< ~ bind:m (flog-text "rewatching {<dock>} {<path>}");< ~ bind:m (watch wire dock path)(pure:m ~)
Exmaple
;< ~ bind:m (rewatch /foo [~zod %foo] /some/path)
take-fact-prefix
Wait for a subscription update on a wire.
Accepts
A wire
as the prefix of what you expect. E.g. if /foo
is given, a fact with a wire of /foo
, /foo/bar
, /foo/bar/baz
, etc, will be accepted.
Produces
A cell of [wire cage]
.
Source
++ take-fact-prefix|= =wire=/ m (strand ,[path cage])^- form:m|= tin=strand-input:strand?+ in.tin `[%skip ~]~ `[%wait ~][~ %agent * %fact *]?. =(watch+wire (scag +((lent wire)) wire.u.in.tin))`[%skip ~]`[%done (slag (lent wire) wire.u.in.tin) cage.sign.u.in.tin]==
Example
;< [=wire =mark =vase] bind:m (take-fact-prefix /foo)
take-fact
Wait for a subscription update on a wire.
Accepts
The wire
you want to listen on.
Produces
A cage
.
Source
++ take-fact|= =wire=/ m (strand ,cage)^- form:m|= tin=strand-input:strand?+ in.tin `[%skip ~]~ `[%wait ~][~ %agent * %fact *]?. =(watch+wire wire.u.in.tin)`[%skip ~]`[%done cage.sign.u.in.tin]==
Example
;< [=mark =vase] bind:m (take-fact /foo)
take-kick
Wait for a subscription close.
Accepts
The wire
you want to listen on.
Produces
~
Source
++ take-kick|= =wire=/ m (strand ,~)^- form:m|= tin=strand-input:strand?+ in.tin `[%skip ~]~ `[%wait ~][~ %agent * %kick *]?. =(watch+wire wire.u.in.tin)`[%skip ~]`[%done ~]==
Example
;< ~ bind:m (take-kick /foo)
take-watch-ack
Take a watch ack on a given wire.
If the watch ack is a nack, the strand fails.
Accepts
A wire
.
Produces
~
Source
++ take-watch-ack|= =wire=/ m (strand ,~)^- form:m|= tin=strand-input:strand?+ in.tin `[%skip ~]~ `[%wait ~][~ %agent * %watch-ack *]?. =(watch+wire wire.u.in.tin)`[%skip ~]?~ p.sign.u.in.tin`[%done ~]`[%fail %watch-ack-fail u.p.sign.u.in.tin]==
Example
;< ~ bind:m (take-watch-ack /foo)
take-watch
Wait for a subscription request.
Accepts
Nothing.
Produces
The subscription path
.
Source
++ take-watch=/ m (strand ,path)|= tin=strand-input:strand?+ in.tin `[%skip ~]~ `[%wait ~][~ %watch *]`[%done path.u.in.tin]==
Example
;< =path bind:m take-watch
Scries
scry
Scry an agent or vane.
Accepts
A pair of [=mold =path]
where mold
is the type returned and path
has the following format:
/[vane letter and care]/[desk]/[rest of path after beak]
The strand implicitly fills in our
and now
in the beak.
Produces
Data of the type produced by the mold you specified.
Source
++ scry|* [=mold =path]=/ m (strand ,mold)^- form:m?> ?=(^ path)?> ?=(^ t.path);< =bowl:spider bind:m get-bowl%- pure:m.^(mold i.path (scot %p our.bowl) i.t.path (scot %da now.bowl) t.t.path)
Example
;< has=? bind:m (scry ? %cu %base /gen/vats/hoon)
keen
Make a remote scry request.
Note this doesn't wait for a response, you'd have to use a separate take-tune strand to receive the result.
Accept
A pair of [=wire =spar:ames]
.
Produces
~
Source
++ keen|= [=wire =spar:ames]=/ m (strand ,~)^- form:m(send-raw-card %pass wire %arvo %a %keen spar)
Example
;< ~ bind:m (keen /foo ~sampel /c/x/4/base/sys/hoon/hoon)
take-tune
Wait for a remote scry result on a particular wire.
Accepts
A wire
.
Produces
A [spar:ames (unit roar:ames)]
Source
++ take-tune|= =wire=/ m (strand ,[spar:ames (unit roar:ames)])^- form:m|= tin=strand-input:strand?+ in.tin `[%skip ~]~ `[%wait ~]::[~ %sign * %ames %tune ^ *]?. =(wire wire.u.in.tin)`[%skip ~]`[%done +>.sign-arvo.u.in.tin]==
Example
;< [spar roar=(unit roar)] bind:m (take-tune /foo)
Time
wait
Send a %wait
to Behn and wait for the %wake
.
Note there's also sleep to wait for a relative amount of time rather than having to specify an absolute time.
Accepts
A @da
of when the timer should fire.
Produces
~
Source
++ wait|= until=@da=/ m (strand ,~)^- form:m;< ~ bind:m (send-wait until)(take-wake `until)
Example
;< now=@da bind:m get-time;< ~ bind:m (wait (add now ~s2))
sleep
Wait for a relative amount of time.
Accepts
A @dr
.
Produces
~
Source
++ sleep|= for=@dr=/ m (strand ,~)^- form:m;< now=@da bind:m get-time(wait (add now for))
Example
;< ~ bind:m (sleep ~s2)
send-wait
Send Behn a %wait
but don't wait for the %wake
.
Accepts
A @da
.
Produces
~
Source
++ send-wait|= until=@da=/ m (strand ,~)^- form:m=/ =card:agent:gall[%pass /wait/(scot %da until) %arvo %b %wait until](send-raw-card card)
Example
;< now=@da bind:m get-time;< ~ bind:m (send-wait (add ~s2 now))
set-timeout
Make a strand fail if it takes too long.
Accepts
This takes the mold
produced but the strand you're timing, and produces a gate. The gate takes a pair of the @dr
timeout and the strand being timed.
Produces
Data of the type produced by the strand being timed.
Source
++ set-timeout|* computation-result=mold=/ m (strand ,computation-result)|= [time=@dr computation=form:m]^- form:m;< now=@da bind:m get-time=/ when (add now time)=/ =card:agent:gall[%pass /timeout/(scot %da when) %arvo %b %wait when];< ~ bind:m (send-raw-card card)|= tin=strand-input:strand=* loop $?: ?& ?=([~ %sign [%timeout @ ~] %behn %wake *] in.tin)=((scot %da when) i.t.wire.u.in.tin)==`[%fail %timeout ~]=/ c-res (computation tin)?: ?=(%cont -.next.c-res)c-res(self.next ..loop(computation self.next.c-res))?: ?=(%done -.next.c-res)=/ =card:agent:gall[%pass /timeout/(scot %da when) %arvo %b %rest when]c-res(cards [card cards.c-res])c-res
Example
;< ~ bind:m ((set-timeout ,~) ~s10 (poke-our %foo %noun !>(~)))
take-wake
Wait for a wake from Behn.
This is meant for internal use by wait, you'd not typically use it directly.
Accepts
A (unit @da)
. If the unit is non-null, it'll only accept a %wake
whose wire is of the form /wait/(scot %da the-given-time)
. If the unit is null, it'll accept a %wake
with a wire of /wait/(scot %da any-time)
.
Produces
~
Source
::++ take-wake|= until=(unit @da)=/ m (strand ,~)^- form:m|= tin=strand-input:strand?+ in.tin `[%skip ~]~ `[%wait ~][~ %sign [%wait @ ~] %behn %wake *]?. |(?=(~ until) =(`u.until (slaw %da i.t.wire.u.in.tin)))`[%skip ~]?~ error.sign-arvo.u.in.tin`[%done ~]`[%fail %timer-error u.error.sign-arvo.u.in.tin]==
Example
;< now=@da bind:m get-time=/ card=card:agent:gall [%pass /wait/(scot %da now) %arvo %b %wait now];< ~ bind:m (send-raw-card card);< ~ bind:m (take-wake `now)
Errors
retry
Retry a strand that produces a unit
if the unit
is null, with a backoff.
Accepts
retry
first takes a result=mold
of the return type and produces a gate. That gate takes two arguments:
crash-after=(unit @ud)
: the number of tries before failing.computation
: A strand that produces a(unit result)
.
Produces
The type of result
.
Source
++ retry|* result=mold|= [crash-after=(unit @ud) computation=_*form:(strand (unit result))]=/ m (strand ,result)=| try=@ud|- ^- form:m=* loop $?: =(crash-after `try)(strand-fail %retry-too-many ~);< ~ bind:m (backoff try ~m1);< res=(unit result) bind:m computation?^ res(pure:m u.res)loop(try +(try))
Example
=/ =hiss:eyre [(need (de-purl:html 'http://example.com')) %get ~ ~];< =httr:eyre bind:m ((retry httr:eyre) `3 (hiss-request hiss))
backoff
Wait for increasing amounts of time with each try.
Accepts
A pair of [try=@ud limit=@dr]
, specifying the current try count and the maximum amount of time to wait.
Produces
~
Source
++ backoff|= [try=@ud limit=@dr]=/ m (strand ,~)^- form:m;< eny=@uvJ bind:m get-entropy%- sleep%+ min limit?: =(0 try) ~s0%+ add(mul ~s1 (bex (dec try)))(mul ~s0..0001 (~(rad og eny) 1.000))
map-err
Rewrite a strand failure error.
Accepts
This function takes the return mold
of the strand in question as its argument and returns a gate that takes two arguments:
f
: a gate that takes a[term tang]
and produces a[term tang]
. This is the%error-tag
and stack trace of the failure you're rewriting.computation
: the strand whose errors you're rewriting.
See the example below for usage.
Produces
Data of the type produced by the strand in question.
Source
++ map-err|* computation-result=mold=/ m (strand ,computation-result)|= [f=$-([term tang] [term tang]) computation=form:m]^- form:m|= tin=strand-input:strand=* loop $=/ c-res (computation tin)?: ?=(%cont -.next.c-res)c-res(self.next ..loop(computation self.next.c-res))?. ?=(%fail -.next.c-res)c-resc-res(err.next (f err.next.c-res))
Example
;< ~ bind:m%+ (map-err ,~)|= [=term =tang]?: =(%poke-fail term)[%foo tang][term tang](poke-our %foo %noun !>(~))
HTTP
send-request
Make an HTTP request via Iris, but don't wait for the response.
Accepts
A request:http
.
Produces
~
Source
++ send-request|= =request:http=/ m (strand ,~)^- form:m(send-raw-card %pass /request %arvo %i %request request *outbound-config:iris)
Example
;< ~ bind:m (send-request %'GET' 'http://example.com' ~ ~)
send-cancel-request
Cancel a previous Iris HTTP request.
This sends it on the /request
wire used by send-request
. It won't work if the original request was on a different wire.
Accepts
Nothing.
Produces
~
Source
++ send-cancel-request=/ m (strand ,~)^- form:m(send-raw-card %pass /request %arvo %i %cancel-request ~)
Example
;< ~ bind:m send-cancel-request
take-client-response
Take the HTTP response from a previous HTTP request made with send-request
.
This listens on the /request
wire, it won't work if you're made a request on a different wire.
Accepts
Nothing.
Produces
Source
++ take-client-response=/ m (strand ,client-response:iris)^- form:m|= tin=strand-input:strand?+ in.tin `[%skip ~]~ `[%wait ~]::[~ %sign [%request ~] %iris %http-response %cancel *]::NOTE iris does not (yet?) retry after cancel, so it means failure:- ~:+ %fail%http-request-cancelled['http request was cancelled by the runtime']~::[~ %sign [%request ~] %iris %http-response %finished *]`[%done client-response.sign-arvo.u.in.tin]==
Example
;< res=client-response:iris bind:m take-client-response
take-maybe-sigh
Take a unitized raw HTTP response.
Accepts
Nothing
Produces
A (unit httr:eyre)
. The unit
is null if we failed to receive a response.
Source
++ take-maybe-sigh=/ m (strand ,(unit httr:eyre))^- form:m;< rep=(unit client-response:iris) bind:mtake-maybe-response?~ rep(pure:m ~):: XX s/b impossible::?. ?=(%finished -.u.rep)(pure:m ~)(pure:m (some (to-httr:iris +.u.rep)))
Example
;< res=(unit httr:eyre) bind:m take-maybe-sigh
take-maybe-response
Take a unitized HTTP response.
Accepts
Nothing
Produces
A (unit client-response:iris)
. The unit
is null if we failed to receive a response.
Source
++ take-maybe-response=/ m (strand ,(unit client-response:iris))^- form:m|= tin=strand-input:strand?+ in.tin `[%skip ~]~ `[%wait ~][~ %sign [%request ~] %iris %http-response %cancel *]`[%done ~][~ %sign [%request ~] %iris %http-response %finished *]`[%done `client-response.sign-arvo.u.in.tin]==
Example
;< res=(unit client-response:iris) bind:m take-maybe-response
extract-body
Extract body from an HTTP response.
Accepts
A client-response:iris
Produces
A cord
.
Source
++ extract-body|= =client-response:iris=/ m (strand ,cord)^- form:m?> ?=(%finished -.client-response)%- pure:m?~ full-file.client-response ''q.data.u.full-file.client-response
fetch-cord
Get the HTTP response body from a URL.
Accepts
The URL in a tape
.
Produces
A cord
of the response body.
Source
++ fetch-cord|= url=tape=/ m (strand ,cord)^- form:m=/ =request:http [%'GET' (crip url) ~ ~];< ~ bind:m (send-request request);< =client-response:iris bind:m take-client-response(extract-body client-response)
Example
;< bod=@t bind:m (fetch-cord "http://example.com")
fetch-json
Get some JSON from a URL.
Accepts
The URL as a tape
.
Produces
A json
structure.
Source
++ fetch-json|= url=tape=/ m (strand ,json)^- form:m;< =cord bind:m (fetch-cord url)=/ json=(unit json) (de-json:html cord)?~ json(strand-fail %json-parse-error ~)(pure:m u.json)
Example
;< =json bind:m (fetch-json "http://example.com")
hiss-request
Make a raw HTTP request, take a raw response.
Accepts
hiss:eyre
Produces
A (unit httr:eyre)
. The unit
is null if we failed to receive a response.
Source
::++ hiss-request|= =hiss:eyre=/ m (strand ,(unit httr:eyre))^- form:m;< ~ bind:m (send-request (hiss-to-request:html hiss))take-maybe-sigh
Example
=/ =hiss:eyre [(need (de-purl:html 'http://example.com')) %get ~ ~];< res=(unit httr:eyre) bind:m (hiss-request hiss)
Build
build-file
Build a source file at the specified beam
.
Accepts
A beam
.
Produces
A (unit vase)
. The vase
contains the compiled file, the unit
is null if it failed.
Source
++ build-file|= [[=ship =desk =case] =spur]=* arg +<=/ m (strand ,(unit vase))^- form:m;< =riot:clay bind:m(warp ship desk ~ %sing %a case spur)?~ riot(pure:m ~)?> =(%vase p.r.u.riot)(pure:m (some !<(vase q.r.u.riot)))
Example
;< now=@da bind:m get-time;< res=(unit vase) bind:m (build-file [~zod %base da+now] /gen/hood/hi/hoon)
build-file-hard
Build a source file at the specified beam
, crashing if it fails.
Accepts
A beam
.
Produces
A vase
.
Source
++ build-file-hard|= [[=ship =desk =case] =spur]=* arg +<=/ m (strand ,vase)^- form:m;< =riot:claybind:m(warp ship desk ~ %sing %a case spur)?> ?=(^ riot)?> ?=(%vase p.r.u.riot)(pure:m !<(vase q.r.u.riot))
Example
;< now=@da bind:m get-time;< =vase bind:m (build-file-hard [~zod %base da+now] /gen/hood/hi/hoon)
build-mark
Build a dynamic mark core from file.
Accepts
A pair of [beak mark]
.
Produces
A dais:clay
Source
++ build-mark|= [[=ship =desk =case] mak=mark]=* arg +<=/ m (strand ,dais:clay)^- form:m;< =riot:clay bind:m(warp ship desk ~ %sing %b case /[mak])?~ riot(strand-fail %build-mark >arg< ~)?> =(%dais p.r.u.riot)(pure:m !<(dais:clay q.r.u.riot))
Example
;< now=@da bind:m get-time;< =dais:clay bind:m (build-mark [~zod %base da+now] %noun)
build-tube
Build a dynamic mark conversion gate from file.
Accepts
A pair of [beak mars:clay]
. A mars
is a pair of the from and to mark.
Produces
A tube:clay
Source
++ build-tube|= [[=ship =desk =case] =mars:clay]=* arg +<=/ m (strand ,tube:clay)^- form:m;< =riot:clay bind:m(warp ship desk ~ %sing %c case /[a.mars]/[b.mars])?~ riot(strand-fail %build-tube >arg< ~)?> =(%tube p.r.u.riot)(pure:m !<(tube:clay q.r.u.riot))
Example
;< now=@da bind:m get-time;< =tube:clay bind:m (build-tube [~zod %base da+now] %mime %txt)
build-nave
Build a static mark core from file.
Accepts
A pair of [beak mark]
.
Produces
A vase
.
Source
++ build-nave|= [[=ship =desk =case] mak=mark]=* arg +<=/ m (strand ,vase)^- form:m;< =riot:clay bind:m(warp ship desk ~ %sing %e case /[mak])?~ riot(strand-fail %build-nave >arg< ~)?> =(%nave p.r.u.riot)(pure:m q.r.u.riot)
Example
;< now=@da bind:m get-time;< =nave:clay bind:m (build-nave [~zod %base da+now] %txt)
build-cast
Build a static mark conversion gate from file.
Accepts
A pair of [beak mars:clay]
. A mars
is a pair of the from mark and to mark.
Source
++ build-cast|= [[=ship =desk =case] =mars:clay]=* arg +<=/ m (strand ,vase)^- form:m;< =riot:clay bind:m(warp ship desk ~ %sing %f case /[a.mars]/[b.mars])?~ riot(strand-fail %build-cast >arg< ~)?> =(%cast p.r.u.riot)(pure:m q.r.u.riot)
Example
;< now=@da bind:m get-time;< =vase bind:m (build-cast [~zod %base da+now] %mime %txt)
eval-hoon
Evaluate some hoon and produce the result.
Accepts
A pair of [gen=hoon bez=(list beam)]
. The gen
argument is the hoon to be evaluated. If bez
is empty, it will be evaluated against the standard ..zuse
subject. If a list of beam
s are provided in bez
, each one will be read from Clay, build, and pinned to the head of the subject, before gen
is evaluated against it.
Produces
A vase
of the result.
Source
++ eval-hoon|= [gen=hoon bez=(list beam)]=/ m (strand ,vase)^- form:m=/ sut=vase !>(..zuse)|-?~ bez(pure:m (slap sut gen));< vax=vase bind:m (build-file-hard i.bez)$(bez t.bez, sut (slop vax sut))
Example
;< =vase bind:m (eval-hoon !,(*hoon (add 1 1)))
Clay
warp
Raw read from Clay.
Accepts
A pair of ship
and riff:clay
.
Produces
A riot:clay
.
Source
++ warp|= [=ship =riff:clay]=/ m (strand ,riot:clay);< ~ bind:m (send-raw-card %pass /warp %arvo %c %warp ship riff)(take-writ /warp)
Example
;< now=@da bind:m get-time;< =riot:clay bind:m (warp %base ~ %sing %x da+now /foo/txt)
read-file
Read a file from Clay.
Accepts
A beam
.
Produces
A cage
.
Source
++ read-file|= [[=ship =desk =case] =spur]=* arg +<=/ m (strand ,cage);< =riot:clay bind:m (warp ship desk ~ %sing %x case spur)?~ riot(strand-fail %read-file >arg< ~)(pure:m r.u.riot)
Example
;< now=@da bind:m get-time;< =cage bind:m (read-file [~zod %base da+now] /foo/txt)
check-for-file
Check for the existence of a file in Clay.
Accepts
A beam
.
Produces
A ?
which is %.y
if the file exists, and %.n
if not.
Source
++ check-for-file|= [[=ship =desk =case] =spur]=/ m (strand ,?);< =riot:clay bind:m (warp ship desk ~ %sing %x case spur)(pure:m ?=(^ riot))
Example
;< now=@da bind:m get-time;< has=? bind:m (check-for-file [~zod %base da+now] /foo/txt)
list-tree
Get a list of all files in the given Clay directory.
Accepts
A beam
.
Produces
A (list path)
.
Source
++ list-tree|= [[=ship =desk =case] =spur]=* arg +<=/ m (strand ,(list path));< =riot:clay bind:m (warp ship desk ~ %sing %t case spur)?~ riot(strand-fail %list-tree >arg< ~)(pure:m !<((list path) q.r.u.riot))
Example
;< now=@da bind:m get-time;< paths=(list path) bind:m (list-tree [~zod %base da+now] /sys)
take-writ
Take a Clay read result.
Accepts
The wire
to listen on.
Produces
Source
++ take-writ|= =wire=/ m (strand ,riot:clay)^- form:m|= tin=strand-input:strand?+ in.tin `[%skip ~]~ `[%wait ~][~ %sign * ?(%behn %clay) %writ *]?. =(wire wire.u.in.tin)`[%skip ~]`[%done +>.sign-arvo.u.in.tin]==
Example
;< =riot-clay bind:m (take-writ /warp)
Main Loop
ignore
Try next on failure.
This produces a failure with an %ignore
status, which main-loop uses to skip the strand and try the next one. This is of little use outside the context of a main-loop
.
Accepts
Nothing.
Produces
Nothing.
Source
++ ignore|= tin=strand-input:strand`[%fail %ignore ~]
handle
Convert skips to %ignore
failures.
This tells main-loop to try the next strand on skips. This would not be used outside of a main-loop
.
Accepts
+handle
takes a mold and produces a gate that takes another strand.
Produces
Data of the type produced by the given mold.
Source
++ handle|* a=mold=/ m (strand ,a)|= =form:m^- form:m|= tin=strand-input:strand=/ res (form tin)=? next.res ?=(%skip -.next.res)[%fail %ignore ~]res
Example
;< =vase bind:m ((handle ,vase) (take-poke %foo))
main-loop
A main-loop
can be used for three things:
- create a loop.
- try the same input against multiple strands.
- Queue input on
%skip
and then dequeue from the beginning on%done
.
Accepts
It first accepts a mold
, specifying the return type, and produces a gate. The gate produced takes a list
of gates that take an argument of the specified mold
, and produce the form
of a strand
of that mold.
Produces
Data of the type produced by the given mold
.
Source
Click to expand
++ main-loop|* a=mold=/ m (strand ,~)=/ m-a (strand ,a)=| queue=(qeu (unit input:strand))=| active=(unit [in=(unit input:strand) =form:m-a forms=(list $-(a form:m-a))])=| state=a|= forms=(lest $-(a form:m-a))^- form:m|= tin=strand-input:strand=* top `form:m`..$=. queue (~(put to queue) in.tin)|^ (continue bowl.tin)::++ continue|= =bowl:strand^- output:m?> =(~ active)?: =(~ queue)`[%cont top]=^ in=(unit input:strand) queue ~(get to queue)^- output:m=. active `[in (i.forms state) t.forms]^- output:m(run bowl in)::++ run^- form:m|= tin=strand-input:strand^- output:m?> ?=(^ active)=/ res (form.u.active tin)=/ =output:m?- -.next.res%wait `[%wait ~]%skip `[%cont ..$(queue (~(put to queue) in.tin))]%cont `[%cont ..$(active `[in.u.active self.next.res forms.u.active])]%done (continue(active ~, state value.next.res) bowl.tin)%fail?: &(?=(^ forms.u.active) ?=(%ignore p.err.next.res))%= $active `[in.u.active (i.forms.u.active state) t.forms.u.active]in.tin in.u.active==`[%fail err.next.res]==[(weld cards.res cards.output) next.output]--
Example
See the separate main-loop
example or the echo
example below.
echo
Echo a given message to the terminal every 2 seconds until told to stop.
Accepts
This strand takes nothing directly, but expects a poke with a mark
of %echo
and vase containing a tape
with the message to echo. To finish, it expects a poke with a mark
of %over
.
Produces
~
Source
++ echo=/ m (strand ,~)^- form:m%- (main-loop ,~):~ |= ~^- form:m;< =vase bind:m ((handle ,vase) (take-poke %echo))=/ message=tape !<(tape vase)%- (slog leaf+"{message}..." ~);< ~ bind:m (sleep ~s2)%- (slog leaf+"{message}.." ~)(pure:m ~)::|= ~^- form:m;< =vase bind:m ((handle ,vase) (take-poke %over))%- (slog leaf+"over..." ~)(pure:m ~)==
Printing
flog
Send a wrapped Dill task to Dill.
Accepts
Produces
~
Source
++ flog|= =flog:dill=/ m (strand ,~)^- form:m(send-raw-card %pass / %arvo %d %flog flog)
Example
;< ~ bind:m (flog %text "foo")
flog-text
Print a message to the terminal via Dill.
Accepts
A tape
.
Produces
~
Source
++ flog-text|= =tape=/ m (strand ,~)^- form:m(flog %text tape)
Example
;< ~ bind:m (flog-text "foo")
flog-tang
Print a tang
to the terminal via Dill.
Accepts
A tang
Produces
~
Source
++ flog-tang|= =tang=/ m (strand ,~)^- form:m=/ =wall(zing (turn (flop tang) (cury wash [0 80])))|- ^- form:m=* loop $?~ wall(pure:m ~);< ~ bind:m (flog-text i.wall)loop(wall t.wall)
Example
;< ~ bind:m (flog-tang 'foo' 'bar' 'baz' ~)
trace
Slog a tang
to the terminal.
Accepts
A tang
.
Produces
~
Source
++ trace|= =tang=/ m (strand ,~)^- form:m(pure:m ((slog tang) ~))
Example
;< ~ bind:m (trace 'foo' 'bar' 'baz' ~)
app-message
Print a message to the terminal tagged with an app name, like:
my-app: foo bar baz
Then, optionally, print a tang
.
Accepts
A triple of [term cord tang]
. The term
is the app name, the cord
is the message, and the tang
is any traceback.
Produces
~
Source
++ app-message|= [app=term =cord =tang]=/ m (strand ,~)^- form:m=/ msg=tape :(weld (trip app) ": " (trip cord));< ~ bind:m (flog-text msg)(flog-tang tang)
Example
;< ~ bind:m (app-message %foo 'foo bar baz' ~)
Threads
send-thread
Run an inline thread via Khan.
Accepts
A triple of:
bear:khan
: desk or beak.shed:khan
: the thread itself.wire
: the wire for responses from Khan.
Produces
~
Source
++ send-thread|= [=bear:khan =shed:khan =wire]=/ m (strand ,~)^- form:m(send-raw-card %pass wire %arvo %k %lard bear shed)
start-thread
Start a child thread.
Accepts
A term
, the name of a thread in /ted
of this desk.
Produces
A tid:spider
, the ID of the child thread.
Source
++ start-thread|= file=term=/ m (strand ,tid:spider);< =bowl:spider bind:m get-bowl(start-thread-with-args byk.bowl file *vase)
Example
;< ~ bind:m (start-thread %foo)
start-thread-with-args
Start a child thread with arguments.
Accepts
A triple of:
beak
: the ship/desk/case where the thread is located.term
: the name of the thread in/ted
of the given desk.vase
: the start argument.
Produces
A tid:spider
, the ID of the child thread.
Source
++ start-thread-with-args|= [=beak file=term args=vase]=/ m (strand ,tid:spider)^- form:m;< =bowl:spider bind:m get-bowl=/ tid(scot %ta (cat 3 (cat 3 'strand_' file) (scot %uv (sham file eny.bowl))))=/ poke-vase !>(`start-args:spider`[`tid.bowl `tid beak file args]);< ~ bind:m (poke-our %spider %spider-start poke-vase);< ~ bind:m (sleep ~s0) :: wait for thread to start(pure:m tid)
Example
;< now=@da bind:m get-time;< ~ bind:m (start-thread-with-args [~zod %base da+now] %foo !>(~))
thread-result
Type definition of a thread result.
Source
+$ thread-result(each vase [term tang])
await-thread
Start a thread with an argument, then await its result.
Accepts
A pair of [term vase]
where term
is the name of a thread in /ted
of this desk, and vase
contains the start argument.
Produces
Source
++ await-thread|= [file=term args=vase]=/ m (strand ,thread-result)^- form:m;< =bowl:spider bind:m get-bowl=/ tid (scot %ta (cat 3 'strand_' (scot %uv (sham file eny.bowl))))=/ poke-vase !>(`start-args:spider`[`tid.bowl `tid byk.bowl file args]);< ~ bind:m (watch-our /awaiting/[tid] %spider /thread-result/[tid]);< ~ bind:m (poke-our %spider %spider-start poke-vase);< ~ bind:m (sleep ~s0) :: wait for thread to start;< =cage bind:m (take-fact /awaiting/[tid]);< ~ bind:m (take-kick /awaiting/[tid])?+ p.cage ~|([%strange-thread-result p.cage file tid] !!)%thread-done (pure:m %& q.cage)%thread-fail (pure:m %| ;;([term tang] q.q.cage))==
Example
;< =thread-result bind:m (await-thread %foo !>(~))