Revert "Cleanup commit #1; revert this when ready to merge."

This reverts commit c12823babc63665e30fe4e3935ccda80601d6cf8.
This commit is contained in:
C. Guy Yarvin 2016-01-25 16:49:09 -08:00
parent 0231d41cb6
commit a0a2cdf64f
386 changed files with 93867 additions and 0 deletions

2
docs/hymn.hook Normal file
View File

@ -0,0 +1,2 @@
/: /%%%/tree/pub/docs /% /hymn/
-<

2
docs/json.hook Normal file
View File

@ -0,0 +1,2 @@
/: /%%%/tree/pub/docs /% /json/
-<

1
elem.hook Normal file
View File

@ -0,0 +1 @@
;list(data-source "default", is404 "true");

2
front/hymn.hook Normal file
View File

@ -0,0 +1,2 @@
/: /%%%/tree/pub/front /% /hymn/
-<

2
front/json.hook Normal file
View File

@ -0,0 +1,2 @@
/: /%%%/tree/pub/front /% /json/
-<

7
index.hook Normal file
View File

@ -0,0 +1,7 @@
/+ tree
/: /%%/ /% /elem/
::
::::
::
^- (map path marl)
[[/ ((getall:tree /h1/h2/h3/h4/h5/h6) -.-)] ~ ~]

195
lib/base.css Normal file
View File

@ -0,0 +1,195 @@
@font-face {
font-family: "bau";
src: url("//storage.googleapis.com/urbit-extra/bau.woff");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: "bau";
src: url("//storage.googleapis.com/urbit-extra/bau-italic.woff");
font-weight: 400;
font-style: italic;
}
@font-face {
font-family: "bau";
src: url("//storage.googleapis.com/urbit-extra/bau-medium.woff");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: "bau";
src: url("//storage.googleapis.com/urbit-extra/bau-mediumitalic.woff");
font-weight: 500;
font-style: italic;
}
@font-face {
font-family: "bau";
src: url("//storage.googleapis.com/urbit-extra/bau-bold.woff");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: "bau";
src: url("//storage.googleapis.com/urbit-extra/bau-bolditalic.woff");
font-weight: 600;
font-style: italic;
}
@font-face {
font-family: "bau";
src: url("//storage.googleapis.com/urbit-extra/bau-super.woff");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: "bau";
src: url("//storage.googleapis.com/urbit-extra/bau-superitalic.woff");
font-weight: 600;
font-style: italic;
}
@font-face {
font-family: "scp";
src: url("//storage.googleapis.com/urbit-extra/scp-extralight.woff");
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("//storage.googleapis.com/urbit-extra/scp-light.woff");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("//storage.googleapis.com/urbit-extra/scp-regular.woff");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("//storage.googleapis.com/urbit-extra/scp-medium.woff");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("//storage.googleapis.com/urbit-extra/scp-bold.woff");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: "scp";
src: url("//storage.googleapis.com/urbit-extra/scp-black.woff");
font-weight: 700;
font-style: normal;
}
html,
body {
margin: 0;
padding: 0;
}
html,
input,
button,
body {
font-family: "bau";
font-size: 18px;
}
pre,
code,
.mono {
font-family:"scp";
}
#c {
width: 32rem;
margin-left: -16rem;
position: absolute;
left: 50%;
}
h1,
h2 {
font-weight: 500;
}
h1 {
font-size: 1.6rem;
}
h1:after {
content: "\2014";
margin-left: 1rem;
}
h2 {
font-size: 1rem;
}
h2.advice {
margin-top: 2rem;
color: #555;
}
#c pre {
font-size: .6rem;
margin-top: 2rem;
}
#pass {
width: 32rem;
}
button {
border: .3rem solid #000;
background-color: #fff;
font-size: 1rem;
padding: .3rem;
font-weight: 500;
}
.sig {
font-weight: 400;
font-size: 2rem;
display: inline;
vertical-align: middle;
}
span#ship {
font-family: 'bau';
font-weight: 400;
font-size: 1.2rem;
text-transform: uppercase;
letter-spacing: .1rem;
display: inline-block;
min-width: 1rem;
}
input {
font-family: 'scp';
display: inline;
}
span#ship,
input {
border: none;
padding: .3rem;
outline: none;
border-bottom: 3px solid #555;
}
@media only screen and (min-device-width: 320px) and (max-device-width: 480px) {
#c {
width: 16rem;
margin-left: -8rem;
}
#pass {
width: 16rem;
}
input {
-webkit-appearance: none;
border-radius: 0;
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
.CodeMirror {
height: 100%
}
.cm-s-default .cm-atom {color: #70f}
.cm-s-default .cm-operator {color: #097}

176
lib/syntax/hoon.js Normal file
View File

@ -0,0 +1,176 @@
CodeMirror.defineMode("hoon", function() {
glyph = /[+\-|$%:.#^~;=?!_,&\/<>%*]/
term = /^[$&|]|^[a-z]([a-z0-9\-]*[a-z0-9])?/
num = /-?-?^[0-9]([0-9.]*|[xwbv]?[0-9a-zA-Z.-~]*)/
res = {}
res.startState = function(){return {soblock: false, doqblock:false, inter:[], sail:false, space:true}}
var propOrVar = function(c){
if(c == '.')
return 'property'
return 'variable'
}
var nomQuote = function(stream,state){
reg = new RegExp('^[^'+state.inter[0]+'{\\\\]')
while(stream.match(reg) || stream.match(/\\./));
if(!stream.eat("{")) {
if(state.inter[0]){stream.eat(state.inter[0])}
state.inter.shift()
}
return 'string'
}
res.token = function(stream, state){
if(state.soqblock && stream.sol()){
if(stream.match(/\s*'''/)){
state.soqblock = false
}
else {
stream.skipToEnd()
}
return "string"
}
if(state.doqblock){
if(stream.match(/\s*"""/)){
state.doqblock = false
}
else {
stream.skipToEnd()
}
return "string"
}
if((state.inter.length) && stream.eat('}')){
return nomQuote(stream,state)
}
if(stream.sol())
state.space = true
if(state.sail){
if(stream.peek().match(/[^#./() ]/)||stream.eol()){
state.sail = false
if(stream.match(/:? /)){
// state.inter = ''
stream.skipToEnd()
return 'string'
}
if(stream.match(term))
state.sail = true
return;
if(stream.match(':'))
state.sail = true
return 'operator'
}
}
if(stream.match("'")){
if(stream.match("''")){
state.soqblock = true
return 'string'
}
while(stream.match(/^[^'\\]/) || stream.match(/\\./));
stream.eat("'")
return 'string'
}
if(stream.match('"')){
if(stream.match('""')){
state.doqblock = true
stream.skipToEnd()
return 'string'
}
state.inter.unshift('"')
return nomQuote(stream,state)
}
if(stream.match(' ;')){
if(stream.eat(' ')){
stream.skipToEnd()
return 'string'
}
if(!stream.match(glyph)){
state.sail = true
}
return 'builtin'
}
if(stream.match('::')){
stream.skipToEnd()
return 'comment'
}
if(stream.match('++ ') || stream.match('+- ')){
stream.match(term)
return 'header'
}
if(state.space && stream.match('--')){
if(stream.eat(glyph) || stream.eat(/[a-z0-9]/))
stream.backUp(3)
else return 'header'
}
if(stream.eat('%'))
if(stream.match(term) || stream.match(num))
return 'tag'
else stream.backUp(1)
if(state.space && stream.match('==')){
return 'tag'
}
if(stream.match(/^@[a-z]*[A-Z]?/))
return 'atom'
if(stream.match(num))
return 'number'
if(stream.eat(/[+\-]/)){
while(stream.eat(/[<>]/) && stream.eat(/[+\-]/));
return propOrVar(stream.peek())
}
if(stream.eat('`')){
state.space = true
return 'operator'
}
if(stream.sol() && stream.eatWhile(glyph)){
state.space = false
return 'builtin'
}
if(stream.eat(glyph)){
state.space = false
stream.backUp(2)
if(stream.eat(/[ ([{]/) || (stream.peek().match(/[^+\-<>]/)
&& stream.eat(glyph))){ // expression start
stream.eatWhile(glyph)
return 'builtin'
}
stream.next()
if(state.space && stream.eat('=')){
if(/[()]/.exec(stream.peek()))
return 'builtin'
return 'operator'
}
if(stream.eat(/[=:.^]/)){
state.space = true
return 'operator'
}
stream.next()
return 'builtin'
}
if(stream.match(term)){
if(state.space && stream.match('/'))
return 'tag'
state.space = false
return propOrVar(stream.peek())
}
if(stream.eat(/[ \[(]/)){
state.space = true
return
}
if(stream.eat(')') || stream.eat(']')){ // XX paren match
return
}
stream.next()
return "error"
}
res.lineComment = '::'
res.fold = "indent"
return res
});
CodeMirror.registerHelper("wordChars", "hoon", /[-\\w]/);
CodeMirror.defineMIME("text/x-hoon", "hoon");

306
lib/urb.js Normal file
View File

@ -0,0 +1,306 @@
if(!window.urb.appl) window.urb.appl = null
window.urb.req = function(method,url,params,json,cb) {
var xhr = new XMLHttpRequest()
method = method.toUpperCase()
if(method == "PUT" || method == "DELETE")
xhr.open("POST", url+"?"+method)
else xhr.open(method, url)
if(json)
xhr.setRequestHeader("content-type", "text/json")
if(!window.urb.oryx) throw "No CSRF token" // XX fetch auth.json
_data = {oryx: window.urb.oryx}
if(params.xyro) { _data.xyro = params.xyro; }
if(params.ship) { _data.ship = params.ship; }
if(params.path) { _data.path = params.path; }
if(params.appl) { _data.appl = params.appl; }
if(params.mark) { _data.mark = params.mark; }
if(params.wire) { _data.wire = params.wire; }
if(cb) {
xhr.onload = function() {
var err,res
try {
err = null
res = {
status:this.status,
data: JSON.parse(this.responseText)
}
if(res.data.reload)
res.reload = res.data.reload
} catch(e) {
// if(urb.wall !== false) document.write(this.responseText) // XX
err = {
message:"Failed to parse JSON",
raw:this.responseText
}
res = null
}
finally {
cb(err,res)
}
}
xhr.onerror = function() {
cb({
status:this.status,
data:this.responseText
})
}
}
xhr.send(JSON.stringify(_data))
}
// window.urb.getJSON = function(url,cb){ window.urb.reqJSON("GET",url, null, cb)}
// window.urb.reqJSON = function(method, url, data, cb){
// var xhr = new XMLHttpRequest()
// xhr.open(method, url)
// xhr.onload = function(){
// urb.fetchTag.call(xhr)
// if(cb) cb(JSON.parse(xhr.responseText))
// }
// xhr.send(data === null ? null : JSON.stringify(data))
// }
window.urb.reqq = []
window.urb.qreq = function(method,url,params,json,cb) {
walk = function() {
qobj = {}
qobj.oargs = window.urb.reqq[0]
qobj.nargs = [].slice.call(qobj.oargs,0,4)
qobj.nargs.push(function(){
if(this.oargs[4])
this.oargs[4].apply(window.urb,arguments)
window.urb.reqq.shift()
if(window.urb.reqq.length > 0)
walk()
}.bind(qobj))
window.urb.req.apply(this,qobj.nargs)
}
l = window.urb.reqq.length
window.urb.reqq.push(arguments);
if(l == 0) { walk() }
}
window.urb.send = function(data,params,cb) { // or send(data, cb)
if(!params || typeof params === "function")
{cb = params; params = {}}
var url, $send
$send = this.send
params.data = data
params.ship = params.ship || this.ship
params.appl = params.appl || this.appl
params.mark = params.mark || $send.mark
// params.seqn = params.seqn || $send.seqn
params.wire = params.wire || "/"
params.xyro = (typeof(params.data) === 'undefined') ? null : params.data
if(!params.mark) throw new Error("You must specify a mark for urb.send.")
if(!params.appl) throw new Error("You must specify an appl for urb.send.")
url = ["to",params.appl,params.mark]
url = "/~/"+url.join("/")
// $send.seqn++
this.qreq('post',url,params,true,function(err,data) {
/* if(err) { $send.seqn--; }
else */ if(data && data.data.fail && urb.wall !== false)
document.write("<pre>"+JSON.stringify(params.xyro)+"\n"
+data.data.mess+"</pre>") // XX
if(cb) { cb.apply(this,arguments); }
})
}
// window.urb.send.seqn = 0
window.urb.send.mark = "json"
window.urb.gsig = function(params) {
var path = params.path
if(!path) path = ""
if(path[0] !== "/") path = "/"+path
return "~"+params.ship+"/"+
params.appl+
path.replace(/[^\x00-\x7F]/g, "")
}
window.urb.puls = false
window.urb.cabs = {}
window.urb.poll = function(params) {
if(!params) throw new Error("You must supply params to urb.poll.")
var url, $this
seqn = this.poll.seqn
if(params.seqn) seqn = params.seqn()
url = "/~/of/"+this.ixor+"?poll="+seqn
this.puls = true
$this = this
this.req("get",url,params,true,function(err,res) {
$this.poll.dely = params.dely || $this.poll.dely
if(res){
if(res.data.beat)
return $this.poll(params)
switch(res.data.type){
case "news":
return document.location.reload() // XX check autoreload
case "rush":
case "mean":
var err2 = err
if(res.data.type == "mean")
err2 = res.data.data
var fn = $this.gsig(res.data.from)
if($this.cabs[fn])
$this.cabs[fn].call(this,err2,
{status: res.status, data: res.data.data.json}) // XX non-json
break;
default:
throw new Error("Lost event %"+res.data.type)
}
if(params.incs)
params.incs()
else
$this.poll.seqn++
$this.poll.dely = 250
return $this.poll(params)
}
else if(err){
setTimeout(function() {
$this.poll(params)
}, $this.poll.dely)
$this.poll.dely += Math.ceil($this.poll.dely*.2)
}
else throw "Neither error nor result on poll"
})
}
window.urb.poll.seqn = 1
window.urb.poll.dely = 250
window.urb.bind = function(path, params, cb, nicecb){ // or bind(path, cb)
if(!params || typeof params === "function")
{cb = params; params = {}}
params.path = path
if(params.path[0] !== "/") params.path = "/"+params.path
params.ship = params.ship || this.ship
params.appl = params.appl || this.appl
params.mark = params.mark || this.bind.mark
params.wire = params.wire || params.path
if(typeof path != "string")
throw new Error("You must specify a string path for urb.bind.")
if(!params.appl) throw new Error("You must specify an appl for urb.bind.")
if(!cb) throw new Error("You must supply a callback to urb.bind.")
var method, perm, url, $this
if(params.mark !== "json")
throw new Error("Non-json subscriptions unimplemented.") // XX
url = "/~/is/"+this.gsig(params)+"."+params.mark
params.path = params.wire
this.cabs[this.gsig(params)] = cb
$this = this
this.qreq("put",url,params,true,function(err,res) {
if(nicecb) { nicecb.apply(this,[err,{status: res.status, data: res.data}])}
// XX give raw data
//
if(!err && !$this.puls) $this.poll(params)
})
}
urb.bind.mark = "json"
window.urb.drop = function(path, params, cb){ // or drop(path,cb)
if(typeof params === "function")
{cb = params; params = {}}
params.path = path
if(params.path[0] !== "/") params.path = "/"+params.path
params.ship = params.ship || this.ship
params.appl = params.appl || this.appl
params.wire = params.wire || params.path
if(typeof path != "string")
throw new Error("You must specify a string path for urb.drop.")
if(!params.appl) throw new Error("You must specify an appl for urb.drop.")
url = "/~/is/"+this.gsig(params)+".json"
method = "delete"
this.req("delete",url,params,true,function(err,res) {
if(cb) cb(err,res)
})
}
window.urb.subscribe = function(params,cb) { // legacy interface
if(!params) throw new Error("You must supply params to urb.subscribe")
return window.urb.bind(params.path, params, cb, cb)
}
window.urb.unsubscribe = function(params,cb) { // legacy intreface
if(!params) throw new Error("You must supply params to urb.unsubscribe.")
return window.urb.drop(params.path, params, cb)
}
window.urb.util = {
isURL: function(s) {
r = new RegExp('^(?!mailto:)(?:(?:http|https|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$', 'i');
return s.length < 2083 && r.test(s);
},
numDot: function(n) {
_n = String(n)
fun = function(s){
if(s.length <= 3)
return s
return fun(s.slice(0,-3))+"."+s.slice(-3)
}
return fun((_n))
},
toDate: function (dat){
var mils = Math.floor((0x10000 * dat.getUTCMilliseconds()) / 1000).toString(16)
function pad(num, str){
return ((new Array(num + 1)).join('0') + str).substr(-num,num)
}
return '~' + dat.getUTCFullYear() +
'.' + (dat.getUTCMonth() + 1) +
'.' + dat.getUTCDate() +
'..' + pad(2, dat.getUTCHours()) +
'.' + pad(2, dat.getUTCMinutes()) +
'.' + pad(2, dat.getUTCSeconds()) +
'..' + pad(4, mils)
},
basepath: function(spur, pathname){
spur = spur || ''
if(spur === '/') spur = ''
pathname = pathname || window.location.pathname
if(pathname[0] == '/') pathname = pathname.slice(1)
pathname = pathname.split("/")
var pref, pred, prec, base = ""
while(base += "/"+(pref = pathname.shift()), pathname.length>0){
if(pref[0] !== '~') break;
if(pref === "~~") continue;
base += "/"+(pred = pathname.shift())
if(/[a-z\-]+/.test(pref.slice(1))){
base += "/"+(prec = pathname.shift())
if(prec == null) throw "Bad basepath."
break;
}
if(pref !== "~") throw "Bad basepath /"+pref
if(pred === "as"){
base += "/"+(prec = pathname.shift())
if(prec == null) throw "Bad basepath."
continue;
}
throw "Bad basepath /~/"+pred
}
return base+spur
}
}

12
mar/acto-game.hoon Normal file
View File

@ -0,0 +1,12 @@
::
:::: /hoon+octo-game+mar
::
/? 310
!:
|_ cod/{who/? box/@ boo/@} :: game state
::
++ grab :: convert from
|%
++ noun {who/? box/@ boo/@} :: clam from $noun
--
--

17
mar/ask-mail.hoon Normal file
View File

@ -0,0 +1,17 @@
::
:::: /hoon+ask-mail+mar
::
/? 314
|_ txt/cord
::
++ grab :: convert from
|%
++ noun @t :: clam from %noun
++ json (cork so:jo need)
--
++ grow
|%
++ psal ;div: {(trip txt)}
++ mime [text+/plain (taco txt)]
--
--

14
mar/atom.hoon Normal file
View File

@ -0,0 +1,14 @@
::
:::: /hoon/atom/mar
::
/? 314
!:
:::: A minimal atom mark
|_ ato/@
++ grab |%
++ noun @
++ mime |=({* p/octs} q.p)
--
++ grow |%
++ mime [/application/x-urb-unknown (taco ato)]
-- --

21
mar/bit/accounts.hoon Normal file
View File

@ -0,0 +1,21 @@
:: this mark is used to receive a confirmed transaction
::
:::: /hoon+bit-accounts+mar
::
/? 310
/- bit-api
!:
[bit-api .]
|_ bit-accounts
::
++ grab :: converter arm
|%
++ noun bit-accounts :: clam from noun
++ json |= jon/^json ^- bit-accounts
~| jon
%- need %. jon
=> jo
=+ bal=(ot amount+so currency+(cu cass sa) ~)
(ot accounts+(ar (ot id+so name+so balance+bal ~)) ~)
--
--

5
mar/bit/addr-made.hoon Normal file
View File

@ -0,0 +1,5 @@
|_ @t
++ grab |%
++ noun cord
--
--

View File

@ -0,0 +1,6 @@
|_ $~
++ grab |%
++ noun $~
--
--

31
mar/bit/api-call.hoon Normal file
View File

@ -0,0 +1,31 @@
::
:::: /hoon/bit-api-call/mar
::
/? 314
/- bit-api
[bit-api .]
|_ {access-token/@t req/bit-api-call}
::
++ wrap
|= {end-point/path req/$@($get {$post p/json})}
[/com/coinbase/sandbox/api v1+end-point req ~ ['access_token' access-token]~]
::
++ order
|= {amount/@t currency/@t} ^- json
(jobe qty+s+amount ?~(currency ~ [currency+s+currency ~]))
++ grow
|% ++ httpreq
%- wrap
|-
?- -.req
$list [/accounts %get]
$buy [/buys %post (order +.req)]
$sell [/sells %post (order +.req)]
$send $(req [%txt-send (rsh 3 2 (scot %uc adr.req)) btc.req])
$txt-send
:+ /transactions/'send_money' %post
(joba %transaction (jobe to+s+to.req amount+s+btc.req ~))
==
--
--

21
mar/bit/get-token.hoon Normal file
View File

@ -0,0 +1,21 @@
::
:::: /hoon/bit-get-token/mar
::
/? 314
/- bit-api
/+ http
[bit-api .]
|_ req/bit-get-token
::
++ grow
|% ++ httpreq
^- request:http
=- [/com/coinbase/sandbox /oauth/token [%post ~] ~ `quay`-]
:~ ['grant_type' 'authorization_code']
['code' oat.req]
['redirect_uri' (crip (earn red.req))]
['client_id' cid.req]
['client_secret' sec.req]
==
--
--

17
mar/bit/transaction.hoon Normal file
View File

@ -0,0 +1,17 @@
:: this mark is used to receive a confirmed transaction
::
:::: /hoon+bit-transaction+mar
::
/? 310
!:
|_ id/@t ::XX time
::
++ grab :: converter arm
|%
++ noun @t :: clam from noun
++ json |= jon/^json
~| jon
(need ((ot transaction+(ot id+so ~) ~):jo jon))
--
--

12
mar/client-secret.hoon Normal file
View File

@ -0,0 +1,12 @@
::
:::: /hoon+client-secret+mar
::
/? 314
|_ txt/cord
::
++ grab :: convert from
|%
++ noun @t :: clam from %noun
++ json (cork so:jo need)
--
--

16
mar/cloud/auth.hoon Normal file
View File

@ -0,0 +1,16 @@
:: this mark is used to receive incoming oauth2 tokens that we use to poke our %gall server
::
:::: /hook+door+do-auth+mar
::
/? 310
!:
|_ cod/cord
::
++ grab :: converter arm
|%
++ noun @t :: clam from noun
++ json (cork (ot authcode+so platform+so ~):jo need) :: (need (so:jo jon))
--
--

9
mar/cloud/secret.hoon Normal file
View File

@ -0,0 +1,9 @@
!:
|_ cod/cord
::
++ grab :: converter am
|%
++ noun @t :: clam from noun
++ json (cork (ot secret+so platform+so ~):jo need)
--
--

16
mar/coffee.hoon Normal file
View File

@ -0,0 +1,16 @@
::
:::: /hoon/core/md/pro
::
/? 314
|_ mud/@t
++ grow
|%
++ mime [/text/coffeescript (taco mud)]
--
++ grab
|%
++ mime |=({p/mite q/octs} (@t q.q))
++ noun @t
--
++ grad %mime
--

18
mar/css.hoon Normal file
View File

@ -0,0 +1,18 @@
::
:::: /hoon/core/css/mar
::
|_ mud/@t
++ grow :: convert to
|% ++ mime [/text/css (taco mud)] :: convert to %mime
++ elem ;style :: convert to %hymn
;- (trip mud)
==
++ hymn ;html:(head:"{elem}" body)
--
++ grab
|% :: convert from
++ mime |=({p/mite q/octs} (@t q.q))
++ noun @t :: clam from %noun
--
++ grad %mime
--

36
mar/down.hoon Normal file
View File

@ -0,0 +1,36 @@
::
:::: /hoon+down+mar
::
/? 314
/- markdown
/+ down-jet, frontmatter
::
::::
::
[markdown .]
|_ don/down
++ grab :: convert from
|%
++ noun down :: clam from %noun
++ md
|= src/@t
=+ [atr mud]=(parse:frontmatter (lore src))
[[%meta atr] (mark:down-jet mud)]
--
::
++ grow :: convert into
|%
++ hymn :: convert to %hymn
;html
;head:title:"Untitled"
;body
;* (print:down-jet don)
==
==
++ elem :: convert to %elem
;div
;* (print:down-jet don)
==
:: ++ react elem
--
--

15
mar/elem.hoon Normal file
View File

@ -0,0 +1,15 @@
::
:::: /hoon/core/elem/mar
::
/? 314
|_ own/manx
::
++ grow :: convert to
|%
++ hymn ;html:(head:title:"Untitled" body:"+{own}") :: convert to %hymn
++ html (crip (poxo hymn)) :: convert to %html
++ mime [/text/html (taco html)] :: convert to %mime
--
++ grab |% :: convert from
++ noun manx :: clam from %noun
-- --

21
mar/eot.hoon Normal file
View File

@ -0,0 +1,21 @@
:: probly
:::: /hoon/core/eot/pro
::
/? 314
::
:::: compute
::
|_ otf/@
::
++ grow :: convert to
|%
++ mime :: convert to %mime
[/font/eot (taco otf)]
--
++ grab
|%
++ mime |=({p/mite q/octs} q.q)
++ noun @
--
++ grad %mime
--

17
mar/helm-hi.hoon Normal file
View File

@ -0,0 +1,17 @@
::
:::: /hoon+helm-hi+mar
::
/? 314
|_ txt/cord
::
++ grab :: convert from
|%
++ noun @t :: clam from %noun
++ json (cork so:jo need)
--
++ grow
|%
++ psal ;div: {(trip txt)}
++ mime [text+/plain (taco txt)]
--
--

1
mar/helm/reload.hoon Normal file
View File

@ -0,0 +1 @@
|*(* ~)

9
mar/hiss.hoon Normal file
View File

@ -0,0 +1,9 @@
::
:::: /hoon+hiss+mar
::
/? 314
/+ http
|_ hiss
::
++ grab |% ++ httpreq request-to-hiss:http
-- --

18
mar/html.hoon Normal file
View File

@ -0,0 +1,18 @@
::
:::: /hoon/core/html/mar
::
/? 314
::
:::: compute
::
|_ htm/@t
::
++ grow :: convert to
|% ::
++ mime [/text/html (met 3 htm) htm] :: to %mime
++ hymn (need (poxa htm)) :: to %hymn
-- ::
++ grab |% :: convert from
++ noun @t :: clam from %noun
++ mime |=({p/mite q/octs} q.q) :: retrieve form $mime
-- --

9
mar/httpreq.hoon Normal file
View File

@ -0,0 +1,9 @@
::
:::: /hoon+core+httpreq+pro
::
/? 314
/+ http
::
|_ req/request:http
++ grow |% ++ tank >req<
-- --

23
mar/index.hoon Normal file
View File

@ -0,0 +1,23 @@
::
:::: /hoon+core+elem+mar
::
/? 314
/+ tree,react
[. tree react]
!:
::::
::
|_ all/(map path marl)
::
++ grow :: convert to
|%
++ json
%. all
%+ map-to-json
|=(a/path (crip (spud a)))
|=(a/marl [%a (turn a react-to-json)])
--
++ grab |% :: convert from
++ noun (map path marl) :: clam from %noun
::++ elem |=(a=manx `_all`[[/ ((getall %h1) a)] ~ ~])
-- --

20
mar/js.hoon Normal file
View File

@ -0,0 +1,20 @@
::
:::: /hoon/core/js/mar
::
!:
|_ mud/@
++ grow
|%
++ mime [/application/javascript (taco (@t mud))]
++ elem ;script
;- (trip (@t mud))
==
++ hymn ;html:(head:"+{elem}" body)
--
++ grab
|% :: convert from
++ mime |=({p/mite q/octs} (@t q.q))
++ noun cord :: clam from %noun
--
++ grad %mime
--

23
mar/json.hoon Normal file
View File

@ -0,0 +1,23 @@
::
:::: /hoon/core/json/mar
::
/? 314
::
:::: compute
::
|_ jon/json
::
++ grow :: convert to
|%
++ mime [/text/json (taco txt)] :: convert to %mime
++ txt (crip (pojo jon))
--
++ grab
|% :: convert from
++ mime |=({p/mite q/octs} (fall (rush (@t q.q) apex:poja) *json))
++ noun json :: clam from %noun
++ numb jone
++ time jode
--
++ grad %mime
--

10
mar/load.hoon Normal file
View File

@ -0,0 +1,10 @@
::
:::: /hoon+core+load+mar
::
!:
|_ man/span
++ grab
|% :: convert from
++ noun span :: clam from %noun
--
--

10
mar/log.hoon Normal file
View File

@ -0,0 +1,10 @@
::
:::: /hoon+core+log+mar
::
!:
|_ man/span
++ grab
|% :: convert from
++ noun span :: clam from %noun
--
--

25
mar/markdown.hoon Normal file
View File

@ -0,0 +1,25 @@
::
:::: /hoon/core/markdown/pro
::
/? 314
::
|_ mud/@t
++ grow
|%
++ mime [/text/x-markdown (taco mud)]
++ md mud
++ txt
(lore (cat 3 mud '\0a'))
--
++ grab
|%
++ mime |=({p/mite q/octs} q.q)
++ noun @t
++ md |=(@t +<)
++ txt
|= wan/wain
=+ (role wan)
(end 3 (dec (met 3 -)) -)
--
++ grad %txt
--

23
mar/md.hoon Normal file
View File

@ -0,0 +1,23 @@
::
:::: /hoon/core/md/pro
::
/? 314
::
|_ mud/@t
++ grow
|%
++ mime [/text/x-markdown (taco mud)]
++ txt
(lore (cat 3 mud '\0a'))
--
++ grab
|%
++ mime |=({p/mite q/octs} q.q)
++ noun @t
++ txt
|= wan/wain
=+ (role wan)
(end 3 (dec (met 3 -)) -)
--
++ grad %txt
--

22
mar/mdy.hoon Normal file
View File

@ -0,0 +1,22 @@
::
:::: /hoon/core/mdy/pro
::
/? 314
/+ frontmatter
!:
|_ {atr/(map cord cord) mud/@t}
++ grow
|%
++ front atr
++ mime [/text/x-markdown (taco md)]
++ md (role txt)
++ txt (print:frontmatter atr (lore mud))
--
++ grab
|%
++ noun {(map cord cord) @t}
++ md (cork lore txt)
++ txt parse:frontmatter
--
++ grad %txt
--

15
mar/oauth-tokens.hoon Normal file
View File

@ -0,0 +1,15 @@
:: this mark is used to receive incoming oauth2 refresh+access tokens
::
:::: /hoon+oauth-tokens+mar
::
/? 310
!:
|_ {tok/@t ref/@t}
::
++ grab :: converter arm
|%
++ noun {@t @t} :: clam from noun
++ json (corl need (ot 'access_token'^so 'refresh_token'^so ~):jo)
--
--

15
mar/oauth2-code.hoon Normal file
View File

@ -0,0 +1,15 @@
:: this mark is used to receive incoming oauth2 tokens that we use to poke our %gall server
::
:::: /hoon+oauth2-code+mar
::
/? 310
!:
|_ cod/cord
::
++ grab :: converter arm
|%
++ noun @t :: clam from noun
++ json (cork so:jo need) :: (need (so:jo jon))
--
--

16
mar/oct3/move.hoon Normal file
View File

@ -0,0 +1,16 @@
::
:::: /hoon+oct3-move+mar
::
/? 314
!:
::::
::
=+ point={x/@ y/@}
|_ point
::
++ grab :: convert from
|%
++ json (corl need (at ni ni ~):jo) :: reparse from %json
++ noun point :: clam from %noun
--
--

35
mar/oct3/update.hoon Normal file
View File

@ -0,0 +1,35 @@
:: :: ::
:::: /hoon+oct3-update+mar :::::: dependencies
:: :: ::
/? 310 :: arvo
/- oct3 :: structures
/+ oct3 :: libraries
[. oct3 ^oct3]
!: :: ::
:::: :: :: protocol
:: :: ::
|_ play :: game
++ grab :: convert from
|%
++ noun play :: from %noun
--
++ grow :: convert to
|%
++ json ^- ^json :: to %json
~! +>-<
?: ?=({$|} +>-<)
~! +>-<
~! p
s+(crip p)
=+ she=|=(ship s+(scot %p +<))
=+ hes=|=({ship *} (she +<-))
%- jobe
:~ who+s+?:(who.p %x %o)
plx+?~(p.sag.p ~ (she u.p.sag.p))
plo+?~(q.sag.p ~ (she u.q.sag.p))
aud+a+(turn (~(tap by aud.p)) hes)
box+~(jon bo box.p)
boo+~(jon bo boo.p)
==
--
--

16
mar/oct4/move.hoon Normal file
View File

@ -0,0 +1,16 @@
::
:::: /hoon+oct4-move+mar
::
/? 314
!:
::::
::
=+ point={x/@ y/@}
|_ point
::
++ grab :: convert from
|%
++ json (corl need (at ni ni ~):jo) :: reparse from %json
++ noun point :: clam from %noun
--
--

35
mar/oct4/update.hoon Normal file
View File

@ -0,0 +1,35 @@
:: :: ::
:::: /hoon+oct4-update+mar :::::: dependencies
:: :: ::
/? 310 :: arvo
/- oct4 :: structures
/+ oct4 :: libraries
!: :: ::
:::: :: :: protocol
:: :: ::
[oct4 ^oct4 .]
|_ play :: game
++ grab :: convert from
|%
++ noun play :: from %noun
--
++ grow :: convert to
|%
++ json ^- ^json :: to %json
~! +>-<
?: ?=($| +>-<)
~! +>-<
~! p
s+(crip p)
=+ she=|=(ship s+(scot %p +<))
=+ hes=|=({ship *} (she +<-))
%- jobe
:~ who+s+?:(who.p %x %o)
plx+?~(p.sag.p ~ (she u.p.sag.p))
plo+?~(q.sag.p ~ (she u.q.sag.p))
aud+a+(turn (~(tap by aud.p)) hes)
box+~(jon bo box.p)
boo+~(jon bo boo.p)
==
--
--

20
mar/otf.hoon Normal file
View File

@ -0,0 +1,20 @@
::
:::: /hoon/core/otf/pro
::
/? 314
::
:::: compute
::
|_ otf/mime
::
++ grow :: convert to
|%
++ mime otf :: convert to %mime
--
++ grab
|%
++ mime |=({mite p/octs} [/font/otf p])
++ noun ^mime
--
++ grad %mime
--

13
mar/purl.hoon Normal file
View File

@ -0,0 +1,13 @@
::
:::: /hoon+purl+mar
::
/? 314
|_ url/purl
::
++ grow |% ++ hiss [url %get ~ ~]
--
++ grab :: convert from
|%
++ noun purl :: clam from %noun
--
--

31
mar/react-snip.hoon Normal file
View File

@ -0,0 +1,31 @@
::
:::: /hoon/core/react-snip/mar
::
/? 314
/+ react
!:
::::
::
[. react]
|_ {hed/marl tal/marl}
::
++ grow :: convert to
|%
++ mime [/application/json (tact tape)]
++ tape (pojo react-snips-json)
++ elem ;div:(h1:"*{hed}" div:"*{tal}")
++ react-snip-js (crip (react-to-tape elem))
++ react-snips-json
::?> ?=([[%div ~] [[%h1 ~] *] [[%div ~] *] ~]] own) :: xx mystery fish-loop
%^ jobe
head+react-head-json
body+react-snip-json
~
::
++ react-head-json (react-to-json ;h1:"*{hed}")
++ react-snip-json (react-to-json ;div:"*{tal}")
--
++ grab |% :: convert from
++ noun manx :: clam from %noun
++ snip |=(a/{marl marl} a)
-- --

23
mar/react.hoon Normal file
View File

@ -0,0 +1,23 @@
::
:::: /hoon/core/react/mar
::
/? 314
/+ react
!:
::::
::
[. react]
|_ own/manx
::
++ grow :: convert to
|%
++ tape (pojo react-json)
++ react-js (crip (react-to-tape own))
:: ++ js react-js :: convert to %js
++ react-json (react-to-json own)
++ mime [/application/json (tact tape)] :: convert to %mime
--
++ grab |% :: convert from
++ noun manx :: clam from %noun
++ elem |= a/manx a
-- --

10
mar/save.hoon Normal file
View File

@ -0,0 +1,10 @@
::
:::: /hoon+core+save+mar
::
!:
|_ man/span
++ grab
|% :: convert from
++ noun span :: clam from %noun
--
--

28
mar/sched.hoon Normal file
View File

@ -0,0 +1,28 @@
!:
:::: /hoon/core/sched/mar
::
|_ dat/(map @da cord)
++ grow :: convert to
|% ++ mime [/text/x-sched (tact tape)]
++ tape
(zing `wall`(turn sorted-list |=({a/@da b/cord} "{<a>} {(trip b)}\0a")))
++ elem =< ;ul: *{(turn sorted-list .)}
|= {tym/@da ite/cord} ^- manx
;li: ;{b "{<tym>}"}: {(trip ite)}
++ sorted-list
(sort (~(tap by dat)) |=({{l/@ @} {r/@ @}} (lth l r)))
--
++ grab
|% :: convert from
++ mime
|= {p/mite q/octs} ^+ dat
=< (mo (turn (lore q.q) .))
|= a/@t ^- {@da @t}
%+ rash a
;~ (glue ace)
(cook |=(a/coin ?>(?=({$~ $da @} a) `@da`q.p.a)) nuck:so)
(cook crip (star prn))
==
--
++ grad %mime
--

60
mar/snip.hoon Normal file
View File

@ -0,0 +1,60 @@
::
:::: /hoon+core+elem+mar
::
/? 314
!:
|%
++ words 1
++ hedtal
=| met/marl
|= a/marl ^- {hed/marl tal/marl}
?~ a [~ ~]
?. ?=($h1 n.g.i.a)
?: ?=($meta n.g.i.a)
$(a t.a, met [i.a met])
=+ had=$(a c.i.a)
?^ -.had had
$(a t.a)
[c.i.a (weld (flop met) (limit words t.a))]
::
++ limit
|= {lim/@u mal/marl}
=< res
|- ^- {rem/@u res/marl}
?~ mal [lim ~]
?~ lim [0 ~]
=+ ^- {lam/@u hed/manx}
?: ?=(_:/(**) i.mal)
[lim :/(tay)]:(deword lim v.i.a.g.i.mal)
[rem ele(c res)]:[ele=i.mal $(mal c.i.mal)]
[rem - res]:[hed $(lim lam, mal t.mal)]
::
++ deword
|= {lim/@u tay/tape} ^- {lim/@u tay/tape}
?~ tay [lim tay]
?~ lim [0 ~]
=+ wer=(dot 1^1 tay)
?~ q.wer
[lim - tay]:[i.tay $(tay t.tay)]
=+ nex=$(lim (dec lim), tay q.q.u.q.wer)
[-.nex [(wonk wer) +.nex]]
--
::
!:
|_ {hed/marl tal/marl}
::
++ grow :: convert to
|%
++ mime
=< mime
|%
++ elem ;div:(h1:"*{hed}" div:"*{tal}") :: convert to %elem
++ hymn ;html:(head:title:"snip" body:"+{elem}") :: convert to %hymn
++ html (crip (poxo hymn)) :: convert to %html
++ mime [/text/html (taco html)] :: convert to %mime
--
--
++ grab |% :: convert from
++ noun {marl marl} :: clam from $noun
++ elem |=(a/manx (hedtal +.a))
-- --

38
mar/sole/action.hoon Normal file
View File

@ -0,0 +1,38 @@
::
:::: /hoon+sole-action+mar
::
/? 314
/- sole
!:
::::
::
[sole .]
|_ sole-action
::
++ grab :: convert from
|%
++ json
|= jon/^json ^- sole-action
%- need %. jon
=> [jo ..sole-action]
|^ (fo %ret (of det+change ~))
++ fo
|* {a/term b/fist}
|=(c/json ?.(=([%s a] c) (b c) (some [a ~])))
::
++ ra
|* {a/{p/term q/fist} b/fist}
|= c/json %. c
?.(=(%a -.c) b (pe p.a (ar q.a)))
::
++ change (ot ler+(at ni ni ~) ted+(cu |*(a/* [0v0 a]) edit) ~)
++ char (cu turf so)
++ edit
%+ fo %nop
%+ ra mor+|=(json (edit +<))
(of del+ni set+(cu tuba sa) ins+(ot at+ni cha+char ~) ~)
--
::
++ noun sole-action :: clam from %noun
--
--

60
mar/sole/effect.hoon Normal file
View File

@ -0,0 +1,60 @@
::
:::: /hoon+sole-effect+mar
::
/? 314
/- sole
!:
::::
::
[sole .]
|%
++ mar-sole-change :: XX dependency
|_ cha/sole-change
++ grow
|% ++ json
^- ^json
=+ cha
=< (jobe ted+(. ted) ler+a+~[(jone own.ler) (jone his.ler)] ~)
|= det/sole-edit
?- -.det
$nop [%s 'nop']
$mor [%a (turn p.det ..$)]
$del (joba %del (jone p.det))
$set (joba %set (jape (tufa p.det)))
$ins (joba %ins (jobe at+(jone p.det) cha+s+(tuft q.det) ~))
==
--
--
++ wush
|= {wid/@u tan/tang}
^- tape
=+ rolt=|=(a/wall `tape`?~(a ~ ?~(t.a i.a :(weld i.a "\0a" $(a t.a)))))
(rolt (turn (flop tan) |=(a/tank (rolt (wash 0^wid a)))))
::
--
!:
|_ sef/sole-effect
::
++ grab :: convert from
|%
++ noun sole-effect :: clam from %noun
--
++ grow
|%
++ json
^- ^json
?+ -.sef
~|(unsupported-effect+-.sef !!)
$mor [%a (turn p.sef |=(a/sole-effect json(sef a)))]
$err (joba %hop (jone p.sef))
$txt (joba %txt (jape p.sef))
$tan (joba %tan (jape (wush 160 p.sef)))
$det (joba %det json:~(grow mar-sole-change +.sef))
$pro
(joba %pro (jobe vis+b+vis.sef tag+s+tag.sef cad+(jape cad.sef) ~))
::
?($bel $clr $nex)
(joba %act %s -.sef)
==
--
--

16
mar/styl.hoon Normal file
View File

@ -0,0 +1,16 @@
::
:::: /hoon/core/styl/pro
::
/? 314
|_ mud/@t
++ grow
|%
++ mime [/text/styl (taco mud)]
--
++ grab
|%
++ mime |=({p/mite q/octs} q.q)
++ noun @t
--
++ grad %mime
--

119
mar/talk/command.hoon Normal file
View File

@ -0,0 +1,119 @@
::
:::: /hoon+talk-command+mar
::
/? 314
/- talk
!:
[talk .]
|_ cod/command
::
++ grab :: convert from
|%
++ noun command :: clam from %noun
++ json
=> [jo ..command]
|= a/json ^- command
=- (need ((of -) a))
=< :~ publish+(ar thot)
review+(ar thot)
design+(ot party+so config+(mu conf) ~)
==
|%
++ op :: parse keys of map
|* {fel/rule wit/fist}
%+ cu mo
%- ci :_ (om wit)
|= a/(map cord _(need *wit))
^- (unit (list _[(wonk *fel) (need *wit)]))
(zl (turn (~(tap by a)) (head-rush fel)))
::
++ ke :: callbacks
|* {gar/* sef/_|.(fist)}
|= jon/json
^- (unit _gar)
=- ~! gar ~! (need -) -
((sef) jon)
::
++ as :: array as set
:: |*(a=fist (cu sa (ar a))) :: XX types
|* a/fist
%- cu :_ (ar a)
~(gas in *(set _(need *a)))
::
++ lake |*(a/_* $+(json (unit a)))
++ peach
|* a/{rule rule}
|= tub/nail
^- (like (each _(wonk (-.a)) _(wonk (+.a))))
%. tub
;~(pose (stag %& -.a) (stag %| +.a))
::
++ head-rush
|* a/rule
|* {b/cord c/*}
=+ nit=(rush b a)
?~ nit ~
(some [u.nit c])
::
::
++ thot
^- $+(json (unit thought))
%- ot :~
serial+(ci (slat %uv) so)
audience+audi
statement+stam
==
::
++ audi (op parn memb) :: audience
++ auri (op parn (ci (soft presence) so))
++ memb (ot envelope+lope delivery+(ci (soft delivery) so) ~)
++ lope (ot visible+bo sender+(mu (su parn)) ~)
::
++ parn
^- $+(nail (like partner))
%+ peach
;~((glue fas) ;~(pfix sig fed:ag) urs:ab)
%+ sear (soft passport)
;~((glue fas) sym urs:ab) :: XX [a-z0-9_]{1,15}
::
++ speech-or-eval $?(speech {$eval p/@t} {$mor p/(list speech-or-eval)})
++ eval
|= a/(trel @da bouquet speech-or-eval)
^- statement
%= a r ^- speech
|-
?: ?=($mor -.r.a)
[%mor (turn p.r.a |=(b/speech-or-eval ^$(r.a b)))]
?. ?=($eval -.r.a) r.a
=- [%fat tank+- %exp p.r.a]
=+ pax=[&1:% &2:% (scot %da p.a) |3:%]
p:(mule |.([(sell (slap !>(..zuse) (rain pax p.r.a)))]~))
==
::
++ stam
^- $+(json (unit statement))
%+ cu eval
(ot date+di bouquet+(as (ar so)) speech+spec ~)
::
++ spec
%+ ke *speech-or-eval |.
%- of
:~ lin+(ot say+bo txt+so ~)
url+(su aurf:urlp)
eval+so
mor+(ar spec)
:: exp+(cu |=(a=cord [a ~]) so)
:: inv+(ot ship+(su fed:ag) party+(su urs:ab) ~)
==
::
++ conf
^- $+(json (unit config))
%- ot :~
sources+(as (su parn))
caption+so
:- %cordon
(ot posture+(ci (soft posture) so) list+(as (su fed:ag)) ~)
==
--
-- --

144
mar/talk/report.hoon Normal file
View File

@ -0,0 +1,144 @@
::
:::: /hoon/talk-report/mar
::
/? 314
/- talk
/+ talk
!:
[talk .]
|_ rep/report
::
++ grab :: convert from
|%
++ noun report :: clam from %noun
--
++ grow
|%
++ mime [/text/json (taco (crip (pojo json)))]
++ json
=> +
|^ %+ joba -.rep
?- -.rep
$cabal (cabl +.rep)
$house a+(turn (~(tap by +.rep)) jose)
$glyph ((jome |=(a/char a) nack) +.rep)
$grams (jobe num+(jone p.rep) tele+[%a (turn q.rep gram)] ~)
$group (jobe local+(grop p.rep) global+%.(q.rep (jome parn grop)) ~)
==
++ joce |=(a/span [%s a])
++ jose
|= {a/span b/posture c/cord}
(jobe name+[%s a] posture+[%s a] caption+[%s b] ~)
::
++ jove
|= {a/envelope b/delivery}
%- jobe :~
envelope+(jobe visible+[%b p.a] sender+?~(q.a ~ s+(parn u.q.a)) ~)
delivery+[%s b]
==
++ jope |=(a/ship (jape +:<a>)) ::[%s (crip +:(scow %p a))])
++ joke |=(a/tank [%s (role (turn (wash 0^80 a) crip))])
++ jode |=(a/time (jone (div (mul (sub a ~1970.1.1) 1.000) ~s1)))
:: ++ jase
:: |* a=,json
:: |= b=(set ,$+<.a) ^- json
:: ~! b
:: [%a (turn (~(tap in b)) a)]
::
++ jome :: stringify keys
|* {a/_cord b/_json}
|= c/(map _+<.a _+<.b)
(jobe (turn (~(tap by c)) (both a b)))
::
++ both :: cons two gates
|* {a/_* b/_*}
|=(c/_[+<.a +<.b] [(a -.c) (b +.c)])
::
::
++ nack |=(a/(set (set partner)) [%a (turn (~(tap in a)) sorc)])
++ grop (jome phon stas) :: (map ship status)
++ phon |=(a/ship (scot %p a))
++ stas |=(status (jobe presence+(joce p) human+(huma q) ~))
++ gram |=(telegram (jobe ship+(jope p) thought+(thot q) ~))
++ thot
|= thought
(jobe serial+(jape <p>) audience+(audi q) statement+(stam r) ~)
::
++ audi (jome parn jove)
++ bouq
|= a/bouquet
a+(turn (~(tap in a)) |=(b/path a+(turn b |=(c/span s+c))))
::
++ parn
|= a/partner ^- cord
?- -.a
$& (stat p.a)
$| %- crip
?- -.p.a
$twitter "{(trip -.p.a)}/{(trip p.p.a)}"
==
==
::
++ stat
|= a/station ^- cord
(crip "{<p.a>}/{(trip q.a)}")
::
++ stam
|= statement
(jobe date+(jode p) bouquet+(bouq q) speech+(spec r) ~)
::
++ spec
|= a/speech
%+ joba -.a
?+ -.a ~|(stub+-.a !!)
$lin (jobe txt+[%s q.a] say+[%b p.a] ~)
$url (joba txt+[%s (crip (earf p.a))])
$exp (joba txt+[%s p.a])
$tax (joba txt+(jape (rend-work-duty p.a)))
$app (jobe txt+[%s q.a] src+[%s p.a] ~)
$fat (jobe tor+(tors p.a) taf+$(a q.a) ~)
$mor a+(turn p.a spec)
:: %inv (jobe ship+(jope p.a) party+[%s q.a] ~)
==
::
++ tors
|= a/torso
%+ joba -.a
?- -.a
$text [%s (role +.a)]
$tank [%a (turn +.a joke)]
$name (jobe nom+s+p.a mon+$(a q.a) ~)
==
::
++ huma
|= human
%^ jobe
hand+?~(hand ~ [%s u.hand])
:- %true
?~ true ~
=+ u.true
(jobe first+[%s p] middle+?~(q ~ [%s u.q]) last+[%s r] ~)
~
::
++ cabl
|= cabal
%- jobe :~
loc+(conf loc)
ham+((jome stat conf) ham)
==
::
++ sorc
|= a/(set partner) ^- json
[%a (turn (~(tap in a)) |=(b/partner s+(parn b)))]
::
++ conf
|= config
%- jobe :~
sources+(sorc sources)
caption+[%s caption]
=- cordon+(jobe posture+[%s -.cordon] list+[%a -] ~)
(turn (~(tap in q.cordon)) jope) :: XX jase
==
--
-- --

320
mar/talk/telegrams.hoon Normal file
View File

@ -0,0 +1,320 @@
::
:::: /hoon/talk-telegrams/mar
::
/? 314
/- talk
/+ talk
!:
=+ talk
|_ gam/(list telegram)
::
++ grab-work-duty => [jo work-stuff]
|^ dute
++ as
:: |*(a/fist (cu sa (ar a))) :: XX types
|* a/fist
%- cu :_ (ar a)
~(gas in *(set _(need *a)))
++ ot
|* a/(pole {@tas fist})
|= b/json
%. ((^ot a) b)
%- slog
?+ b ~
{$o *}
%+ murn `(list {@tas fist})`a
|= {c/term d/fist} ^- (unit tank)
=+ (~(get by p.b) c)
?~ - (some >[c (turn (~(tap by p.b)) head)]<)
=+ (d u)
?~ - (some >[c u]<)
~
==
++ of
|* a/(pole {@tas fist})
|= b/json
%. ((of:jo a) b)
%- slog
?+ b ~
{$o *}
%+ murn `(list {@tas fist})`a
|= {c/term d/fist} ^- (unit tank)
=+ (~(get by p.b) c)
?~ - ~
=+ (d u)
?~ - (some >[c u]<)
~
==
++ id (ci (slat %uv) so)
++ ship (su fed:ag)
++ dute
%- of :~
create+task change+(ot id+id meat+uppd ~)
archive+id update+(ot id+id version+ni her+(su fed:ag) meat+uppd ~)
==
++ task
%- ot :~
id+id 'date_created'^di
version+ni 'date_modified'^di
creator+ship doer+(mu ship)
tags+(as so) 'date_due'^(mu di)
done+(mu di) title+so
description+so discussion+(ar (ot date+di ship+ship body+so ~))
==
++ audi (as stan)
++ stan (su ;~((glue fas) ;~(pfix sig fed:ag) urs:ab))
++ uppd
%- of :~
set-doer+(mu (su fed:ag))
set-date-due+(mu di)
set-tags+(as so)
set-title+so
set-description+so
set-done+bo
add-comment+(ot ship+(su fed:ag) com+so ~)
==
--
++ grow-work-duty
=> work-stuff
=+ jope=|=(a/ship [%s (rsh 3 1 (scot %p a))])
=+ jove=|=(a/@uvI [%s (scot %uv a)])
=< |= duty
%+ joba +<-
?- +<-
$create (task tax)
$archive (jove id)
$change (jobe id+(jove id) meat+(flesh meat) ~)
$update
%- jobe :~
id+(jove id)
version+(jone version)
her+(jope her)
meat+(flesh meat)
==
==
|%
++ tags
|= a/(set @t)
[%a (turn (sort (~(tap in a)) aor) |=(b/cord s+b))]
::
++ task
|= ^task
%- jobe :~ id+[%s (scot %uv id)]
tags+(^tags tags)
doer+?~(doer ~ (jope u.doer))
title+[%s title]
creator+(jope creator)
version+(jone version)
'date_created'^(jode date-created)
'date_modified'^(jode date-modified)
description+[%s description]
=< discussion+[%a (turn discussion .)]
|=(comment (jobe date+(jode date) ship+(jope ship) body+[%s body] ~))
'date_due'^?~(date-due ~ (jode u.date-due))
done+?~(done ~ (jode u.done))
==
++ flesh
|= ^flesh
%+ joba +<-
?- +<-
$set-doer ?~(her ~ (jope u.her))
$set-date-due ?~(wen ~ (jode u.wen))
$set-tags (tags tag)
$set-title [%s til]
$set-description [%s des]
$set-done [%b don]
$add-comment (jobe ship+(jope who) com+[%s com] ~)
==
--
++ grab
|%
++ noun (list telegram)
++ mime |=(^mime (json (rash q.q apex:poja)))
++ json
=> [jo ..telegram dute=grab-work-duty]
|= a/json ^- (list telegram)
=- (need ((ar (ot ship+(su fed:ag) thought+thot ~)) a))
|%
++ of
|* a/(pole {@tas fist})
|= b/json
%. ((of:jo a) b)
%- slog
?+ b ~
{$o *}
%+ murn `(list {@tas fist})`a
|= {c/term d/fist} ^- (unit tank)
=+ (~(get by p.b) c)
?~ - ~
=+ (d u)
?~ - (some >[c u]<)
~
==
++ op :: parse keys of map
|* {fel/rule wit/fist}
%+ cu mo
%- ci :_ (om wit)
|= a/(map cord _(need *wit))
^- (unit (list _[(wonk *fel) (need *wit)]))
(zl (turn (~(tap by a)) (head-rush fel)))
::
++ as :: array as set
:: |*(a/fist (cu sa (ar a))) :: XX types
|* a/fist
%- cu :_ (ar a)
~(gas in *(set _(need *a)))
::
++ ke :: callbacks
|* {gar/* sef/_|.(fist)}
|= jon/json
^- (unit _gar)
=- ~! gar ~! (need -) -
((sef) jon)
::
++ lake |*(a/_* $+(json (unit a)))
++ head-rush
|* a/rule
|* {b/cord c/*}
=+ nit=(rush b a)
?~ nit ~
(some [u.nit c])
::
::
++ thot
^- $+(json (unit thought))
%- ot :~
serial+(ci (slat %uv) so)
audience+audi
statement+stam
==
::
++ audi (op parn memb) :: audience
++ auri (op parn (ci (soft presence) so))
++ memb (ot envelope+lope delivery+(ci (soft delivery) so) ~)
++ lope (ot visible+bo sender+(mu (su parn)) ~)
::
++ parn
^- $+(nail (like partner))
%+ pick
;~((glue fas) ;~(pfix sig fed:ag) urs:ab)
%+ sear (soft passport)
;~((glue fas) sym urs:ab) :: XX [a-z0-9_]{1,15}
::
++ stam (ot date+di bouquet+(as (ar so)) speech+spec ~)
++ spec
%+ ke *speech |. ~+
%- of :~
lin+(ot say+bo txt+so ~)
url+(ot txt+(su aurf:urlp) ~)
exp+(ot txt+so ~)
tax+(ot xat+dute ~)
app+(ot txt+so src+so ~)
fat+(ot tor+tors taf+spec ~)
ext+(ot nom+so txe+blob ~)
non+ul
:: inv+(ot ship+(su fed:ag) party+(su urs:ab) ~)
==
++ tors
%+ ke *torso |. ~+
%- of :~
name+(ot nom+so mon+tors ~)
text+(cu lore so)
tank+(ot dat+(cu (hard (list tank)) blob) ~)
==
::
++ blob (cu cue (su fel:ofis))
--
--
::
++ grow
|%
++ mime [/text/json (taco (crip (pojo json)))]
++ json
=> +
|^
:- %a
%+ turn gam
|= telegram
(jobe ship+(jope p) thought+(thot q) ~)
::
++ jove
|= {a/envelope b/delivery}
%- jobe :~
envelope+(jobe visible+[%b p.a] sender+?~(q.a ~ s+(parn u.q.a)) ~)
delivery+[%s b]
==
::
++ jope |=(a/ship (jape +:<a>)) ::[%s (crip +:(scow %p a))])
++ joke |=(a/tank [%s (role (turn (wash 0^80 a) crip))])
++ jode |=(a/time (jone (div (mul (sub a ~1970.1.1) 1.000) ~s1)))
++ jome :: stringify keys
|* {a/_cord b/_json}
|= c/(map _+<.a _+<.b)
(jobe (turn (~(tap by c)) (both a b)))
::
++ both :: cons two gates
|* {a/_* b/_*}
|=(c/_[+<.a +<.b] [(a -.c) (b +.c)])
::
++ thot
|= thought
(jobe serial+(jape <p>) audience+(audi q) statement+(stam r) ~)
::
++ audi (jome parn jove)
++ bouq
|= a/bouquet
a+(turn (~(tap in a)) |=(b/path a+(turn b |=(c/span s+c))))
::
++ parn
|= a/partner ^- cord
?- -.a
$& (stat p.a)
$| %- crip
?- -.p.a
$twitter "{(trip -.p.a)}/{(trip p.p.a)}"
==
==
::
++ stat
|= a/station ^- cord
(crip "{<p.a>}/{(trip q.a)}")
::
++ stam
|= statement
(jobe date+(jode p) bouquet+(bouq q) speech+(spec r) ~)
::
++ spec
|= a/speech
%+ joba -.a
?+ -.a ~|(stub+-.a !!)
$lin (jobe txt+[%s q.a] say+[%b p.a] ~)
$url (joba txt+(jape (earf p.a)))
$exp (joba txt+[%s p.a])
$tax (jobe txt+(jape (rend-work-duty p.a)) xat+(grow-work-duty p.a) ~)
$app (jobe txt+[%s q.a] src+[%s p.a] ~)
$fat (jobe tor+(tors p.a) taf+$(a q.a) ~)
$ext (jobe nom+[%s p.a] txe+(jape (sifo (jam +.a))) ~)
$non ~
:: $inv (jobe ship+(jope p.a) party+[%s q.a] ~)
==
::
++ tors
|= a/torso
%+ joba -.a
?- -.a
$text [%s (role +.a)]
$tank (jobe txt+[%a (turn +.a joke)] dat+(jape (sifo (jam +.a))) ~)
$name (jobe nom+s+p.a mon+$(a q.a) ~)
==
::
--
--
::
++ grad
|%
++ form %talk-telegrams
++ diff |=((list telegram) +<)
++ pact |=((list telegram) +<)
++ join |=({(list telegram) (list telegram)} `(unit mime)`~)
--
--

20
mar/tang.hoon Normal file
View File

@ -0,0 +1,20 @@
::
:::: /hoon+core+tang+mar
::
/? 314
!:
|_ tan/(list tank)
::
++ grow
|%
++ elem
=- ;pre:code:"{(trip (role (turn - crip)))}" :: XX
^- wall %- zing ^- (list wall)
(turn (flop tan) |=(a/tank (wash 0^160 a)))
--
++ grab :: convert from
|%
++ noun (list ^tank) :: clam from %noun
++ tank |=(a/^tank [a]~)
--
--

4
mar/tree-include.hoon Normal file
View File

@ -0,0 +1,4 @@
/- tree-include
|_ tree-include
++ grab |% ++ noun tree-include
-- --

11
mar/unlog.hoon Normal file
View File

@ -0,0 +1,11 @@
::
:::: /hoon+core+unlog+mar
::
!:
|_ man/span
++ grab
|% :: convert from
++ noun span :: clam from %noun
--
--

20
mar/urb.hoon Normal file
View File

@ -0,0 +1,20 @@
::
:::: /hoon/urb/mar
::
/? 314
:: /= dep /$ |=([^ but=path] `@uvH`?>(?=([%dep @ ~] but) (slav %uv i.t.but)))
!:
|_ own/manx
::
++ grow :: convert to
|%
++ html (crip (poxo own)) :: convert to %html
++ mime [/text/html (taco html)] :: convert to %mime
--
++ grab
|% :: convert from
++ noun manx :: clam from %noun
++ hymn :: inject into %hymn
|= old/manx old :: moved to %eyre
--
--

12
mar/urbit.hoon Normal file
View File

@ -0,0 +1,12 @@
::
:::: /hoon+urbit+mar
::
/? 314
:::: A minimal urbit mark
!:
|_ her/@p
++ grab
|%
++ noun @p
--
--

18
mar/user.hoon Normal file
View File

@ -0,0 +1,18 @@
::
:::: /hoon/core/user/mar
::
/? 314
/- user
|_ use/user
::
++ grab :: convert from
|%
++ noun user :: clam from %noun
--
++ grow
|%
++ json
%- jobe
~[[%dir [%s -.use]] [%ship (jape <p.p.use>)] [%name [%s q.p.use]]]
--
--

27
mar/users.hoon Normal file
View File

@ -0,0 +1,27 @@
::
:::: /hoon/core/users/pro
::
/? 314
/- users
!:
|_ use/users
::
++ grab :: convert from
|%
++ noun users :: convert from %noun
--
++ grow
|%
++ json
%+ joba
%users
:- %a
%+ turn
use
|= {p/@p q/@t}
%- jobe
~[[%ship (jape <p>)] [%name [%s q]]]
++ mime
[/text/json (tact (pojo json))]
--
--

11
mar/will.hoon Normal file
View File

@ -0,0 +1,11 @@
::
:::: /hoon+will+mar
::
/? 314
|_ wyl/(unit will)
::
++ grab :: convert from
|%
++ noun (unit will) :: clam from %noun
--
--

1
mar/wipe.hoon Normal file
View File

@ -0,0 +1 @@
|=($~ ~)

20
mar/woff.hoon Normal file
View File

@ -0,0 +1,20 @@
::
:::: /hoon/core/otf/pro
::
/? 314
::
:::: compute
::
|_ wof/mime
::
++ grow :: convert to
|%
++ mime wof :: convert to %mime
--
++ grab
|%
++ mime |=({mite p/octs} [/application/font-woff p])
++ noun ^mime
--
++ grad %mime
--

104
mar/work/command.hoon Normal file
View File

@ -0,0 +1,104 @@
::
:::: /hoon+command+work+mar
::
/- work
!:
::::
::
[work .]
|_ mad/command
++ grab
|% ++ noun command
++ json
=> [jo ..command]
=< (corl need (cu |=(a/command a) coma))
|%
++ as
:: |*(a/fist (cu sa (ar a))) :: XX types
|* a/fist
%- cu :_ (ar a)
~(gas in *(set _(need *a)))
++ ot
|* a/(pole {@tas fist})
|= b/json
%. ((^ot a) b)
%- slog
?+ b ~
{$o *}
%+ murn `(list {@tas fist})`a
|= {c/term d/fist} ^- (unit tank)
=+ (~(get by p.b) c)
?~ - (some >[c (turn (~(tap by p.b)) head)]<)
=+ (d u)
?~ - (some >[c u]<)
~
==
++ of
|* a/(pole {@tas fist})
|= b/json
%. ((of:jo a) b)
%- slog
?+ b ~
{$o *}
%+ murn `(list {@tas fist})`a
|= {c/term d/fist} ^- (unit tank)
=+ (~(get by p.b) c)
?~ - ~
=+ (d u)
?~ - (some >[c u]<)
~
==
++ id (ci (slat %uv) so)
++ ship (su fed:ag)
++ coma
%- of :~
new+task old+(ot id+id dif+uppd ~)
sort+(ar id)
==
++ task
%- ot :~
::index+ni
audience+audi
id+id 'date_created'^di
version+ni 'date_modified'^di
creator+ship doer+(mu ship)
tags+(as so) 'date_due'^(mu di)
done+(mu di) title+so
description+so discussion+(ar (ot date+di ship+ship body+so ~))
==
++ audi (as stan)
++ stan (su ;~((glue fas) ;~(pfix sig fed:ag) urs:ab))
++ uppd
%- of :~
doer+(of release+ul claim+ul ~)
add+(of comment+so ~)
:- %set
%- of :~
audience+audi
date-due+(mu di)
title+so
description+so
tags+(as so)
done+bo
==
==
--
--
++ grow
|%
++ elem ;pre: {(zing `wall`(turn (wash 0^120 >mad<) |=(a/tape ['\0a' a])))}
--
--
:: {new: {
:: id:'0vaof.6df9u.2agc3.d0dp1',
:: date-created:1440011611215,
:: version:1,
:: date-modified:1440011611215,
:: creator:'fyr',
:: tags:['tag'],
:: date-due:null,
:: done:false,
:: title:'Test task',
:: description:'The converter owrks right?',
:: discussion:[{date:1440011611215,ship:'sondel',body:'hi'}]
:: } }

55
mar/work/report.hoon Normal file
View File

@ -0,0 +1,55 @@
::
:::: /hoon+report+work+mar
::
/- work
!:
::::
::
[work .]
|_ client
++ grow
|% ++ json
=+ jope=|=(a/ship [%s (rsh 3 1 (scot %p a))])
%- jobe :~
sort+[%a (turn sort |=(a/@uv [%s (scot %uv a)]))]
=< tasks+(jobe (turn (~(tap by tasks)) .))
|= {@ client-task}
=+ tax
:- (scot %uv id)
%- jobe :~ id+[%s (scot %uv id)]
tags+[%a (turn (^sort (~(tap in tags)) aor) |=(a/cord s+a))]
doer+?~(doer ~ (jope u.doer))
title+[%s title]
creator+(jope creator)
version+(jone version)
archived+[%b archived]
=< audience+[%a (turn (~(tap in audience)) .)]
|=(a/station:talk [%s (crip "{<p.a>}/{(trip q.a)}")])
'date_created'^(jode date-created)
'date_modified'^(jode date-modified)
description+[%s description]
=< discussion+[%a (turn discussion .)]
|=(comment (jobe date+(jode date) ship+(jope ship) body+[%s body] ~))
'date_due'^?~(date-due ~ (jode u.date-due))
done+?~(done ~ (jode u.done))
==
==
-- --
:: sort: ["0v111id" ...]
:: tasks: [ {
:: id:"0v111id"
:: tags:["str" ...]
:: doer:|("~ship" null)
:: title:"str"
:: creator:"~ship"
:: version:12345
:: archived:false
:: audience:["~ship+chan" ...]
:: date_created:1262304000000
:: date_modified:1262304000000
:: description:"str"
:: discussion:[{date:1262304000000 ship:"~ship" body:"str"} ...]
:: date_due:?(1262304000000 null)
:: done:?(1262304000000 null)
:: }
:: ...]

106
mar/work/task.hoon Normal file
View File

@ -0,0 +1,106 @@
::
:::: /hoon/task/work/mar
::
/- work
!:
::::
::
[work .]
|%
++ rend
|= a/(list $@(char dime)) ^- cord
%- crip
|- ^- tape
?~ a ~
?@ i.a [i.a $(a t.a)]
(weld (scow i.a) $(a t.a))
::
++ indent |=(a/wain (turn a |=(b/cord (cat 3 ' ' b))))
::
++ undent
|* {a/wain b/$+(wain *)} ^+ [*b a]
=^ c a
|- ^- {c/wain a/wain}
?~ a [~ a]
?. =(' ' (end 3 2 i.a))
[~ a]
[[- c] a]:[(rsh 3 2 i.a) $(a t.a)]
[(b `wain`c) a]
::
++ keen |*({a/* b/rule} |=(c/nail `(like a)`(b c)))
++ parse
|* {hed/$?($~ $@(@tas tape)) tal/(pole)}
?~ hed (..$ tal)
?^ hed ;~(pfix (just (crip hed)) (..$ tal))
=- ?~(tal had ;~(plug had (..$ tal)))
=< had=(sear . nuck:so)
|= a/coin ^- (unit (odo:raid hed))
?. &(?=({$$ @ @} a) =(hed p.p.a)) ~
(some q.p.a)
::
++ advance
|* {a/wain b/rule} ^+ [(wonk *b) a]
?~(a !! ~|(i.a [(rash i.a b) t.a]))
--
!:
::::
::
|_ taz/task
++ grab
|% ++ txt
|= a/wain ^+ taz
=+ ~[id=%uv "_" date-created=%da " " version=%ud date-modified=%da]
=^ b a (advance a ;~(plug (parse -) (punt (parse " " %da ~))))
=+ [-.b `date-due/(unit @da)`+.b]
=^ tags a (undent a ~(gas in *(set cord)))
=^ title a ?~(a !! a)
=^ b a %+ advance a
;~(plug (parse %p ~) (punt (parse ">" %p ~)) (punt (parse "X" %da ~)))
=+ `{creator/@p doer/(unit @p) done/(unit @da)}`b
=^ description a (undent a role)
:* id date-created version date-modified creator
doer tags date-due done title description :: XX done
|- ^- (list comment)
?: =(~ a) ~
=^ b a (advance a (parse ship=%p " " date=%da ~))
=+ b
=^ body a (undent a role)
[[date ship body] $]
==
--
++ grow
|%
++ elem ;pre: {(zing `wall`(turn (wash 0^120 >taz<) |=(a/tape ['\0a' a])))}
++ mime [/text/x-task (taco (role txt))]
++ txt
=+ taz
=+ due=?~(date-due ~ ~[' ' da+u.date-due])
:- (rend uv+id '_' da+date-created ' ' ud+version da+date-modified due)
%+ welp (indent (sort (~(tap in tags)) aor))
:- title
=+ do=[=-(?~(doer - ['>' p+u.doer -]) ?~(done ~ ~['X' da+u.done]))]
:- (rend p+creator do)
%- zing ^- (list wain)
:- (indent (lore description))
%+ turn discussion
|= comment ^- wain
[(rend p+ship ' ' da+date ~) (indent (lore body))]
--
++ grad %txt
--
:: {id}_{date-created} {version}{date-modified}{|(" {date-due}" ~)}
:: {tag1}
:: {tag2}
:: ...
:: {title}
:: {creator}{|(">{doer}" ~)}{|("X{done}" ~)}
:: {description}
:: {more description}
:: {ship1} {date}
:: {comment}
:: {more comment}
:: {more comment}
:: {ship2} {date}
:: {comment}
:: {more comment}
:: {more comment}

12
mar/write-paste.hoon Normal file
View File

@ -0,0 +1,12 @@
::
:::: /hoon+core+save+mar
::
!:
|_ {typ/?($hoon $md $txt) txt/@t}
++ grab
|%
++ noun {?($hoon $md $txt) @t}
++ json
(corl need =>(jo (ot typ+(ci (soft ?($hoon $md $txt)) so) txt+so ~)))
--
--

18
mar/xml.hoon Normal file
View File

@ -0,0 +1,18 @@
::
:::: /hoon/core/html/mar
::
/? 314
::
:::: compute
::
|_ htm/@t
::
++ grow :: convert to
|% ::
++ mime [/application/xml (taco htm)] :: to %mime
++ hymn (need (poxa htm)) :: to %hymn
-- ::
++ grab |% :: convert from
++ noun @t :: clam from %noun
++ mime |=({p/mite q/octs} q.q) :: retrieve form $mime
-- --

36
pub/bit/fab/hymn.hook Normal file
View File

@ -0,0 +1,36 @@
::
::::
::
/? 314
/= gas /$ fuel
::
:::: ~sivtyv-barnel
::
!:
^- manx
=+ authcode=(fall (~(get by qix.gas) %'code') '')
;html
;head
;title: Coinbase Auth
;script@"/~/at/home/lib/urb.js";
==
;body
;*
?~ authcode
:_ ~
;div: Something went wrong. Please try to auth again.
;=
;script: authcode = {(pojo %s authcode)}
;script:'''
if (authcode)
urb.send({
appl: "bit",
data: authcode,
mark: "oauth2-code"
}, function(){
})
'''
;div: 'Success. Your auth-token has been sent to your app. You can close this now.'
==
==
==

30
pub/cloud/fab/hymn.hook Normal file
View File

@ -0,0 +1,30 @@
::
::::
:::
/? 310
/= gas /$ fuel
::
::::
::
!:
^- manx
=+ do=(~(get by qix.gas) %'code')
;html
;head
;script@"/~/at/home/lib/urb.js";
;script: urb.appl = 'cloud'
;script@"https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js";
;script@"https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/react.js";
::;link/"/main/pub/cloud/src/main.css"(rel "stylesheet");
;title: DO & GCE Manager
==
;body
;script:"""
var authcode = \{}
authcode.do='{?~(do ~ (trip u.do))}'
"""
;div#container;
;script@"/home/pub/cloud/src/main.js";
==
==

0
pub/cloud/src/main.css Normal file
View File

207
pub/cloud/src/main.js Normal file
View File

@ -0,0 +1,207 @@
recl = React.createClass
div = React.DOM.div
a = React.DOM.a
b = React.DOM.button
hr = React.DOM.hr
table = React.DOM.table
th = React.DOM.th
tr = React.DOM.tr
td = React.DOM.td
input = React.DOM.input
function HashToJSON() {
var pairs = window.location.hash.slice(1).split('&');
var result = {};
pairs.forEach(function(pair) {
pair = pair.split('=');
result[pair[0]] = decodeURIComponent(pair[1] || '');
});
return JSON.parse(JSON.stringify(result));
}
DOControls = React.createClass({
createDroplet: function(){
urb.send({appl: "cloud",
mark: "json",
data: {'create-do':{
name:$('#name').val(),
region:$('#region').val(),
size:$('#size').val(),
image:$('#image').val(),
ssh:[], // $('#ssh').val()]
backups:null,//$('#backups').val(),
ipv6:null,//$('#ipv6').val(),
priv_networking:null,//$('#priv-networking').val(),
user_data:null//$('#user-data').val()
}}})
},
render: function(){
href = "https://cloud.digitalocean.com/v1/oauth/authorize?client_id=d8f46b95af38c1ab3d78ad34c2157a6959c23eb0eb5d8e393f650f08e6a75c6f&redirect_uri=http%3A%2F%2Flocalhost%3A8443%2Fhome%2Fpub%2Fcloud%2Ffab&response_type=code&scope=read+write"
return (
div({}, [
div({},
a({href:href},"get authcode"),
b({onClick:this.props.handleClick('do')}, "Send Authcode")
),
div({}, [
input({id:"appsecret"},
b({onClick:this.props.sendSecret('do','#appsecret')}, "Send Secret"))
]),
div({}, [
b({onClick:this.createDroplet}, "Create Droplet"),
input({id:"name",placeholder:"Name of droplet"}),
input({id:"region",placeholder:"Region"}),
input({id:"size",placeholder:"Size (str ending in mb"}),
input({id:"image",placeholder:"Image"}),
input({id:"ssh",placeholder:"ssh keys (optional)"}),
input({id:"backups",placeholder:"backups (optional)"}),
input({id:"ipv6",placeholder:"ipv6 (boolean, optional)"}),
input({id:"user-data",placeholder:" user-data string (optional)"}),
input({id:"priv-networking",placeholder:"Private Networking (boolean, optional)"})
])
])
)
}
})
GCEControls = React.createClass({
createDroplet: function(){
urb.send({
appl: 'cloud',
mark: 'json',
data: {'create-gce':{
// project:$('#project').val(),
// zone:$('#zone').val(),
// name:$('#gname').val(),
// machine_type:$('#machine_type').val() /
}}})
},
createDisk: function(){
urb.send({
appl: 'cloud',
mark: 'json',
data: {'create-gce':{
snap:$('#gsnap').val(),
number:parseInt($('#number').val()),
name:$('#gcpName').val(),
instance_img:$('#instance_image').val()
}}})
},
render: function(){
ghref = "https://accounts.google.com/o/oauth2/auth?response_type=token&scope=https://www.googleapis.com/auth/compute&redirect_uri=http://localhost:8443/home/pub/cloud/fab&client_id=719712694742-6htfj2t9s1j2jid92rc4dfq9psrr9qpo.apps.googleusercontent.com"
return(
div({}, [
div({}, [
b({onClick:this.createDisk}, 'Create Disk From Image'),
input({id:'gcpName',placeholder:'Name for GCE Disk and Instance'}),
input({id:'number',placeholder:'Number of instances'}),
input({id:'gsnap',placeholder:'Snapshot'}),
input({id:'instance_image',placeholder:'Instance Image'})
]),
div({}, [
a({href:ghref},"Get Google Authcode"),
b({onClick:this.props.handleClick('gce')}, "Send Google Authcode")
]),
div({}, [
input({id:"gappsecret"},
b({onClick:this.props.sendSecret('gce','#gappsecret')}, "Send Google Secret"))
])
])
)
}
})
Droplet = React.createClass({
dropletAction: function(act){
return function(){
var action = {act:{}, id:this.props.id, name:this.props.name}
switch(act){
case "snapshot":
action.act[act] = this.refs.snapname.getDOMNode().value
break; default:
action.act[act] = null
}
urb.send({appl: "cloud", data: {action:action}})}
},
render: function() {
var $this = this //local var, else it always points at second
var acts = ["start","stop","reboot","delete"] //,"snapshot"]
var buttons = [];
var buttons = acts.map(function(act){ return b({onClick:$this.dropletAction(act).bind($this)}, act)})
kay = Object.keys(this.props)
kay = kay.filter(function(b){return b!="children"}) // XX individually adress props
return div({},[
buttons,
//input({ref:'snapname',placeholder:'Name of Snapshot'}),
table({},
tr({},kay.map(function(k){return th({},k)})),
tr({},kay.map(function(k){return td({},JSON.stringify($this.props[k]))}))),
hr()])
}
})
Page = recl({
handleClick: function(platform){
return function(){
console.log(platform);
console.log(window.authcode.platform)
if(window.authcode.length !== ''){
urb.send({
appl: "cloud",
data: {authcode:authcode[platform],
platform:platform},
mark: "cloud-auth"})
} else { console.log("nocode") }
}
},
sendSecret: function(platform,codeid){
return function(){
console.log(platform,codeid)
secret= $(codeid).val()
if(secret !== '') {
urb.send({appl: "cloud",
data: {secret:secret,
platform:platform},
mark: "cloud-secret"})
}
}
},
getList: function(){
urb.send({appl: "cloud",
data: {action:"list"},
mark: "json"})
},
render: function(){
var drops = [], imgs = []
if(this.props.instances) drops = this.props.instances.map(Droplet)
if(this.props.images) imgs = this.props.images.map(
function(i){return div({},i.name)}
)
return (div({},
DOControls({handleClick:this.handleClick,sendSecret:this.sendSecret}),
GCEControls({handleClick:this.handleClick,sendSecret:this.sendSecret}),
drops,
imgs
))
}
})
var hash = HashToJSON() //pull out hash of query string for gce authcode
authcode.gce = hash.access_token
mounted = React.render(Page({droplets:[]}), $("#container")[0])
urb.bind("/", function(err,d) {
mounted.setProps(d.data)
return})

40
pub/coin/fab/hymn.hook Normal file
View File

@ -0,0 +1,40 @@
::
::::
::
/? 314
/= gas /$ fuel
::
:::: ~sivtyv-barnel
::
!:
^- manx
=+ :- authcode=<(fall (~(get by qix.gas) %'code') '')>
auth-url="https://www.coinbase.com/oauth/authorize?". :: "concat" . "enate"
"response_type=code".
"&client_id=2e688dde3f7655e7c261313a286e69e7c61ec5502459408b7818c4c74c77bf45".
"&redirect_uri=http://localhost:8444/gen/main/pub/fab/coin".
"&scope=user+balance+buy+sell+send+transactions".
"&meta[send_limit_amount]=1&meta[send_limit_curency]=BTC&meta[send_limit_period]=day"
;html
;head
;title: Coinbase Auth
;script@"/gop/hart.js";
;script@"/gen/main/lib/urb.js";
;script@"https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js";
==
;body
;a/"{auth-url}": Authenticate
;script: authcode = {authcode}
;div#changes;
;script:'''
if (authcode)
urb.send({
appl: "coin",
data: authcode,
mark: "oauth2-code"
})
'''
==
==

24
pub/docs.md Normal file
View File

@ -0,0 +1,24 @@
---
anchor: none
layout: no-anchor
logo: black
---
<div class="short">
# Urbit documentation
The Urbit doc is divided into three parts: [user doc](docs/user),
[developer doc](docs/dev), and [theory](docs/theory) (whitepaper, essays,
videos, etc).
If you want to try Urbit, start with the user doc. If you want
to learn about Urbit, try the theory. Or just start with the
user doc; it doesn't assume any prior knowledge.
The most fun thing to do with Urbit is code, but the developer
doc remains under construction. Sorry. We'll have more soon.
<list dataSort="true"></list>
</div>

28
pub/docs/dev.md Normal file
View File

@ -0,0 +1,28 @@
---
logo: black
sort: 2
title: Developer doc
---
<div class="short">
# Developer documentation
Urbit has three programming layers: [Nock](dev/nock) (combinator nano-VM),
[Hoon](dev/hoon) (strict functional language), and [Arvo](dev/arvo) (functional
OS).
To code in Urbit, the least you need to learn is Hoon, plus a
little bit of Arvo. Nock is a sort of functional assembly
language -- you don't need to know it, but it's useful to.
Nock is also the easiest thing in the world to learn.
You can program for Arvo without knowing much about Arvo
internals, but again it helps. But you need to know Hoon.
Don't worry, it's easier than it looks.
Alas, the developer doc is still under construction. We'll have
more soon.
<list></list>
</div>

13
pub/docs/dev/arvo.md Normal file
View File

@ -0,0 +1,13 @@
---
logo: black
sort: 3
title: Arvo
---
<div class="short">
# Arvo
Arvo is a functional operating system. But hopefully you knew that! Sorry,
please watch this space for actual documentation.
</div>

11
pub/docs/dev/client.md Normal file
View File

@ -0,0 +1,11 @@
---
hide: true
logo: black
sort: 4
title: Frontend tools
---
Frontend tools
==============
<list></list>

View File

@ -0,0 +1,59 @@
# `:tree`
`:tree` is the web filesystem interface. Odds are this file has been rendered for you by `:tree`.
`:tree` is a single-page app that uses a backend in `/home/tree` to load
contents from `%clay` as the user navigates around as `%json`. The frontend
lives in `/home/pub/tree` and is a fairly straightforward
[React](https://facebook.github.io/react/) /
[Flux](https://facebook.github.io/flux/) app.
## Frontend
The frontend code for `:tree` can be found in `/home/pub/tree/src/`.
### CSS
The CSS is written in [Stylus](https://learnboost.github.io/stylus/). The main entry point is `main.styl` and can be compiled with `stylus main.styl` which should output a `main.css`
### JS
The JS is written in [CoffeeScript](http://coffeescript.org/) and packaged with
[Browserify](http://browserify.org/). The main entry point is `main.coffee` and
is compiled with `browserify -t coffeeify main.coffee > main.js`. You'll need
to `npm install` first.
Each page is loaded as JSON and then rendered using React on the page. This
allows us to write JSX in our markdown to implement simple components. Check
out `/home/pub/tree/src/js/components` to see the component library.
You'll notice that some of these doc pages use things like `<list>` in the raw markdown files.
## JSON API
Async provides loading by schema
`{path name sein sibs next prev}` are all immediately accesible from the store
a `getPath` method, if present (defaulting to current url), is used to determine the query root node.
## JSON Internals
### `/[desk]/tree/{path}.json`
`tree/json.hook` accepts a query string schema `q` in light noun encoding
++ schema (dict ,[term $|(mark schema)])
++ dict |*(a=_,* $&([a (dict a)] a))
which is normalized and type-checked to a `query` list of
- `[%kids query]`, the only recursive value, which executes for all subpaths
XX descent is only currently supported to a single level as a performance optimization
- `[%name %t]`, the node name
- `[%path %t]`, the current path
- `[%snip %r]`, a snippet, extracted via `react-snip-json`
- `[%head %r]`, the first `<h1/>`, extracted via `react-head-json`
- `[%body %r]`, the `react-json` body
- `[%meta %j]`, json frontmatter per the `mdy` mark definition
The request types above are `%t` text, `%r` html-derived tree, and `%j`
arbitrary json; an example query, used by the main content renderer, is
`"q=body.r__kids_name.t"` (`body:'r' kids:{name:'t'}` )

View File

@ -0,0 +1,213 @@
---
sort: 6
title: Contributing
---
# Contributing to urbit
Thank you for your interest in contributing to urbit.
## Development practice
You may have an identity on the live network, but doing all your
development on the live network would be cumbersome and unnecessary.
Standard practice in urbit development is to work on a fake `~zod`. A
fake `~zod` will get its initial files from the `urb/zod/` directory
rather than trying to sync them over the network, which is invaluable
for working in Hoon. Also, a fake `~zod` or any fake urbit instances you
start do not talk to the live network, but to a fake network that exists
only on your computer.
To start a fake `~zod`, the command is:
bin/urbit -F -I zod -c [pier directory]
To resume one that was already created, just as on the live network,
remove `-c` (but leave the rest of the options there). `-F` uses the
fake network, and `-I` starts an "imperial" instance - that is, an 8-bit
galaxy.
## Kernel development
Working on either C or non-kernel Hoon should not bring any surprises,
but the Hoon kernel (anything under `urb/zod/arvo/`) is bootstrapped
from `urbit.pill` in `urb/`, and must be manually recompiled if any
changes are made. The command to manually recompile the kernel and
install the new kernel is `|reset` in `dojo`. This rebuilds from the
`arvo` directory in the `home` desk in `%clay`. Currently, `|reset`
does not reload apps like `dojo` itself, which will still reference the
old kernel. To force them to reload, make a trivial edit to their main
source file (under the `ape` directory) in `%clay`.
If you do any kernel development, be sure to read the section below about
pills.
## Git practice
Since we use the GitHub issue tracker, it is helpful to contribute via a
GitHub pull request. If you already know what you are doing, skip down
to the Style section.
Start by cloning the repository on your work machine:
git clone https://github.com/urbit/urbit
And, additionally, fork the repository on GitHub by clicking the "Fork"
button. Add your fork as a remote:
git remote add [username] https://github.com/[username]/urbit
and set it as the default remote to push to:
git config --local remote.pushDefault [username]
This is good practice for any project that uses git. You will pull
upstream branches from urbit/urbit and push to your personal urbit fork
by default.
Next, check out `test`, which is the mainline development branch, and
base a new branch on it to do your work on:
git checkout test
git checkout -b [branch name]
Now you are free to do your work on this branch. When finished, you may
want to clean up your commits:
git rebase -i test
Then you can push to your public fork with `git push` and make a pull
request via the GitHub UI. Make sure you request to merge your branch
into `test`, not `master`.
After your changes are merged upstream, you can delete your branch (via
github UI or `git push :[branch]` remotely, and with `git branch -d`
locally).
## Style
The urbit project uses two-space indentation and avoids tab characters.
In C code, it should not be too difficult to mimic the style of the code
around you, which is just fairly standard K&R with braces on every
compound statement. One thing to watch out for is top-level sections in
source files that are denoted by comments and are actually indented one
level.
Hoon will be a less familiar language to many contributors. Some of our
less obvious stylistic rules are:
- Keep your source files 80 characters or less wide. Many urbit
developers use 80 character terminals/tmux panes/&c.
- Tab characters are actually a syntax error, so be extra sure your
editor is not inserting any. Trailing whitespace is *usually* not a
syntax error, but avoiding it is encouraged.
- The kernel convention is that line comments start at column 57 with
the `::` followed by 2 spaces. This leaves 20 characters for the
comment. Outside the kernel, things are less strict.
- Tall arms within a core are conventionally separated by empty comments
(just `::`) at the same indentation level as the initial `++` or `+-`.
The last arm in a core is not followed by an empty comment, because it
is visually closed by the `--` that closes the core. The empty comment
is also sometimes omitted in data structure definitions.
## The kernel and pills
urbit bootstraps itself using a binary blob called `urbit.pill`, which
we do indeed keep in version control. This creates some special
requirements. If you are not changing anything in the kernel (everything
under `urb/zod/arvo/`) then you can skim this section (please do not
skip it entirely, though). If you *are* working there, then this
section is critically important!
The procedure for creating `urbit.pill` is often called "soliding". It
is somewhat similar to `|reset`, but instead of replacing your running
kernel, it writes the compiled kernel to a file. The command to solid
is, on a fakezod:
.urbit/pill +solid
When the compilation finishes, your `urbit.pill` will be found in the
`[pier]/.urb/put/` directory. Copy it into `urb/` and add it to your
commit.
The requirement here is that every commit that changes the kernel must
come with an `urbit.pill` built from the same code in `urb/zod/arvo/`
for that commit. (Only changing the actual Hoon code counts, so a change
to a jet with no corresponding Hoon change does not require a new pill.)
This is so that checking out an arbitrary revision and starting up a
fakezod actually works as expected. However you do this is fine, but I
like to do it as part of my committing process - just before `git
commit`, I fire up a new fakezod. This will use the previous
`urbit.pill`, but the kernel code in `%clay` will be copied from
`urb/zod/arvo/`, so `+solid` will compile it. Then I copy `urbit.pill`
into `urb/` and make my commit.
If you rebase or interactive rebase your commits, be sure to preserve
this property on all the commits you end up with. If multiple people
were collaborating on your branch, you may end up with conflicts in
`urbit.pill` and have to merge the branch into itself to resolve them.
Just do the same procedure to create a new, merged pill before
committing the merge. Otherwise, just make sure to use the correct
`urbit.pill` for each commit.
## Debug urbit with `gdb`
Follow the build instructions in README.md but run `make` with argument `DEBUG=yes`:
(If you've already built urbit first run `make clean`.)
make DEBUG=yes
Run `gdb`, while loading `bin/urbit` and its symbol table:
gdb bin/urbit
Set a breakpoint on `main()` (optional):
break main
Run your urbit comet `mycomet`:
run mycomet
Continue from the breakpoint on `main()`:
continue
## What to work on
If you are not thinking of contributing with a specific goal in mind,
the GitHub issue tracker is the first place you should look for ideas.
Issues are tagged with a priority and a difficulty. A good place to
start is on either a low-difficulty issue or a low-priority issue.
Higher priority issues are likely to be assigned to someone - if this is
the case, then contacting that person to coordinate before starting to
work is probably a good idea.
There is also a "help wanted" tag for things that we are especially
eager to have outside contributions on. Check here first!
## Staying in touch
The urbit developers communicate on urbit itself. Joining the
`~doznec/urbit-meta` channel on `talk` is highly recommended.
Subscribing to `urbit-dev` on Google Groups is also recommended, since
this is where continuity breach notifications are sent.
You can also contact one of the following people:
- Philip Monk
email: philip.monk@tlon.io
urbit: `~wictuc-folrex`
GitHub: [@philipcmonk](https://github.com/philipcmonk/)
- Raymond Pasco
email: ray@the.ug
urbit: `~ramtev-wisbyt`
GitHub: [@juped](https://github.com/juped/)

24
pub/docs/dev/hoon.md Normal file
View File

@ -0,0 +1,24 @@
---
logo: black
sort: 2
title: Hoon
---
<div class="short">
# Hoon
Hoon is a strict, typed, pure functional language. This site is
served by an urbit written in Hoon.
If you're interested in learning the fundamentals of Hoon from
the bottom up, start with [Principles of
Hoon](hoon/principles).
If you want to jump into building things right away and prefer to
learn from the top down, check out [Leap into
Hoon](hoon/leap-in/1-basic).
Both of these are under active development.
</div>

View File

@ -0,0 +1,8 @@
---
hide: false
next: false
sort: 1
title: Leap into Hoon
---
<list></list>

View File

@ -0,0 +1,421 @@
---
logo: black
sort: 1
next: true
title: Basic Hoon
---
# Basic Hoon
Our goal is to get you programming interesting and useful things
as soon as possible. To get there we have to quickly cover some
of the fundamentals of hoon. To do this we'll walk through two
simple programs: the first [Project
Euler](https://projecteuler.net/) problem and
[fizzbuzz](https://en.wikipedia.org/wiki/Fizz_buzz).
To run this code, you'll need an urbit, and you'll need the
`%examples` desk from `~wactex-ribmex`. If you haven't installed
urbit yet, check out the [installation
instructions](http://urbit.org/docs/user/install). Once urbit is
intalled, take a look at the [basic
operation](http://urbit.org/docs/user/basic) of your urbit.
If you haven't pulled the examples desk from `~wactex-ribmex`, do
so now:
~fintud-macrep:dojo> |merge %examples ~wactex-ribmex %examples
>=
; ~wactex-ribmex is your neighbor
; ~wactex-ribmex is your neighbor
[time passes...]
merged with strategy %init
The merge could take several minutes; you'll know it's done when
"merged with strategy %init" is printed. Mount the new files to
your Unix pier directory:
~fintud-macrep:dojo> |mount /=examples=
Switch desks to run commands from the `%examples` desk:
~fintud-macrep:dojo> =dir /=examples=
=% /~fintud-macrep/examples/~2015.11.13..02.25.00..41e9/
Run an example:
~fintud-macrep:dojo> +euler1
233.168
## Euler 1
Let's check out the code for Euler 1. First, the problem:
```
If we list all the natural numbers below 10 that are multiples of
3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
```
Here is the hoon solution (which should be in your pier directory
under `/examples/gen/euler1.hoon`):
```
:: project euler 1
:: https://projecteuler.net/problem=1
:: run in dojo with +euler1
::
:::: /hoon/euler1/gen
::
:- %say |= *
:- %noun
=< (sum 1.000)
::
:::: ~fintud-macrep
::
|%
++ three
|= a=@
=| b=@
|- ^- @u
?: (lth a b)
0
(add b $(b (add 3 b)))
++ five
|= a=@
=| b=@
|- ^- @
?: (lte a b)
0
?: =((mod b 3) 0)
$(b (add b 5))
(add b $(b (add b 5)))
++ sum
|= a=@u
(add (five a) (three a))
--
```
> Hoon is not generally whitespace sensitive, but we do have two
> different kinds of whitespace: a single space and a gap, which
> is two or more spaces or a linebreak. Tabs are taboo. Do not
> use them. Really. For a more detailed explanation of when to
> use spaces vs. gaps, see the syntax section before the first
> excercises.
### Lines 1-11:
Any line that begins with `::` is a comment.
:- %say |= *
:- %noun
=< (sum 1.000)
All you need to know about the lines above is that they call the
`++sum` function with an argument of `1.000`. We'll cover them in
more detail later.
### How to form expressions
Hoon does not use reserved words to form expressions. Instead,
expressions are formed with runes, which are diagraphs of two
ascii symbols. Each rune takes a specific number of
children--either expressions formed by other runes or literals
that produce their own value.
For example, the rune `?:` from line 17 is the classic
'if-then-else' statement, and thus takes three children:
?: (lth a b) :: if first child evals to true
0 :: then produce result of second
(add b $(b (add 3 b))) :: else, produce result of third
Since runes are such a fundamental structure in Hoon, we found
ourselves speaking them out loud frequently. It quickly grew
cumbersome to have to say "question mark, colon" to describe
`?:`. To alleviate this problem, we came up with our own naming
scheme: each ascii glyph has a single syllable pronunciation
phonetically designed to be both easily remembered and easily
pronounced in conjunction with the other glyphs (when forming a
rune).
See the entire naming schema below/or link to it:
```
ace [1 space] gal < pel (
bar | gap [>1 space, nl] per )
bas \ gar > sel [
buc $ hax # sem ;
cab _ hep - ser ]
cen % kel { soq '
col : ker } tar *
com , ket ^ tec `
doq " lus + tis =
dot . pam & wut ?
fas / pat @ zap !
```
Using our naming scheme `?:` is said 'wut col'.
### Lines 12-34
Now let's quickly walk through this code line-by-line. Lines
12-34 are wrapped in a `|%` (pronounced 'bar cen'), which
produces a core, a fundamental datatype in hoon similar to a
struct, class, or object. A core is just a map of names
to any kind of code, whether it be functions or data. Each
element in this map begins with a `++` followed by the name and
the corresponding code. Since `|%` takes an arbitrary number of
children, it needs to be closed with a `--`.
> `++` is not technically a rune, since it is only used in core
> syntax as shown above
Let's step into each of the three arms within our core.
### `++ sum`
++ sum
|= a=@
(add (five a) (three a))
--
`|=` produces a function, much like a lambda in lisp. It takes two children:
- A set of argument(s). In this case our argument set only
contains one: `a` which is required to be an atom or natural
number, denoted by `@`.
- The body of the function itself, which is executed when the
function is called (in this case, with `(sum 1.000)`). This
particular function adds the results of evaluating the gates `++
five` and `++three` with each of their respective input
parameters set to `a`.
### ++ three
++ three
|= a=@
=| b=@
|- ^- @u
?: (lth a b)
0
(add b $(b (add 3 b)))
As above, `++three` takes an integer argument, `a`, and then
executes the remainder of the code with `a` set to the actual
arguments.
Similarly, `=|` pushes its first child, `b` into our context (in
other words, it declares a variable `b`) and executes the
remainder of the code. However, `b` is not an argument; `=|`
sets `b` to the default value of whatever type it is declared as.
Since the default value of an atom is `0`, b is set to `0`.
So now we have two variables: `a` is set to our input, and `b` is
initialized to `0`.
The easiest way to think about `|-` that it lays down a recursion
point. More on this later.
`^-` is just a cast that sets the result of the remainder of the
code to an unsigned integer, `@u`.
In pseudocode, the last three lines read like this: if `a` is
less than `b`, produce zero. Else, add `b` to the result of
rerunning the segment of the function following the `|-` with the
value of `b` changed to `b` plus three.
The only thing that should look completely unfamiliar to you here
is the `$(b (add 3 b))`, which causes us to recurse back to our
last recursion point with the value of `b` set to `(add 3 b)`.
Note that we only specify what changes (`b` in this case). If
you recurse by an actual function call, then you have to specify
every argument.
> If you're familiar with Clojure, `|-` is `loop` and `$()` is
> recur.
## Excercises
Please tweak your code to complete the following excercises.
There are a few runes and some syntax that we have yet to cover that
you will need to complete the excercises below. For these, please
refer to our cheatsheat at the bottom.
1. Read and understand `++five` line by line.
2. Change `++sum` to accept two variables, `a` and `b`. Pass `a`
to three and `b` to five. Then run the code with `a` set to
`1.000` and b set to `2.000`.
3. Check if this new result is under one thousand. If it is,
return the string 'result is less than one thousand'. If not,
return 'result is greater than or equal to one thousand'.
```
Review
|% start core (collection of named ++ arms)
|= define function
=| define variable from type with default value
|- drop a recursion point
^- cast
?: if-then-else
=(a b) test equality
(function args ...) call function
New material
- :- make a cell of values. The irregular wide form of this is
[a b] with two expressions separated by a single space.
- Cords are one datatype for text in hoon. They're just a big
atom formed from adjacent unicode bytes -- a "c string". To
produce a cord enclose text within single quotes. To set the type
of an argument to a cord, use @t.
- There are two syntaxes for writing Hoon: tall form and wide
form.
In tall form, expressions are formed with either two spaces or
a line break separating both a rune from its children and each
of its children from one another. We use tall form when writing
multiline expressions.
For more concise expressions, we use wideform, which is always
a single line. Wideform can be used inside tall form
expressions, but not vice versa.
Wideform expressions are formed with a rune followed by ()
containing its children, all of which are separated by a
single space. For example to make a cell of two elements:
:-(a b)
We've already seen wideform in action, for example with
=((mod b 3) 0). In this case = is actually an irregular form
of .=, which tests its two children for equality.
Another irregular form is [a b] for :-(a b)
Surrounding a function with () is an irregular wide form
syntax for calling a function with n arguments.
```
## The subject
Now we're going to cover the boiler plate that we skimmed over
earlier.
:- %say |= *
:- %noun
=< (sum [1.000 2.000])
This program is a cell of two elements: the first, `%say`, tells
the interpreter what to produce--in this case a value.
The second element is `|=`, which we know produces a function.
`|=`'s first child is its argument(s), which in this case is any
noun (`*`). Its second child is the remainder of the program.
Similarly, the rest of the program is a cell of the literal
`%noun`, which tells the shell that we're producing a value of
type `noun`, and the second child contains the code that we run
to actually produce our value of the type `noun`.
`=<` is a rune that takes two children. The second child is the
context against which we run the first child. So in this case, we
are running the expression `(sum 1.000)` against everything
contained within the `|%`. In Hoon, we call the code executed the
"formula" and its context the "subject".
```
::::::::::::::::::::::::::::::
=< (sum 1.000) :: formula
::::::::::::::::::::::::::::::
|% ::
++ three ::
|= a=@ ::
=| b=@ ::
|- ^- @u ::
?: (lth a b) ::
0 ::
(add b $(b (add 3 b))) ::
::
++ five ::
|= a=@ :: subject
=| b=@ ::
|- ^- @ ::
?: (lte a b) ::
0 ::
?: =((mod b 3) 0) ::
$(b (add b 5)) ::
(add b $(b (add b 5))) ::
::
++ sum ::
|= a=@u ::
(add (five a) (three a)) ::
-- ::
::::::::::::::::::::::::::::::
```
In nearly every language there is a similar concept of a
"context" in which expressions are executed. For example, in C
this includes things like the call stack, stack variables, and so
on.
Hoon is unique in that this context is a first-class value.
Scheme allows a sort of reification of the context through
continutations, and some may see a parallel to Forth's stack, but
Hoon takes takes the concept one step further.
Our starting subject is the standard library, which is defined in
`/arvo/hoon.hoon` and `/arvo/zuse.hoon`. This is where functions
like `add` are defined. When we define a core with `|%`, we
don't throw away the subject (i.e. the standard library); rather,
we stack the new core on top of the old subject so that both are
accessible.
## Exercises:
4. Pass `++sum` its arguments (`2000` and `3000`) from the
commandline.
5. Comment out all of the arms of the `|%`. Now add another arm
and call it `++add`, have it accept two arguments and procduce
42 (regardless of input). Change the `=<` line to `[(add 5 7)
(^add 5 7)]`. Can you recognize what's happening?
6. Write fizbuzz:
Write a program that prints the numbers from 1 to 100
(entered from the command line). But for multiples of three
print 'Fizz' instead of the number and for the multiples of
five print 'Buzz'. For numbers which are multiples of both
three and five print 'FizzBuzz'.
Cheatsheet:
- To pass arguments from the command line to a program, you
replace the `*` in the first line of the boiler plate to
`[^ [[arg=TYPE ~] ~]]` where `TYPE` is replaced with the
type of argument you're expecting. Then `+euler1 a` from
the dojo sets `arg` to `a`.
- A list of strings is of type `(list ,@t)`, so the result of
the fizzbuzz function is of this type (hint: you'll need to
use `^-`)
- The empty list is `~`
- Lisp-style cons (construct a cell/prepend an element) is
`[new-element list]`
- For example, the first three positive integers are `[1 2 3
~]`
- `gte` tests whether `a` is greater than or equal to `b`.
- `mod` runs the modulo operation on two atoms.
- See the [basic math section]() for more info.

View File

@ -0,0 +1,335 @@
---
next: false
sort: 2
title: Network Messages
---
Enough of pure hoonery. Let's get to the good stuff. Let's get
our planets to talk to each other.
Of course, for talking to be of any use, we need someone
listening. What we've written up until now are just shell
commands that produce a value and then disappear. We need an
actual app to listen for messages from another planet. Let's
take a look at a very basic one.
```
:: There is no love that is not an echo
::
:::: /hoon/echo/ape
::
/? 314
!:
|_ [bowl state=~]
++ poke-noun
|= arg=*
^- [(list) _+>.$]
~& [%argument arg]
[~ +>.$]
--
```
This is a very simple app that does only one thing. If you poke
it with a value it prints that out. You have to start the app,
then you can poke it from the command line with the following
commands:
```
~fintud-macrep:dojo> |start %echo
>=
~fintud-macrep:dojo> :echo 5
[%argument 5]
>=
~fintud-macrep:dojo> :echo [1 2]
[%argument [1 2]]
>=
```
> There is currently a bug where the `%argument` lines are
> printed *above* the line you entered, so your output may not
> look exactly like this.
Most of the app code should be simple enough to guess its
function. The important part of this code is the definition of
`++poke-noun`.
Once an app starts, it's always on in the background, and you
interact with it by sending it messages. The most
straightforward way to do that is to poke it from the command
line. When you do that, `++poke-noun` is called from your app.
In our case, `++poke-noun` takes an argument `arg` and prints it
out with `~&`. This is an unusual rune that formally "does
nothing", but the interpreter detects it and printfs the first
child. This is a slightly hacky way of printing to the console,
and we'll get to the correct way later on.
But what does `++poke-noun` produce? Recall that `^-` casts to a
type. In this case, it's declaring that end result of the
function will be of type `[(list) _+>.$]`. But what does this
mean?
The phrase to remember is "a list of moves and our state". Urbit
is a message passing system, so whenver we want to do something
that interacts with the rest of the system we send a message.
Thus, a move is arvo's equivalent of a syscall. The first
thing that `++poke-noun` produces is a list of messages, called
"moves". In this case, we don't actually want the system to do
anything, so we produce the empty list, `~` (in the `[~ +>.$]`
line).
The second thing `++poke-noun` produces is our state. `+>.$`
refers to a particular address in our subject where our formal
app state is stored. It'll become clear why this is later on,
but for now pretend that `+>.$` is a magic invocation that means
"app state".
Let's look at another example. Say we want to only accept a
number, and then print out the square of that number.
```
/? 314
!:
|_ [bowl state=~]
::
++ poke-atom
|= arg=@
^- [(list) _+>.$]
~& [%square (mul arg arg)]
[~ +>.$]
--
```
A few things have changed. Firstly, we no longer accept
arbitrary nouns because we can only square atoms. Thus, our
argument is now `arg=@`. Secondly, it's `++poke-atom` rather
than `++poke-noun`.
Are there other `++poke`s? Definitely. In fact, `noun` and
`atom` are just two of arbitrarily many "marks". A mark is
fundamentally a type definition, but accessible at the arvo
level. Each mark is defined in the `/mar` directory. Some marks
have conversion routines to other marks, and some have diff,
patch, and merge algorithms. None of these are required for a
mark to exist, though.
`noun` and `atom` are two of dozens of predefined marks, and the
user may add more at will. The type associated with `noun` is
`*`, and the type associated with `atom` is `@`.
Data constructed on the command line is by default marked with
`noun`. In this case, the app is expecting an atom, so we have
to explicitly mark the data with `atom`. Try the following
commands:
```
~fintud-macrep:dojo> |start %square
>=
~fintud-macrep:dojo> :square 6
gall: %square: no poke arm for noun
~fintud-macrep:dojo> :square &atom 6
[%square 36]
>=
```
> Recall the bug where `%square` may get printed above the input
> line.
Marks are powerful, and they're the backbone of urbit's data
pipeline, so we'll be getting quite used to them.
**Exercises**:
- Write an app that computes fizzbuzz on its input (as in the
previous section).
- One way of representing strings is with double quoted strings
called "tapes". The hoon type is `tape`, and there is a
corresponding mark with the same name. Write an app that
accepts a tape and prints out `(flop argument)`, where
`argument` is the input. What does this do?
Let's write our first network message! Here's `/ape/pong.hoon`:
```
/? 314
|%
++ move ,[bone term path *]
--
!:
|_ [bowl state=~]
::
++ poke-urbit
|= to=@p
^- [(list move) _+>.$]
[[[ost %poke /sending [to %pong] %atom 'howdy'] ~] +>.$]
::
++ poke-atom
|= arg=@
^- [(list move) _+>.$]
~& [%receiving (,@t arg)]
[~ +>.$]
::
++ coup |=(* [~ +>.$])
--
```
Run it with these commands:
```
~fintud-macrep:dojo> |start %pong
>=
~fintud-macrep:dojo> :pong &urbit ~sampel-sipnym
>=
```
Replace `~sampel-sipnym` with another urbit. Don't forget to
start the `%pong` app on that urbit too. You should see, on the
foreign urbit, this output:
```
[%receiving 'howdy']
```
Most of the code should be straightforward. In `++poke-atom`,
the only new thing is the expression `(,@t arg)`. As we already
know, `@t` is the type of "cord" text strings. `,` is an
operator that turns a type into a validator function -- that is,
a function whose domain is all nouns and range is the given type,
and which is identity when the domain is restricted to the given
type. In simpler terms, it's a function that coerces any value
to the given type. We call this `,@t` function on the argument.
This coerces the argument to text, so that we can print it out
prettily.
The more interesting part is in `++poke-urbit`. The `urbit` mark
is an urbit identity, and the hoon type associated with it is
`@p` (the "p" stands for "phonetic base").
Recall that in a `++poke` arm we produce "a list of moves and our
state". Until now, we've left the list of moves empty, since we
haven't wanted to tell arvo to do anything in particular. Now we
want to send a message to another urbit. Thus, we produce a list
with one element:
```
[ost %poke /sending [to %pong] %atom 'howdy']
```
The general form of a move is
`[bone term path *]`
If you look up `++bone` in `hoon.hoon`, you'll see that it's a
number (`@ud`), and that it's an opaque reference to a duct.
`++duct` in hoon.hoon is a list of `wire`s, where `wire` is an
alias for `path`. `++path` is a list of `span`s, which are ASCII
text. Thus, a duct is a list of paths, and a bone is an opaque
reference to that duct (in the same way that a Unix file
descriptor is an opaque reference to a file structure). Thus,
the center of all this is the concept of a "duct".
A duct is stack of causes, represented as paths. At the bottom
of every duct is a unix event, such as a keystroke, network
packet, file change, or timer event. When arvo is given this
event, it routes the event to appropriate kernel module for
handling.
Sometimes, the module can immediately handle the event and
produce any necessary results. Otherwise, it asks other kernel
modules or applications to do certain things, and produces the
result from that. When it sends a message to another kernel
module or application, it sends it "along" the duct it was given,
plus with a new path. Arvo pushes the new path onto the duct.
Now the duct has two entries, with the unix even on the bottom
and the kernel module that handled it next. This process can
continue indefinitely, adding more and more layers onto the duct.
When an entity produces a result, a layer is popped off the duct.
In effect, a duct is an arvo-level call stack. The duct system
creates a structured message-passing system. It's worth noting
that while in traditional call stacks a function call happens
synchronously and returns exactly once, in arvo multiple moves
can be sent at once, they are evaluated asynchronously, and each
one may be responded to zero or more times.
Anyhow, the point is that whatever caused `++poke-urbit` to be
called is also the root cause for the network message we're
trying to send. Thus, we say to send the network message along
the given bone `ost`. Of course, we have to push a layer to the
duct. This layer can have any data we want in it, but we don't
need anything specific here, so we just use `/sending`. If we
were expecting a response (which we're not), it would come back
along the `/sending` path. It's a good idea for debugging
purposes to make the path human-readable, but it's not necessary.
Looking back at the general form of a move, there is a `term`,
which in this case is `%poke`. This is the name of the
particular kind of move we're sending. If you think of a move as
a syscall (which you should), then this `term` is the name of the
syscall. Common ones include: `%poke`, to message an app;
`%warp`, to read from the filesystem; `%wait`, to set a timer;
and `%them`, to send an http request.
The general form ends with `*` since each type of move takes
different data. In our case, a `%poke` move takes a target
(urbit and app) and marked data and pokes that app on that urbit
with that data. `[to %pong]` is the target urbit and app,
`%atom` is the mark`, and `'howdy'` is the data.
When arvo receives a `%poke` move, it calls the appropriate
`++poke`. The same mechanism is used for sending messages
between apps on the same urbit as for sending messages between
apps on different urbits.
> We said earlier that we're not expecting a response. This is
> not entirely true: the `++coup` is called when we receive
> acknowledgment that the `++poke` was called. We don't do
> anything with this information right now, but we could.
**Exercises**:
- Extend either of the apps in the first two exercises to accept
input over the network in the same way as `pong`.
- Modify `pong` to print out a message when it receives an ack.
- Write two apps, `even` and `odd`. When you pass an atom to
`even`, check whether it's even. If so, divide it by two and
recurse; otherwise, poke `odd` with it. When `odd` recieves
an atom, check whether it's equal to one. If so, terminate,
printing "%success". Otherwise, check whether it's odd. If
so, multiply it by three, add one, and recurse; otherwise, poke
`even` with it. multiply it by three and add one. When either
app receives a number, print it out along with the name of the
app. In the end, you should be able to watch Collatz's
conjecture play out between the two apps. Sample output:
```
~fintud-macrep:dojo> :even &atom 18
[%even 18]
[%odd 9]
[%even 28]
[%even 14]
[%odd 7]
[%even 22]
[%odd 11]
[%even 34]
[%odd 17]
[%even 52]
[%even 26]
[%odd 13]
[%even 40]
[%even 20]
[%even 10]
[%odd 5]
[%even 16]
[%even 8]
[%even 4]
[%even 2]
%success
```
- Put `even` and `odd` on two separate ships and pass the
messages over the network.

View File

@ -0,0 +1,55 @@
---
hide: true
next: false
sort: 3
title: Advanced Applications
---
XXX PLACEHOLDER
But what is our app state, exactly? In Unix systems, application
state is just a block of memory, which you need to serialize to
disk if you want to keep it around for very long.
In urbit, app state is a single (usually complex) value. In our
example, we don't have any special state, so we defined
`state=~`, meaning that our state is null. Of course, `state` is
just a name we're assigning to it, and you're free to use
whatever name you want.
Since urbit is purely functional, we can't just implicitly "have"
and "change" our state. Rather, it's explicitly passed to us, in
the `|_ [bowl state=~]` line, and we produce the new state with
`+>.$` in the `[~ +>.$]` line.
Two points you may be wondering about. Firstly, `bowl` is a set
of general global state that is managed by the system. It
includes things like `now` (current time), `our` (our urbit
identity), and `eny` (256 bits of guaranteed-fresh entropy). For
the full list of things in `++bowl`, search for `++ bowl` (note
the double space) in `/arvo/zuse.hoon`.
> This is a very common technique in learning hoon. While some
> documentation exists, often the easiest way to learn about an
> identifier you see in code is to search in `/arvo/zuse.hoon`
> and `/arvo/hoon.hoon` for it. These are our two "standard
> libraries", and they're usually not hard to read. Since
> urbit's codebase is relatively small (those two files are less
> than 15000 lines of code combined, and besides the standard
> library they include the hoon parser and compiler, plus the
> /arvo microkernel), you can usually use the code and the
> comments as reference doc.
Second point is that urbit needs no "serialize to disk" step.
Everything you produce in the app state is persistent across
calls to the app, restarts of the urbit, and even power failure.
If you want to write to the filesystem, you can, but it's not
needed for persistence. Urbit has transactional events, which
makes it an ACID operating system. Persistence is just another
one of those things you don't have to worry about when
programming in urbit.
As fascinating as state is, we don't actually need any state to
accomplish our immediate goal, which is to get apps on two urbits
talking to each other. We'll discuss state more in a later
chapter.

View File

@ -0,0 +1,7 @@
Library
========
<list dataPreview="true" titlesOnly="true"></list>
<search/>

View File

@ -0,0 +1,37 @@
volume 0, Kelvin Versioning.
===========================
### `++hoon`
++ hoon %164 :: version stub
Declares the current Hoon version number in degrees Kelvin.
When normal people release normal software, they count by fractions, and
they count up. Thus, they can keep extending and revising their systems
incrementally. This is generally considered a good thing. It generally
is.
In some cases, however, specifications needs to be permanently frozen.
This requirement is generally found in the context of standards. Some
standards are extensible or versionable, but some are not. ASCII, for
instance, is perma-frozen. So is IPv4 (its relationship to IPv6 is
little more than nominal - if they were really the same protocol, they'd
have the same ethertype). Moreover, many standards render themselves
incompatible in practice through excessive enthusiasm for extensibility.
They may not be perma-frozen, but they probably should be.
The true, Martian way to perma-freeze a system is what I call Kelvin
versioning. In Kelvin versioning, releases count down by integer degrees
Kelvin. At absolute zero, the system can no longer be changed. At 1K,
one more modification is possible. And so on. For instance, Nock is at
5K. It might change, though it probably won't. Nouns themselves are at
0K - it is impossible to imagine changing anything about their three
sentence definition.
------------------------------------------------------------------------
~zod/try=> stub
164
------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,450 @@
chapter 2a, basic unsigned math
===============================
### `++add`
Add
++ add :: add
~/ %add
|= [a=@ b=@]
^- @
?: =(0 a) b
$(a (dec a), b +(b))
::
Produces the sum of `a` and `b` as an atom.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (add 2 2)
4
~zod/try=> (add 1 1.000.000)
1.000.001
~zod/try=> (add 1.333 (mul 2 2))
1.337
------------------------------------------------------------------------
### `++cap`
Tree head
++ cap :: tree head
~/ %cap
|= a=@
^- ?(%2 %3)
?- a
%2 %2
%3 %3
?(%0 %1) !!
* $(a (div a 2))
==
::
Tests whether an `a` is in the head or tail of a noun. Produces the
[cube]() `%2` if it is within the head, or the [cube]() `%3` if is is
within the tail.
`a` is an [atom]().
~zod/try=> (cap 4)
%2
~zod/try=> (cap 6)
%3
~zod/try=> (cap (add 10 9))
%2
------------------------------------------------------------------------
### `++dec`
Decrement
++ dec :: decrement
~/ %dec
|= a=@
~| %decrement-underflow
?< =(0 a)
=+ b=0
|- ^- @
?: =(a +(b)) b
$(b +(b))
::
Produces `a-1` as an atom.
`a` is an [atom]().
~zod/try=> (dec 7)
6
~zod/try=> (dec 0)
! decrement-underflow
! exit
------------------------------------------------------------------------
### `++div`
Divide
++ div :: divide
~/ %div
|= [a=@ b=@]
^- @
~| 'div'
?< =(0 b)
=+ c=0
|-
?: (lth a b) c
$(a (sub a b), c +(c))
::
Computes `a` divided by `b`, producing an atom.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (div 4 2)
2
~zod/try=> (div 17 8)
2
~zod/try=> (div 20 30)
0
------------------------------------------------------------------------
### `++fac`
Factorial
++ fac :: factorial
~/ %fac
|= a=@
^- @
?: =(0 a) 1
(mul a $(a (dec a)))
::
Computes the factorial of `a`, producing an atom.
`a` is an [atom]().
~zod/try=> (fac 3)
6
~zod/try=> (fac 0)
1
~zod/try=> (fac 11)
39.916.800
------------------------------------------------------------------------
### `++gte`
Greater-than/equal
++ gte :: greater-equal
~/ %gte
|= [a=@ b=@]
^- ?
!(lth a b)
::
Tests whether `a` is greater than a number `b`, producing a loobean.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (gte 100 10)
%.y
~zod/try=> (gte 4 4)
%.y
~zod/try=> (gte 3 4)
%.n
------------------------------------------------------------------------
### `++gth`
Greater-than
++ gth :: greater-than
~/ %gth
|= [a=@ b=@]
^- ?
!(lte a b)
::
Tests whether `a` is greater than `b`, producing a loobean.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (gth 'd' 'c')
%.y
~zod/try=> (gth ~h1 ~m61)
%.n
------------------------------------------------------------------------
### `++lte`
Less-than/equal
++ lte :: less-equal
~/ %lte
|= [a=@ b=@]
|(=(a b) (lth a b))
::
Tests whether `a` is less than or equal to `b`, producing a loobean.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (lte 4 5)
%.y
~zod/try=> (lte 5 4)
%.n
~zod/try=> (lte 5 5)
%.y
~zod/try=> (lte 0 0)
%.y
------------------------------------------------------------------------
### `++lth`
Less-than
++ lth :: less-than
~/ %lth
|= [a=@ b=@]
^- ?
?& !=(a b)
|-
?| =(0 a)
?& !=(0 b)
$(a (dec a), b (dec b))
== == ==
::
Tests whether `a` is less than `b`, producing a loobean.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (lth 4 5)
%.y
~zod/try=> (lth 5 4)
%.n
~zod/try=> (lth 5 5)
%.n
~zod/try=> (lth 5 0)
%.n
------------------------------------------------------------------------
### `++mas`
Axis within head/tail
++ mas :: tree body
~/ %mas
|= a=@
^- @
?- a
1 !!
2 1
3 1
* (add (mod a 2) (mul $(a (div a 2)) 2))
==
::
------------------------------------------------------------------------
Computes the axis of `a` within the head or the tail, producing an atom.
`a` is an [atom]().
~zod/try=> (mas 3)
1
~zod/try=> (mas 4)
2
~zod/try=> (mas 5)
3
~zod/try=> (mas 6)
2
~zod/try=> (mas 0)
! exit
~zod/try=> (mas 1)
! exit
### `++max`
Maximum
++ max :: maximum
~/ %max
|= [a=@ b=@]
^- @
?: (gth a b) a
b
::
Computes the maximum of `a` and `b`, producing an atom.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (max 10 100)
100
~zod/try=> (max 10.443 9)
10.443
~zod/try=> (max 0 1)
1
------------------------------------------------------------------------
### `++min`
Minimum
++ min :: minimum
~/ %min
|= [a=@ b=@]
^- @
?: (lth a b) a
b
::
Computes the minimum of `a` and `b`, producing an atom.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (min 10 100)
10
~zod/try=> (min 10.443 9)
9
~zod/try=> (min 0 1)
0
------------------------------------------------------------------------
### `++mod`
Modulus
++ mod :: remainder
~/ %mod
|= [a=@ b=@]
^- @
?< =(0 b)
(sub a (mul b (div a b)))
::
Computes the remainder of dividing `a` by `b`, producing an atom.
`a` is an [atom]().
`b` is an [atom]().
------------------------------------------------------------------------
### `++mul`
Multiply
++ mul :: multiply
~/ %mul
|= [a=@ b=@]
^- @
=+ c=0
|-
?: =(0 a) c
$(a (dec a), c (add b c))
::
Multiplies `a` by `b`, producing an atom.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (mul 3 4)
12
~zod/try=> (mul 0 1)
0
------------------------------------------------------------------------
### `++peg`
Axis within axis
++ peg :: tree connect
~/ %peg
|= [a=@ b=@]
^- @
?- b
1 a
2 (mul a 2)
3 +((mul a 2))
* (add (mod b 2) (mul $(b (div b 2)) 2))
==
::
Computes the axis of `b` within axis `a`, producing an atom.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (peg 4 1)
4
~zod/try=> (peg 4 2)
8
~zod/try=> (peg 8 45)
269
------------------------------------------------------------------------
### `++sub`
Subtract
++ sub :: subtract
~/ %sub
|= [a=@ b=@]
~| %subtract-underflow
^- @
?: =(0 b) a
$(a (dec a), b (dec b))
Subtracts `b` from `a`, producing an atom.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (sub 10 5)
5
~zod/try=> (sub 243 44)
199
~zod/try=> (sub 5 0)
5
~zod/try=> (sub 0 5)
! subtract-underflow
! exit
------------------------------------------------------------------------

View File

@ -0,0 +1,897 @@
chapter 2b, basic containers
============================
Section 2bA, units
------------------
### `++biff`
Unit as argument
++ biff :: apply
|* [a=(unit) b=$+(* (unit))]
?~ a ~
(b u.a)
Applies a gate that produces a unit, `b`, to the value (`u.a`) of a unit
`a`. If `a` is empty, `~` is produced.
`a` is a [unit]().
`b` is a [gate]() that accepts a noun and produces a unit.
~zod/try=> (biff (some 5) |=(a=@ (some (add a 2))))
[~ u=7]
~zod/try=> (biff ~ |=(a=@ (some (add a 2))))
~
------------------------------------------------------------------------
### `++bind`
Bind
++ bind :: argue
|* [a=(unit) b=gate]
?~ a ~
[~ u=(b u.a)]
Applies a function `b` to the value (`u.a`) of a unit `a`, producing a
unit.
`a` is a [unit]()
`b` is a [gate]().
~zod/try=> (bind ((unit ,@) [~ 97]) ,@t)
[~ `a`]
~zod/try=> =a |=(a=@ (add a 1))
~zod/try=> (bind ((unit ,@) [~ 2]) a)
[~ 3]
------------------------------------------------------------------------
### `++bond`
Replace null
++ bond :: replace
|* a=trap
|* b=(unit)
?~ b $:a
u.b
Replaces an empty unit `b` with the product of a kicked trap `a`. If the
unit is not empty, then the original unit is produced.
`a` is a [trap]().
`b` is a [unit]().
~zod/try=> (bex 10)
1.024
~zod/try=> ((bond |.((bex 10))) ~)
1.024
~zod/try=> ((bond |.((bex 10))) (slaw %ud '123'))
123
------------------------------------------------------------------------
### `++both`
Group unit values
++ both :: all the above
|* [a=(unit) b=(unit)]
?~ a ~
?~ b ~
[~ u=[u.a u.b]]
Produces a unit whose value is a cell of the values of two input units
`a` and `b`. If either of the two units are empty, `~` is produced.
`a` is a [unit]().
`b` is a [unit]().
~zod/try=> (both (some 1) (some %b))
[~ u=[1 %b]]
~zod/try=> (both ~ (some %b))
~
------------------------------------------------------------------------
### `++clap`
Apply gate to two units
++ clap :: combine
|* [a=(unit) b=(unit) c=_|=(^ +<-)]
?~ a b
?~ b a
[~ u=(c u.a u.b)]
Applies a binary operation `c` which produces a unit to the values of
two units `a` and `b`.
`a` is a [unit]().
`b` is a [unit]().
`c` is a [gate]() that performs a binary operation.
~zod/try=> =u ((unit ,@t) [~ 'a'])
~zod/try=> =v ((unit ,@t) [~ 'b'])
~zod/try=> (clap u v |=([a=@t b=@t] (welp (trip a) (trip b))))
[~ u="ab"]
~zod/try=> =a ((unit ,@u) [~ 1])
~zod/try=> =b ((unit ,@u) [~ 2])
~zod/try=> =c |=([a=@ b=@] (add a b))
~zod/try=> (clap a b c)
[~ 3]
------------------------------------------------------------------------
### `++drop`
Unit list
++ drop :: enlist
|* a=(unit)
?~ a ~
[i=u.a t=~]
Produces a [list]() of the value from a unit `a`.
`a` is a [unit]().
~zod/try=> =a ((unit ,@) [~ 97])
~zod/try=> (drop a)
[i=97 t=~]
~zod/try=> =a ((unit ,@) [~])
~zod/try=> (drop a)
~
------------------------------------------------------------------------
### `++fall`
Default unit
++ fall :: default
|* [a=(unit) b=*]
?~(a b u.a)
Produces a default value `b` for a unit `a` in cases where the unit is
null.
`a` is a [unit]().
`b` is a [noun]() used as the default value.
~zod/try=> (fall ~ `a`)
`a`
~zod/try=> (fall [~ u=0] `a`)
0
------------------------------------------------------------------------
### `++lift`
Fmap
++ lift :: lift gate (fmap)
|* a=gate :: flipped
|* b=(unit) :: curried
(bind b a) :: bind
Similar to `fmap` in Haskell: accepts a gate `a` that accepts and
produces an unwrapped value, passes it the value of a unit `b`, and then
produces a unit value.
`a` is a [gate]().
`b` is a [unit]().
~zod/try=> ((lift dec) `(unit ,@)`~)
~
~zod/try=> ((lift dec) `(unit ,@)`[~ 20])
[~ 19]
------------------------------------------------------------------------
### `++mate`
Choose
++ mate :: choose
|* [a=(unit) b=(unit)]
?~ b a
?~ a b
?.(=(u.a u.b) ~|('mate' !!) a)
Accepts two units `a` and `b` whose values are expected to be
equivalent. If either is empty, then the value of the other is produced.
If neither are empty, it asserts that both values are the same and
produces that value. If the assertion fails, `++mate` crashes with
`'mate'` in the stack trace.
`a` is a [unit]().
`b` is a [unit]().
~zod/try=> =a ((unit ,@) [~ 97])
~zod/try=> =b ((unit ,@) [~ 97])
~zod/try=> (mate a b)
[~ 97]
~zod/try=> =a ((unit ,@) [~ 97])
~zod/try=> =b ((unit ,@) [~])
~zod/try=> (mate a b)
[~ 97]
~zod/try=> =a ((unit ,@) [~ 97])
~zod/try=> =b ((unit ,@) [~ 98])
~zod/try=> (mate a b)
! 'mate'
! exit
------------------------------------------------------------------------
### `++need`
Unwrap
++ need :: demand
|* a=(unit)
?~ a !!
u.a
Retrieve the value from a unit and crash if the unit is null.
`a` is a [unit]().
~zod/try=> =a ((unit ,[@t @t]) [~ ['a' 'b']])
~zod/try=> (need a)
['a' 'b']
~zod/try=> =a ((unit ,@ud) [~ 17])
~zod/try=> (need a)
17
~zod/try=> =a ((unit ,@) [~])
~zod/try=> (need a)
! exit
------------------------------------------------------------------------
### `++some`
Unify
++ some :: lift (pure)
|* a=*
[~ u=a]
Takes any atom `a` and produces a unit with the value set to `a`.
`a` is a [noun]().
~zod/try=> (some [`a` `b`])
[~ u=[`a` `b`]]
~zod/try=> (some &)
[~ u=%.y]
------------------------------------------------------------------------
section 2bB, lists
------------------
Reverse
### `++flop`
++ flop :: reverse
~/ %flop
|* a=(list)
=> .(a (homo a))
^+ a
=+ b=`_a`~
|-
?~ a b
$(a t.a, b [i.a b])
Produces the list `a` in reverse order.
`a` is a [list]().
~zod/try=> =a (limo [1 2 3 ~])
~zod/try=> (flop a)
~[3 2 1]
### `++homo`
Homogenize
++ homo :: homogenize
|* a=(list)
^+ =< $
|% +- $ ?:(_? ~ [i=(snag 0 a) t=$])
--
a
Produces a list whose type is a fork of all the contained types in the
list `a`.
`a` is a [list]().
~zod/try=> lyst
[i=1 t=[i=97 t=[i=2 t=[i=98 t=[i=[~ u=10] t=~]]]]]
~zod/try=> (homo lyst)
~[1 97 2 98 [~ u=10]]
~zod/try=> =a (limo [1 2 3 ~])
~zod/try=> a
[i=1 t=[i=2 t=[i=3 t=~]]]
~zod/try=> (homo a)
~[1 2 3]
### `++limo`
List Constructor
++ limo :: listify
|* a=*
^+ =< $
|% +- $ ?~(a ~ ?:(_? i=-.a t=$ $(a +.a)))
--
a
Turns a null-terminated tuple into a list.
`a` is a null-terminated tuple.
~zod/try=> (limo [1 2 3 ~])
[i=1 t=[i=2 t=[i=3 t=~]]]
### `++lent`
List length
++ lent :: length
~/ %lent
|= a=(list)
^- @
=+ b=0
|-
?~ a b
$(a t.a, b +(b))
Produces the length of any list `a` as an atom.
`a` is a [list]().
~zod/try=> (lent (limo [1 2 3 4 ~]))
4
~zod/try=> (lent (limo [1 'a' 2 'b' (some 10) ~]))
5
------------------------------------------------------------------------
### `++levy`
"and" to list
++ levy
~/ %levy :: all of
|* [a=(list) b=_|=(p=* .?(p))]
|- ^- ?
?~ a &
?. (b i.a) |
$(a t.a)
Produces the Boolean "and" of the result of every element in list `a`
passed to gate `b`.
`a` is a [list]().
`b` is a [gate]().
~zod/try=> =a |=(a=@ (lte a 1))
~zod/try=> (levy (limo [0 1 2 1 ~]) a)
%.n
~zod/try=> =a |=(a=@ (lte a 3))
~zod/try=> (levy (limo [0 1 2 1 ~]) a)
%.y
------------------------------------------------------------------------
### `++lien`
"or" to list
++ lien :: some of
~/ %lien
|* [a=(list) b=$+(* ?)]
|- ^- ?
?~ a |
?: (b i.a) &
$(a t.a)
Produces the Boolean "or" of the result of every element in list `a`
passed to gate `b`.
`a` is a [list]().
`b` is a [gate]().
~zod/try=> =a |=(a=@ (gte a 1))
~zod/try=> (lien (limo [0 1 2 1 ~]) a)
%.y
~zod/try=> =a |=(a=@ (gte a 3))
~zod/try=> (lien (limo [0 1 2 1 ~]) a)
%.n
------------------------------------------------------------------------
### `++murn`
Maybe transform
++ murn :: maybe transform
|* [a=(list) b=$+(* (unit))]
|-
?~ a ~
=+ c=(b i.a)
?~ c
$(a t.a)
[i=u.c t=$(a t.a)]
Passes each member of list `a` to gate `b`, which must produce a unit.
Produces a new list with all the results that do not produce `~`.
`a` is a [list]().
`b` is a [gate]() that produces a [unit]().
~zod/try=> =a |=(a=@ ?.((gte a 2) ~ (some (add a 10))))
~zod/try=> (murn (limo [0 1 2 3 ~]) a)
[i=12 t=[i=13 t=~]]
### `++reap`
Replicate
++ reap :: replicate
|* [a=@ b=*]
|- ^- (list ,_b)
?~ a ~
[b $(a (dec a))]
Replicate: produces a list containing `a` copies of `b`.
`a` is an [atom]()
`b` is a [noun]()
~zod/try=> (reap 20 %a)
~[%a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a]
~zod/try=> (reap 5 ~s1)
~[~s1 ~s1 ~s1 ~s1 ~s1]
~zod/try=> `@dr`(roll (reap 5 ~s1) add)
~s5
------------------------------------------------------------------------
### `++reel`
Right fold
++ reel :: right fold
~/ %reel
|* [a=(list) b=_|=([* *] +<+)]
|- ^+ +<+.b
?~ a
+<+.b
(b i.a $(a t.a))
Right fold: moves right to left across a list `a`, recursively slamming
a binary gate `b` with an element from `a` and an accumulator, producing
the final value of the accumulator.
`a` is a [list]().
`b` is a binary [gate]().
~zod/try=> =sum =|([p=@ q=@] |.((add p q)))
~zod/try=> (reel (limo [1 2 3 4 5 ~]) sum)
15
~zod/try=> =a =|([p=@ q=@] |.((sub p q)))
~zod/try=> (reel (limo [6 3 1 ~]) a)
4
~zod/try=> (reel (limo [3 6 1 ~]) a)
! subtract-underflow
! exit
------------------------------------------------------------------------
### `++roll`
Left fold
++ roll :: left fold
~/ %roll
|* [a=(list) b=_|=([* *] +<+)]
|- ^+ +<+.b
?~ a
+<+.b
$(a t.a, b b(+<+ (b i.a +<+.b)))
Left fold: moves left to right across a list `a`, recursively slamming a
binary gate `b` with an element from the list and an accumulator,
producing the final value of the accumulator.
`a` is a [list]().
`b` is a binary [gate]().
~zod/try=> =sum =|([p=@ q=@] |.((add p q)))
~zod/try=> (roll (limo [1 2 3 4 5 ~]) sum)
q=15
~zod/try=> =a =|([p=@ q=@] |.((sub p q)))
~zod/try=> (roll (limo [6 3 1 ~]) a)
! subtract-underflow
! exit
~zod/try=> (roll (limo [1 3 6 ~]) a)
q=4
------------------------------------------------------------------------
### `++skid`
Separate
++ skid :: separate
|* [a=(list) b=$+(* ?)]
|- ^+ [p=a q=a]
?~ a [~ ~]
=+ c=$(a t.a)
?:((b i.a) [[i.a p.c] q.c] [p.c [i.a q.c]])
Seperates a list `a` into two lists - Those elements of `a` who produce
true when slammed to gate `b` and those who produce `%.n`.
`a` is a [list]().
`b` is a [gate]() that accepts one argument and produces a loobean.
~zod/try=> =a |=(a=@ (gth a 1))
~zod/try=> (skid (limo [0 1 2 3 ~]) a)
[p=[i=2 t=[i=3 t=~]] q=[i=0 t=[i=1 t=~]]]
------------------------------------------------------------------------
### `++skim`
Suffix
++ skim :: only
~/ %skim
|* [a=(list) b=_|=(p=* .?(p))]
|-
^+ a
?~ a ~
?:((b i.a) [i.a $(a t.a)] $(a t.a))
Cycles through the members of a list `a`, passing them to a gate `b` and
producing a list of all of the members that produce `%.y`. Inverse of
`++skip`.
`a` is a [list]().
`b` is a [gate]() that accepts one argument and produces a loobean.
~zod/try=> =a |=(a=@ (gth a 1))
~zod/try=> (skim (limo [0 1 2 3 ~]) a)
[i=2 t=[i=3 t=~]]
------------------------------------------------------------------------
### `++skip`
Except
++ skip :: except
~/ %skip
|* [a=(list) b=_|=(p=* .?(p))]
|-
^+ a
?~ a ~
?:((b i.a) $(a t.a) [i.a $(a t.a)])
Cycles through the members of a list `a`, passing them to a gate `b` and
producing a list of all of the members that produce `%.n`. Inverse of
`++skim`.
`a` is a [list]().
`b` is a [gate]() that accepts one argument and produces a loobean.
~zod/try=> =a |=(a=@ (gth a 1))
~zod/try=> (skip (limo [0 1 2 3 ~]) a)
[i=0 t=[i=1 t=~]]
------------------------------------------------------------------------
### `++scag`
Prefix
++ scag :: prefix
~/ %scag
|* [a=@ b=(list)]
|- ^+ b
?: |(?=(~ b) =(0 a)) ~
[i.b $(b t.b, a (dec a))]
Accepts an atom `a` and list `b`, producing the first `a` elements of
the front of the list.
`a` is an [atom]().
`b` is a [list]().
~zod/try=> (scag 2 (limo [0 1 2 3 ~]))
[i=0 t=[i=1 t=~]]
~zod/try=> (scag 10 (limo [1 2 3 4 ~]))
[i=1 t=[i=2 t=[i=3 t=[i=4 t=~]]]]
------------------------------------------------------------------------
### `++slag`
Suffix
++ slag :: suffix
~/ %slag
|* [a=@ b=(list)]
|- ^+ b
?: =(0 a) b
?~ b ~
$(b t.b, a (dec a))
Accepts an atom `a` and list `b`, producing the remaining elements from
`b` starting at `a`.
`a` is an [atom]().
`b` is a [list]().
~zod/try=> (slag 2 (limo [1 2 3 4 ~]))
[i=3 t=[i=4 t=~]]
~zod/try=> (slag 1 (limo [1 2 3 4 ~]))
[i=2 t=[i=3 t=[i=4 t=~]]]
------------------------------------------------------------------------
### `++snag`
Index
++ snag :: index
~/ %snag
|* [a=@ b=(list)]
|-
?~ b
~|('snag-fail' !!)
?: =(0 a) i.b
$(b t.b, a (dec a))
Accepts an atom `a` and a list `b`, producing the element at the index
of `a`and failing if the list is null. Lists are 0-indexed.
`a` is an [atom]().
`b` is a [list]().
~zod/try=> (snag 2 "asdf")
~~d
~zod/try=> (snag 0 `(list ,@ud)`~[1 2 3 4])
1
------------------------------------------------------------------------
### `++sort`
Quicksort
++ sort :: quicksort
~/ %sort
|* [a=(list) b=$+([* *] ?)]
=> .(a ^.(homo a))
|- ^+ a
?~ a ~
%+ weld
$(a (skim t.a |=(c=_i.a (b c i.a))))
^+ t.a
[i.a $(a (skim t.a |=(c=_i.a !(b c i.a))))]
Quicksort: accepts a list `a` and a gate `b` which accepts two nouns and
produces a loobean. `++sort` then produces a list of the elements of `a`
sorted according to `b`.
`a` is an [atom]().
`b` is a [gate]() which accepts two nouns and produces a loobean.
~zod/try=> =a =|([p=@ q=@] |.((gth p q)))
~zod/try=> (sort (limo [0 1 2 3 ~]) a)
~[3 2 1 0]
------------------------------------------------------------------------
### `++swag`
Infix
++ swag :: infix
|* [[a=@ b=@] c=(list)]
(scag b (slag a c))
Similar to `substr` in Javascript: extracts a string infix, beginning at
inclusive index `a`, producing `b` number of characters.
`a` and `b` are [atom]()s.
`c` is a [list]().
~zod/try=> (swag [2 5] "roly poly")
"ly po"
~zod/try=> (swag [2 2] (limo [1 2 3 4 ~]))
[i=3 t=[i=4 t=~]]
------------------------------------------------------------------------
### `++turn`
Gate to list
++ turn :: transform
~/ %turn
|* [a=(list) b=_,*]
|-
?~ a ~
[i=(b i.a) t=$(a t.a)]
Accepts a list `a` and a gate `b`. Produces a list with the gate applied
to each element of the original list.
`a` is a [list]().
`b` is a [gate]().
~zod/try=> (turn (limo [104 111 111 110 ~]) ,@t)
<|h o o n|>
~zod/try=> =a |=(a=@ (add a 4))
~zod/try=> (turn (limo [1 2 3 4 ~]) a)
~[5 6 7 8]
------------------------------------------------------------------------
### `++weld`
Concatenate
++ weld :: concatenate
~/ %weld
|* [a=(list) b=(list)]
=> .(a ^.(homo a), b ^.(homo b))
|- ^+ b
?~ a b
[i.a $(a t.a)]
Concatenate two lists `a` and `b`.
`a` and `b` are [list]()s.
~zod/try=> (weld "urb" "it")
~[~~u ~~r ~~b ~~i ~~t]
~zod/try=> (weld (limo [1 2 ~]) (limo [3 4 ~]))
~[1 2 3 4]
------------------------------------------------------------------------
### `++welp`
Perfect weld
++ welp :: perfect weld
=| [* *]
|%
+- $
?~ +<-
+<-(. +<+)
+<-(+ $(+<- +<->))
--
Concatenate two lists `a` and `b` without losing their type information
to homogenization.
`a` and `b` are [list]()s.
~zod/try=> (welp "foo" "bar")
"foobar"
~zod/arvo=/hoon/hoon> (welp ~[60 61 62] ~[%a %b %c])
[60 61 62 %a %b %c ~]
~zod/arvo=/hoon/hoon> :type; (welp ~[60 61 62] ~[%a %b %c])
[60 61 62 %a %b %c ~]
[@ud @ud @ud %a %b %c %~]
~zod/arvo=/hoon/hoon> (welp [sa/1 so/2 ~] si/3)
[[%sa 1] [%so 2] %si 3]
------------------------------------------------------------------------
### `++wild`
XXDELETE
++ wild :: concatenate
|* [a=(list) b=(list)]
=> .(a ^.(homo a), b ^.(homo b))
|-
?~ a b
[i=i.a $(a t.a)]
Concatenates two lists `a` and `b`, homogenizing their types
individually.
`a` and `b` are [list]()s.
~zod/try=> (wild (limo ~[1 2 3]) (limo [4]~))
~[1 2 3 4]
~zod/try=> (wild (limo 60 61 62 ~) (limo %a %b %c ~))
[i=60 [i=61 [i=62 ~[%a %b %c]]]]
~zod/try=> (weld (limo 60 61 62 ~) (limo %a %b %c ~))
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.000 15].[10.016 57]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.001 15].[10.016 57]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.002 15].[10.016 57]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.004 15].[10.016 57]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.006 15].[10.016 57]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.006 29].[10.006 44]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.056 3].[10.061 13]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.058 3].[10.061 13]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.059 3].[10.061 13]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.060 5].[10.060 47]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.826 7].[9.844 35]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.827 7].[9.844 35]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.827 11].[9.838 13]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.828 11].[9.838 13]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.829 13].[9.831 47]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.830 13].[9.831 47]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.706 7].[9.712 25]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.707 7].[9.712 25]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.708 7].[9.712 25]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.712 7].[9.712 25]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.712 8].[9.712 25]>
! exit
------------------------------------------------------------------------
### `++zing`
Cons
++ zing :: promote
=| *
|%
+- $
?~ +<
+<
(welp +<- $(+< +<+))
--
Turns a list of lists into a single list by promoting the elements of
each sublist into the higher.
Accepts a [list]() of lists.
~zod/try=> (zing (limo [(limo ['a' 'b' 'c' ~]) (limo ['e' 'f' 'g' ~]) (limo ['h' 'i' 'j' ~]) ~]))
~['a' 'b' 'c' 'e' 'f' 'g' 'h' 'i' 'j']
~zod/try=> (zing (limo [(limo [1 'a' 2 'b' ~]) (limo [3 'c' 4 'd' ~]) ~]))
~[1 97 2 98 3 99 4 100]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,437 @@
section 2dA, sets
=================
### `++apt`
Set verification
++ apt :: set invariant
|= a=(tree)
?~ a
&
?& ?~(l.a & ?&((vor n.a n.l.a) (hor n.l.a n.a)))
?~(r.a & ?&((vor n.a n.r.a) (hor n.a n.r.a)))
==
::
Produces a loobean indicating whether `a` is a set or not.
`a` is a [tree]().
~zod/try=> =b (sa `(list ,@t)`['john' 'bonita' 'daniel' 'madeleine' ~])
~zod/try=> (apt b)
%.y
~zod/try=> =m (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ['c' 4] ['d' 5] ~])
~zod/try=> m
{[p='d' q=5] [p='a' q=1] [p='c' q=4] [p='b' q=[2 3]]}
~zod/try=> (apt m)
%.y
------------------------------------------------------------------------
### `++in`
Set operations
++ in :: set engine
~/ %in
|/ a=(set)
Input arm.
~zod/try=> ~(. in (sa "asd"))
<13.evb [nlr(^$1{@tD $1}) <414.fvk 101.jzo 1.ypj %164>]>
`a` is a [set]()
### `+-all:in`
Logical AND
+- all :: logical AND
~/ %all
|* b=$+(* ?)
|- ^- ?
?~ a
&
?&((b n.a) $(a l.a) $(a r.a))
::
Computes the logical AND on every element in `a` slammed with `b`,
producing a loobean.
`a` is a [set]().
`b` is a [wet gate]() that accepts a noun and produces a loobean.
~zod/try=> =b (sa `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
~zod/try=> (~(all in b) |=(a=* ?@(+.a & |)))
%.n
~zod/try=> =b (sa `(list ,@t)`['john' 'bonita' 'daniel' 'madeleine' ~])
~zod/try=> (~(all in b) |=(a=@t (gte a 100)))
%.y
------------------------------------------------------------------------
### `+-any:in`
Logical OR
+- any :: logical OR
~/ %any
|* b=$+(* ?)
|- ^- ?
?~ a
|
?|((b n.a) $(a l.a) $(a r.a))
::
Computes the logical OR on every element of `a` slammed with `b`.
`a` is a [set]().
`b` is a [gate]() that accepts a noun and produces a loobean.
~zod/try=> =b (sa `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
~zod/try=> (~(any in b) |=(a=* ?@(+.a & |)))
%.y
~zod/try=> =b (sa `(list ,@t)`['john' 'bonita' 'daniel' 'madeleine' ~])
~zod/try=> (~(any in b) |=(a=@t (lte a 100)))
%.n
------------------------------------------------------------------------
### `+-del:in`
Remove noun
+- del :: b without any a
~/ %del
|* b=*
|- ^+ a
?~ a
~
?. =(b n.a)
?: (hor b n.a)
[n.a $(a l.a) r.a]
[n.a l.a $(a r.a)]
|- ^- ?(~ _a)
?~ l.a r.a
?~ r.a l.a
?: (vor n.l.a n.r.a)
[n.l.a l.l.a $(l.a r.l.a)]
[n.r.a $(r.a l.r.a) r.r.a]
::
Removes `b` from the set `a`.
`a` is a [set]().
`b` is a [noun]().
~zod/try=> =b (sa `(list ,@t)`['a' 'b' 'c' ~])
~zod/try=> (~(del in b) 'a')
{'c' 'b'}
~zod/try=> =b (sa `(list ,@t)`['john' 'bonita' 'daniel' 'madeleine' ~])
~zod/try=> (~(del in b) 'john')
{'bonita' 'madeleine' 'daniel'}
~zod/try=> (~(del in b) 'susan')
{'bonita' 'madeleine' 'daniel' 'john'}
------------------------------------------------------------------------
### `+-dig:in`
Axis a in b
+- dig :: axis of a in b
|= b=*
=+ c=1
|- ^- (unit ,@)
?~ a ~
?: =(b n.a) [~ u=(peg c 2)]
?: (gor b n.a)
$(a l.a, c (peg c 6))
$(a r.a, c (peg c 7))
::
Produce the axis of `b` within `a`.
`a` is a [set]().
`b` is a [noun]().
~zod/try=> =a (sa `(list ,@)`[1 2 3 4 5 6 7 ~])
~zod/try=> a
{5 4 7 6 1 3 2}
~zod/try=> -.a
n=6
~zod/try=> (~(dig in a) 7)
[~ 12]
~zod/try=> (~(dig in a) 2)
[~ 14]
~zod/try=> (~(dig in a) 6)
[~ 2]
------------------------------------------------------------------------
### `+-gas:in`
Concatenate
+- gas :: concatenate
~/ %gas
|= b=(list ,_?>(?=(^ a) n.a))
|- ^+ a
?~ b
a
$(b t.b, a (put(+< a) i.b))
::
Insert the elements of a list `b` into a set `a`.
`a` is a [set]().
`b` is a [list]().
~zod/try=> b
{'bonita' 'madeleine' 'rudolf' 'john'}
~zod/try=> (~(gas in b) `(list ,@t)`['14' 'things' 'number' '1.337' ~])
{'1.337' '14' 'number' 'things' 'bonita' 'madeleine' 'rudolf' 'john'}
~zod/try=> (~(gas in s) `(list ,@t)`['1' '2' '3' ~])
{'1' '3' '2' 'e' 'd' 'a' 'c' 'b'}
------------------------------------------------------------------------
### `+-has:in`
b in a?
+- has :: b exists in a check
~/ %has
|* b=*
|- ^- ?
?~ a
|
?: =(b n.a)
&
?: (hor b n.a)
$(a l.a)
$(a r.a)
::
Checks if `b` is an element of `a`, producing a loobean.
`a` is a [set]().
`b` is a [noun]().
~zod/try=> =a (~(gas in `(set ,@t)`~) `(list ,@t)`[`a` `b` `c` ~])
~zod/try=> (~(has in a) `a`)
%.y
~zod/try=> (~(has in a) 'z')
%.n
------------------------------------------------------------------------
### `+-int:in`
Intersection
+- int :: intersection
~/ %int
|* b=_a
|- ^+ a
?~ b
~
?~ a
~
?. (vor n.a n.b)
$(a b, b a)
?: =(n.b n.a)
[n.a $(a l.a, b l.b) $(a r.a, b r.b)]
?: (hor n.b n.a)
%- uni(+< $(a l.a, b [n.b l.b ~])) $(b r.b)
%- uni(+< $(a r.a, b [n.b ~ r.b])) $(b l.b)
Produces a set of the intersection between two sets of the same type,
`a` and `b`.
`a` is a [set]().
`b` is a [set]().
~zod/try=> (~(int in (sa "ac")) (sa "ha"))
{~~a}
~zod/try=> (~(int in (sa "acmo")) ~)
{}
~zod/try=> (~(int in (sa "acmo")) (sa "ham"))
{~~a ~~m}
~zod/try=> (~(int in (sa "acmo")) (sa "lep"))
{}
------------------------------------------------------------------------
### `+-put:in`
Put b in a
+- put :: puts b in a
~/ %put
|* b=*
|- ^+ a
?~ a
[b ~ ~]
?: =(b n.a)
a
?: (hor b n.a)
=+ c=$(a l.a)
?> ?=(^ c)
?: (vor n.a n.c)
[n.a c r.a]
[n.c l.c [n.a r.c r.a]]
=+ c=$(a r.a)
?> ?=(^ c)
?: (vor n.a n.c)
[n.a l.a c]
[n.c [n.a l.a l.c] r.c]
::
Add an element `b` to the set `a`.
`a` is a [set]().
`b` is a [noun]().
~zod/try=> =a (~(gas in `(set ,@t)`~) `(list ,@t)`[`a` `b` `c` ~])
~zod/try=> =b (~(put in a) `d`)
~zod/try=> b
{`d` `a` `c` `b`}
~zod/try=> -.l.+.b
n=`d`
------------------------------------------------------------------------
### `+-rep:in`
Accumulate
+- rep :: replace by tile
|* [b=* c=_,*]
|-
?~ a b
$(a r.a, b $(a l.a, b (c n.a b)))
::
Accumulate the elements of `a` using a gate `c` and an accumulator `b`.
`a` is a [set]().
`b` is a [noun]() that accepts a noun and produces a loobean.
`c` is a [gate]().
~zod/try=> =a (~(gas in *(set ,@)) [1 2 3 ~])
~zod/try=> a
{1 3 2}
~zod/try=> (~(rep in a) 0 |=([a=@ b=@] (add a b)))
6
------------------------------------------------------------------------
### `+-tap:in`
Set to list
+- tap :: list tiles a set
~/ %tap
|= b=(list ,_?>(?=(^ a) n.a))
^+ b
?~ a
b
$(a r.a, b [n.a $(a l.a)])
::
Flatten the set `a` into a list.
`a` is an [set]().
`a` is a [set]().
`b` is a [list]().
~zod/try=> =s (sa `(list ,@t)`['a' 'b' 'c' 'd' 'e' ~])
~zod/try=> s
{'e' 'd' 'a' 'c' 'b'}
~zod/try=> (~(tap in s) `(list ,@t)`['1' '2' '3' ~])
~['b' 'c' 'a' 'd' 'e' '1' '2' '3']
~zod/try=> b
{'bonita' 'madeleine' 'daniel' 'john'}
~zod/try=> (~(tap in b) `(list ,@t)`['david' 'people' ~])
~['john' 'daniel' 'madeleine' 'bonita' 'david' 'people']
------------------------------------------------------------------------
### `+-uni:in`
Union
+- uni :: union
~/ %uni
|* b=_a
|- ^+ a
?~ b
a
?~ a
b
?: (vor n.a n.b)
?: =(n.b n.a)
[n.b $(a l.a, b l.b) $(a r.a, b r.b)]
?: (hor n.b n.a)
$(a [n.a $(a l.a, b [n.b l.b ~]) r.a], b r.b)
$(a [n.a l.a $(a r.a, b [n.b ~ r.b])], b l.b)
?: =(n.a n.b)
[n.b $(b l.b, a l.a) $(b r.b, a r.a)]
?: (hor n.a n.b)
$(b [n.b $(b l.b, a [n.a l.a ~]) r.b], a r.a)
$(b [n.b l.b $(b r.b, a [n.a ~ r.a])], a l.a)
Produces a set of the union between two sets of the same type, `a` and
`b`.
`a` is a [set]().
`b` is a [set]().
~zod/try=> (~(uni in (sa "ac")) (sa "ha"))
{~~a ~~c ~~h}
~zod/try=> (~(uni in (sa "acmo")) ~)
{~~a ~~c ~~m ~~o}
~zod/try=> (~(uni in (sa "acmo")) (sa "ham"))
{~~a ~~c ~~m ~~o ~~h}
~zod/try=> (~(uni in (sa "acmo")) (sa "lep"))
{~~e ~~a ~~c ~~m ~~l ~~o ~~p}
------------------------------------------------------------------------
### `+-wyt:in`
Set size
+- wyt :: size of set
|- ^- @
?~(a 0 +((add $(a l.a) $(a r.a))))
Produce the number of elements in set `a` as an atom.
`a` is an [set]().
~zod/try=> =a (~(put in (~(put in (sa)) 'a')) 'b')
~zod/try=> ~(wyt in a)
2
~zod/try=> b
{'bonita' 'madeleine' 'daniel' 'john'}
~zod/try=> ~(wyt in b)
4
------------------------------------------------------------------------

View File

@ -0,0 +1,813 @@
section 2dB, maps
=================
### `++ept`
Map invariant.
++ ept :: map invariant
|= a=(tree ,[p=* q=*])
?~ a
&
?& ?~(l.a & ?&((vor p.n.a p.n.l.a) (hor p.n.l.a p.n.a)))
?~(r.a & ?&((vor p.n.a p.n.r.a) (hor p.n.a p.n.r.a)))
==
Computes whether `a` is a [map](), producing a loobean.
`a` is a [tree]().
~zod/try=> m
{[p='d' q=5] [p='a' q=1] [p='c' q=4] [p='b' q=[2 3]]}
~zod/try=> (ept m)
%.y
~zod/try=> b
{'bonita' 'madeleine' 'daniel' 'john'}
~zod/try=> (ept b)
! type-fail
! exit
------------------------------------------------------------------------
### `++ja`
Jar engine
++ ja :: jar engine
|/ a=(jar)
A container arm for `++jar` operation arms. A `++jar` is a `++map` of
`++list`s. The contained arms inherit the [sample]() jar.
`a` is a [jar]().
~zod/try=> ~(. ja (mo (limo a/"ho" b/"he" ~)))
<2.dgz [nlr([p={%a %b} q=""]) <414.fvk 101.jzo 1.ypj %164>]>
------------------------------------------------------------------------
### `+-get:ja`
Grab value by key
+- get :: grab value by key
|* b=*
=+ c=(~(get by a) b)
?~(c ~ u.c)
Produces a list retrieved from jar `a` using the key `b`.
`a` is a [`++jar`](/doc/hoon/library/1#++jar).
`b` is a key of the same type as the keys in `a`.
~zod/try=> =l (mo `(list ,[@t (list ,@)])`[['a' `(list ,@)`[1 2 3 ~]] ['b' `(list ,@)`[4 5 6 ~]] ~])
~zod/try=> l
{[p='a' q=~[1 2 3]] [p='b' q=~[4 5 6]]}
~zod/try=> (~(get ja l) 'a')
~[1 2 3]
~zod/try=> (~(get ja l) 'b')
~[4 5 6]
~zod/try=> (~(get ja l) 'c')
~
------------------------------------------------------------------------
### `+-add:ja`
Prepend to list
+- add :: adds key-list pair
|* [b=* c=*]
=+ d=(get(+< a) b)
(~(put by a) b [c d])
Produces jar `a` with value `c` prepended to the list located at key
`b`.
`a` is a [jar]().
`b` is a key of the same type as the keys in `a`.
`c` is a value of the same type as the values in `a`.
~zod/try=> =l (mo `(list ,[@t (list ,@)])`[['a' `(list ,@)`[1 2 3 ~]] ['b' `(list ,@)`[4 5 6 ~]] ~])
~zod/try=> l
{[p='a' q=~[1 2 3]] [p='b' q=~[4 5 6]]}
~zod/try=> (~(add ja l) 'b' 7)
{[p='a' q=~[1 2 3]] [p='b' q=~[7 4 5 6]]}
~zod/try=> (~(add ja l) 'a' 100)
{[p='a' q=~[100 1 2 3]] [p='b' q=~[4 5 6]]}
~zod/try=> (~(add ja l) 'c' 7)
{[p='a' q=~[1 2 3]] [p='c' q=~[7]] [p='b' q=~[4 5 6]]}
~zod/try=> (~(add ja l) 'c' `(list ,@)`[7 8 9 ~])
! type-fail
! exit
------------------------------------------------------------------------
### `++ju`
Jug operations
++ ju :: jug engine
|/ a=(jug)
Container arm for jug operation arms. A `++jug` is a `++map` of
`++sets`. The contained arms inherit its [sample]() jug, `a`.
`a` is a [jug]().
~zod/try=> ~(. ju (mo (limo a/(sa "ho") b/(sa "he") ~)))
<2.dgz [nlr([p={%a %b} q={nlr(^$1{@tD $1}) nlr(^$3{@tD $3})}]) <414.fvk 101.jzo 1.ypj %164>]>
### `+-del:ju`
Remove
+- del :: delete at key b
|* [b=* c=*]
^+ a
=+ d=(get(+< a) b)
=+ e=(~(del in d) c)
?~ e
(~(del by a) b)
(~(put by a) b e)
Produces jug `a` with value `c` removed from set located at key `b`.
`a` is a [jug]().
`b` is a key of the same type as the keys in `a`.
`c` is the value of the same type of the keys in `a` that is to be
removed.
~zod/try=> s
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
~zod/try=> (~(del ju s) 'a' 1)
{[p='a' q={3 2}] [p='b' q={5 4 6}]}
~zod/try=> (~(del ju s) 'c' 7)
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
------------------------------------------------------------------------
### `+-get:ju`
Retrieve set
+- get :: gets set by key
|* b=*
=+ c=(~(get by a) b)
?~(c ~ u.c)
Produces a set retrieved from jar `a` using key `b`.
`a` is a [jar]().
`b` is a key of the same type as the keys in `a`.
~zod/try=> s
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
~zod/try=> (~(get ju s) 'a')
{1 3 2}
~zod/try=> (~(get ju s) 'b')
{5 4 6}
~zod/try=> (~(get ju s) 'c')
~
------------------------------------------------------------------------
### `+-has:ju`
Check contents
+- has :: existence check
|* [b=* c=*]
^- ?
(~(has in (get(+< a) b)) c)
Computes whether a value `c` exists within the set located at key `b`
with jar `a`. Produces a loobean.
`a` is a [set]().
`b` is a key as a [noun]().
`c` is a value as a [noun]().
~zod/try=> s
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
~zod/try=> (~(has ju s) 'a' 3)
%.y
~zod/try=> (~(has ju s) 'b' 6)
%.y
~zod/try=> (~(has ju s) 'a' 7)
%.n
~zod/try=> (~(has jus s) 'c' 7)
! -find-limb.jus
! find-none
! exit
~zod/try=> (~(has ju s) 'c' 7)
%.n
------------------------------------------------------------------------
### `+-put:ju`
Add key-set pair
+- put :: adds key-element pair
|* [b=* c=*]
^+ a
=+ d=(get(+< a) b)
(~(put by a) b (~(put in d) c))
Produces jar `a` with `c` added to the set value located at key `b`.
`a` is a [set]().
`b` is a key as a [noun]().
`c` is a [value]().
~zod/try=> s
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
~zod/try=> (~(put ju s) 'a' 7)
{[p='a' q={7 1 3 2}] [p='b' q={5 4 6}]}
~zod/try=> (~(put ju s) 'a' 1)
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
~zod/try=> (~(put ju s) 'c' 7)
{[p='a' q={1 3 2}] [p='c' q={7}] [p='b' q={5 4 6}]}
------------------------------------------------------------------------
### `++by`
Map operations
++ by :: map engine
~/ %by
|/ a=(map)
Container arm for map operation arms. A map is a set of key, value
pairs. The contained arms inherit it's [sample]() [map](), `a`.
`a` is a [map]().
~zod/try=> ~(. by (mo (limo [%a 1] [%b 2] ~)))
<19.irb [nlr([p={%a %b} q=@ud]) <414.rvm 101.jzo 1.ypj %164>]>
------------------------------------------------------------------------
### `+-all:by`
Logical AND
+- all :: logical AND
~/ %all
|* b=$+(* ?)
|- ^- ?
?~ a
&
?&((b q.n.a) $(a l.a) $(a r.a))
Computes the logical AND on the results of slamming every element in map
`a` with gate `b`. Produces a loobean.
`a` is a [map]().
`b` is a [wet gate]().
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
~zod/try=> (~(all by b) |=(a=* ?@(a & |)))
%.n
~zod/try=> =a (mo `(list ,[@t @u])`[['a' 1] ['b' 2] ['c' 3] ['d' 4] ['e' 5] ~])
~zod/try=> (~(all by a) |=(a=@ (lte a 6)))
%.y
~zod/try=> (~(all by a) |=(a=@ (lte a 4)))
%.n
------------------------------------------------------------------------
### `+-any:by`
Logical OR
+- any :: logical OR
~/ %any
|* b=$+(* ?)
|- ^- ?
?~ a
|
?|((b q.n.a) $(a l.a) $(a r.a))
Computes the logical OR on the results of slamming every element with
gate `b`. Produces a loobean.
`a` is a [map]().
`b` is a [wet gate]().
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
~zod/try=> (~(all by b) |=(a=* ?@(a & |)))
%.y
~zod/try=> =a (mo `(list ,[@t @u])`[['a' 1] ['b' 2] ['c' 3] ['d' 4] ['e' 5] ~])
~zod/try=> (~(any by a) |=(a=@ (lte a 4)))
%.y
------------------------------------------------------------------------
### `+-del:by`
Delete
+- del :: delete at key b
~/ %del
|* b=*
|- ^+ a
?~ a
~
?. =(b p.n.a)
?: (gor b p.n.a)
[n.a $(a l.a) r.a]
[n.a l.a $(a r.a)]
|- ^- ?(~ _a)
?~ l.a r.a
?~ r.a l.a
?: (vor p.n.l.a p.n.r.a)
[n.l.a l.l.a $(l.a r.l.a)]
[n.r.a $(r.a l.r.a) r.r.a]
Produces map `a` with the element located at key `b` removed.
`a` is a [map]().
`b` is a key as a [noun]().
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
~zod/try=> (~(del by b) `a`)
{[p=`b` q=[2 3]]}
------------------------------------------------------------------------
### `+-dig:by`
Axis of key
+- dig :: axis of key
|= b=*
=+ c=1
|- ^- (unit ,@)
?~ a ~
?: =(b p.n.a) [~ u=(peg c 2)]
?: (gor b p.n.a)
$(a l.a, c (peg c 6))
$(a r.a, c (peg c 7))
Produce the axis of key `b` within map `a`.
`a` is a [map]().
`b` is a key as a [noun]().
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
~zod/try=> (~(dig by b) `b`)
[~ 2]
------------------------------------------------------------------------
### `+-gas:by`
Concatenate
+- gas :: concatenate
~/ %gas
|* b=(list ,[p=* q=*])
=> .(b `(list ,_?>(?=(^ a) n.a))`b)
|- ^+ a
?~ b
a
$(b t.b, a (put(+< a) p.i.b q.i.b))
Insert a list of key-value pairs `b` into map `a`.
`a` is a [map]().
`b` is a [list]() of [cells]() of key-value nouns `p` and `q`.
~zod/try=> =a (mo `(list ,[@t *])`[[`a` 1] [`b` 2] ~])
~zod/try=> =b `(list ,[@t *])`[[`c` 3] [`d` 4] ~]
~zod/try=> (~(gas by a) b)
{[p=`d` q=4] [p=`a` q=1] [p=`c` q=3] [p=`b` q=2]}
------------------------------------------------------------------------
### `+-get:by`
Grab unit value
+- get :: unit value by key
~/ %get
|* b=*
|- ^- ?(~ [~ u=_?>(?=(^ a) q.n.a)])
?~ a
~
?: =(b p.n.a)
[~ u=q.n.a]
?: (gor b p.n.a)
$(a l.a)
$(a r.a)
Produce the unit value of the value located at key `b` within map `a`.
`a` is a [map]()
`b` is a [key]() as a [noun]()
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
~zod/try=> (~(get by b) `b`)
[~ [2 3]]
------------------------------------------------------------------------
### `+-got:by`
Assert
+- got
|* b=*
%- need
%- get(+< a) b
Produce the value located at key `b` within map `a`. Crash if key `b`
does not exist.
`a` is a [map]().
`b` is a [key]().
~zod/try=> =m (mo `(list ,[@t *])`[['a' 1] ['b' 2] ~])
~zod/try=> m
{[p='a' q=1] [p='b' q=2]}
~zod/try=> (~(get by m) 'a')
[~ 1]
~zod/try=> (~(got by m) 'a')
1
~zod/try=> (~(got by m) 'c')
! exit
------------------------------------------------------------------------
### `+-has:by`
Key existence check
+- has :: key existence check
~/ %has
|* b=*
!=(~ (get(+< a) b))
Checks whether map `a` contains an element with key `b`, producing a
loobean.
`a` is a [map]().
`b` is a key as a [noun]().
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
~zod/try=> (~(has by b) `b`)
%.y
~zod/try=> (~(has by b) `c`)
%.n
------------------------------------------------------------------------
### `+-int:by`
Intersection
+- int :: intersection
~/ %int
|* b=_a
|- ^+ a
?~ b
~
?~ a
~
?: (vor p.n.a p.n.b)
?: =(p.n.b p.n.a)
[n.b $(a l.a, b l.b) $(a r.a, b r.b)]
?: (hor p.n.b p.n.a)
%- uni(+< $(a l.a, b [n.b l.b ~])) $(b r.b)
%- uni(+< $(a r.a, b [n.b ~ r.b])) $(b l.b)
?: =(p.n.a p.n.b)
[n.b $(b l.b, a l.a) $(b r.b, a r.a)]
?: (hor p.n.a p.n.b)
%- uni(+< $(b l.b, a [n.a l.a ~])) $(a r.a)
%- uni(+< $(b r.b, a [n.a ~ r.a])) $(a l.a)
Produces a map of the (key) intersection between two maps of the same
type, `a` and `b`. If both maps have an identical key that point to
different values, the element from map `b` is used.
`a` is a [map]().
`b` is a [map]().
~zod/try=> =n (mo `(list ,[@t *])`[['a' 1] ['c' 3] ~])
~zod/try=> n
{[p='a' q=1] [p='c' q=3]}
~zod/try=> m
{[p='a' q=1] [p='b' q=2]}
~zod/try=> (~(int by m) n)
{[p='a' q=1]}
~ravpel-holber/try=> =p (mo `(list ,[@t *])`[['a' 2] ['b' 2] ~])
~zod/try=> p
{[p='a' q=2] [p='b' q=2]}
~zod/try=> (~(int by p) n)
{[p='a' q=2]}
~zod/try=> =q (mo `(list ,[@t *])`[['a' 2] ['c' 2] ~])
~zod/try=> q
{[p='a' q=2] [p='b' q=2]}
~zod/try=> (~(int by p) q)
{[p='a' q=2] [p='b' q=2]}
~zod/try=> =o (mo `(list ,[@t *])`[['c' 3] ['d' 4] ~])
~zod/try=> (~(int by m) o)
{}
------------------------------------------------------------------------
### `+-mar:by`
Assert and Add
+- mar :: add with validation
|* [b=_?>(?=(^ a) p.n.a) c=(unit ,_?>(?=(^ a) q.n.a))]
?~ c
(del b)
(put b u.c)
Produces map `a` with the addition of a key-value pair, where the value
is a nonempty unit.
Accept a noun and a unit of a noun of the type of the map's keys and
values, respectively. Validate that the value is not null and put the
pair in the map. If the value is null, delete the key.
XX This arm is broken, asana task 15186618346453
~zod/try=> m
{[p='a' q=1] [p='b' q=2]}
~zod/try=> (~(mar by m) 'c' (some 3))
! -find-limb.n
! find-none
! exit
~zod/try=> (~(mar by m) 'c' ~)
! -find-limb.n
! find-none
! exit
~zod/try=> (~(mar by m) 'b' ~)
! -find-limb.n
! find-none
! exit
------------------------------------------------------------------------
### `+-put:by`
Add key-value pair
+- put :: adds key-value pair
~/ %put
|* [b=* c=*]
|- ^+ a
?~ a
[[b c] ~ ~]
?: =(b p.n.a)
?: =(c q.n.a)
a
[[b c] l.a r.a]
?: (gor b p.n.a)
=+ d=$(a l.a)
?> ?=(^ d)
?: (vor p.n.a p.n.d)
[n.a d r.a]
[n.d l.d [n.a r.d r.a]]
=+ d=$(a r.a)
?> ?=(^ d)
?: (vor p.n.a p.n.d)
[n.a l.a d]
[n.d [n.a l.a l.d] r.d]
Produces `a` with the addition of the key-value pair of `b` and `c`.
`a` is a [map]().
`b` is a key of the same type as the keys in `a`.
`c` is a value of the same type of the values in `a`.
~zod/try=> m
{[p='a' q=1] [p='b' q=2]}
~zod/try=> (~(put by m) 'c' 3)
{[p='a' q=1] [p='c' q=3] [p='b' q=2]}
~zod/try=> (~(put by m) "zod" 26)
! type-fail
! exit
~zod/try=> (~(put by m) 'a' 2)
{[p='a' q=2] [p='b' q=2]}
------------------------------------------------------------------------
### `+-rep:by`
+- rep :: replace by product
|* [b=* c=_,*]
|-
?~ a b
$(a r.a, b $(a l.a, b (c q.n.a b)))
Accumulate using gate from values in map
XX interface changing.
------------------------------------------------------------------------
### `+-rib:by`
+- rib :: transform + product
|* [b=* c=_,*]
|- ^+ [b a]
?~ a [b ~]
=+ d=(c n.a b)
=. n.a +.d
=+ e=$(a l.a, b -.d)
=+ f=$(a r.a, b -.e)
[-.f [n.a +.e +.f]]
Replace values with accumulator
XX interface changing, possibly disappearing
------------------------------------------------------------------------
### `+-run:by`
Transform values
+- run :: turns to tuples
|* b=_,*
|-
?~ a a
a(n (b q.n.a), l $(a l.a), r $(a r.a))
Iterates over every value in set `a` using gate `b`. Produces a map.
`a` is a [map]().
`b` is a [wet gate]().
~zod/try=> m
{[p='a' q=1] [p='b' q=2]}
~zod/try=> ^+(m (~(run by m) dec))
{[p='a' q=0] [p='b' q=1]}
~zod/try=> `(map ,@tas ,@t)`(~(run by m) (cury scot %ux))
{[p=%a q='0x1'] [p=%b q='0x2']}
------------------------------------------------------------------------
### `+-tap:by`
Listify pairs
+- tap :: listify pairs
~/ %tap
|= b=(list ,_?>(?=(^ a) n.a))
^+ b
?~ a
b
$(a r.a, b [n.a $(a l.a)])
Produces the list of all elements in map `a` that is prepended to list
`b`, which is empty by default.
`a` is a [map]().
`b` is a [list]().
{[p='a' q=1] [p='b' q=2]}
~zod/try=> `*`m
[[98 2] [[97 1] 0 0] 0]
~zod/try=> (~(tap by m))
~[[p='b' q=2] [p='a' q=1]]
~zod/try=> `*`(~(tap by m))
[[98 2] [97 1] 0]
------------------------------------------------------------------------
### `+-uni:by`
Union
+- uni :: union, merge
~/ %uni
|* b=_a
|- ^+ a
?~ b
a
?~ a
b
?: (vor p.n.a p.n.b)
?: =(p.n.b p.n.a)
[n.b $(a l.a, b l.b) $(a r.a, b r.b)]
?: (hor p.n.b p.n.a)
$(a [n.a $(a l.a, b [n.b l.b ~]) r.a], b r.b)
$(a [n.a l.a $(a r.a, b [n.b ~ r.b])], b l.b)
?: =(p.n.a p.n.b)
[n.b $(b l.b, a l.a) $(b r.b, a r.a)]
?: (hor p.n.a p.n.b)
$(b [n.b $(b l.b, a [n.a l.a ~]) r.b], a r.a)
$(b [n.b l.b $(b r.b, a [n.a ~ r.a])], a l.a)
Produces a map of the union between the keys of `a` and `b`. If `b`
shares a key with `a`, the tuple from `a` is preserved.
`a` is a [map]().
`b` is a [map]().
~zod/try=> m
{[p='a' q=1] [p='b' q=2]}
~zod/try=> o
{[p='d' q=4] [p='c' q=3]}
~zod/try=> (~(uni by m) o)
{[p='d' q=4] [p='a' q=1] [p='c' q=3] [p='b' q=2]}
~zod/try=> (~(uni by m) ~)
{[p='a' q=1] [p='b' q=2]}
~zod/try=> n
{[p='a' q=1] [p='c' q=9]}
~zod/try=> (~(uni by o) n)
{[p='d' q=4] [p='a' q=1] [p='c' q=3]}
~zod/try=> =n (mo `(list ,[@t *])`[['a' 1] ['c' 9] ~])
~zod/try=> n
{[p='a' q=1] [p='c' q=9]}
~zod/try=> (~(uni by o) n)
{[p='d' q=4] [p='a' q=1] [p='c' q=9]}
------------------------------------------------------------------------
### `+-urn:by`
Turn (with key)
+- urn :: turn
|* b=$+([* *] *)
|-
?~ a ~
[n=[p=p.n.a q=(b p.n.a q.n.a)] l=$(a l.a) r=$(a r.a)]
Iterates over every value in map `a` using gate `b`, which accepts both
the key and the value of each element as its sample.
`a` is a [map]().
`b` is a [wet gate]() that accepts two nouns (a key and a value) and
produces a noun (the new value).
~zod/try=> m
{[p='a' q=1] [p='b' q=2]}
~zod/try=> (~(urn by m) |=(a=[p=* q=*] q.a))
{[p='a' q=1] [p='b' q=2]}
~zod/try=> (~(urn by m) |=(a=[p=* q=*] 7))
{[p='a' q=7] [p='b' q=7]}
~zod/try=> (~(urn by m) |=(a=[p=* q=*] p.a))
{[p='a' q=97] [p='b' q=98]}
------------------------------------------------------------------------
### `+-wyt:by`
Depth
+- wyt :: depth of map
|- ^- @
?~(a 0 +((add $(a l.a) $(a r.a))))
Produce the depth of the tree map `a`.
`a` is a [map]().
~zod/try=> m
{[p='a' q=1] [p='b' q=2]}
~zod/try=> o
{[p='d' q=4] [p='c' q=3]}
~zod/try=> ~(wyt by m)
2
~zod/try=> ~(wyt by o)
2
~zod/try=> ~(wyt by (~(uni by m) o))
4
------------------------------------------------------------------------

View File

@ -0,0 +1,221 @@
section 2dC, queues
===================
### `++to`
Queue engine
++ to :: queue engine
|/ a=(qeu)
Container arm for queue operation arms. The contained arms inherit its
[sample]() `++qeu` `a`.
`a` is a queue, [++qeu]().
### `+-bal:to`
Balance
+- bal
|- ^+ a
?~ a ~
?. |(?=(~ l.a) (vor n.a n.l.a))
$(a [n.l.a l.l.a $(a [n.a r.l.a r.a])])
?. |(?=(~ r.a) (vor n.a n.r.a))
$(a [n.r.a $(a [n.a l.a l.r.a]) r.r.a])
a
::
Vertically rebalances queue `a`.
`a` is a [queue]().
~zod/try=> `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~]
{"a" "b" "c" "d" "e" "f" "g"}
~zod/try=> `*`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~]
[[97 0] 0 [98 0] 0 [99 0] 0 [100 0] 0 [101 0] 0 [102 0] 0 [103 0] 0 0]
~zod/try=> ~(bal to `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~])
{"a" "b" "c" "d" "e" "f" "g"}
~zod/try=> `*`~(bal to `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~])
[[100 0] [[99 0] [[98 0] [[97 0] 0 0] 0] 0] [101 0] 0 [102 0] 0 [103 0] 0 0]
------------------------------------------------------------------------
### `+-dep:to`
Maximum Depth
+- dep :: max depth of queue
|- ^- @
?~ a 0
+((max $(a l.a) $(a r.a)))
::
Produces the maximum depth of leaves (r.a and l.a) in queue `a`.
`a` is a [queue]().
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 4 5 6 7 ~])
~zod/try=> ~(dep to a)
4
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 4 ~])
~zod/try=> ~(dep to a)
3
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 ~])
~zod/try=> ~(dep to a)
2
~zod/try=> ~(dep to `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~])
7
~zod/try=> ~(dep to ~(bal to `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~]))
4
------------------------------------------------------------------------
### `+-gas`
Push list
+- gas :: insert list to queue
|= b=(list ,_?>(?=(^ a) n.a))
|- ^+ a
?~(b a $(b t.b, a (put(+< a) i.b)))
::
Push all elements of list `b` into the queue.
`a` is a [queue]().
`b` is a list.
~zod/try=> (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 ~])
{3 2 1}
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 ~])
~zod/try=> =b `(list ,@)`[4 5 6 ~]
~zod/try=> (~(gas to a) b)
{6 5 4 3 2 1}
------------------------------------------------------------------------
### `+-get:to`
Pop
+- get :: head-tail pair
|- ^+ [p=?>(?=(^ a) n.a) q=a]
?~ a
!!
?~ r.a
[n.a l.a]
=+ b=$(a r.a)
:- p.b
?: |(?=(~ q.b) (vor n.a n.q.b))
[n.a l.a q.b]
[n.q.b [n.a l.a l.q.b] r.q.b]
::
Produces the head and tail queue of `a`.
`a` is a [queue]().
~zod/try=> =s (~(gas to *(qeu ,@)) `(list ,@)`~[1 2 3])
~zod/try=> ~(get to s)
[p=1 q={3 2}]
~zod/try=> ~(get to ~)
! exit
------------------------------------------------------------------------
### `+-nap:to`
Remove last in
+- nap :: removes head
?> ?=(^ a)
?: =(~ l.a) r.a
=+ b=get(+< l.a)
bal(+< ^+(a [p.b q.b r.a]))
::
Removes the head of queue `a`, producing the resulting queue.
`a` is a [queue]().
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 4 5 6 ~])
~zod/try=> -.a
n=6
~zod/try=> =b ~(nap to a)
~zod/try=> -.b
n=2
~zod/try=> b
{5 4 3 2 1}
~zod/try=> a
{6 5 4 3 2 1}
------------------------------------------------------------------------
### `+-put:to`
Insert
+- put :: insert new tail
|* b=*
|- ^+ a
?~ a
[b ~ ~]
bal(+< a(l $(a l.a)))
::
Accept any noun `b` and adds to queue `a` as the head, producing the
resulting queue.
`a` is a [queue]().
`b` is any noun.
~zod/try=> (~(gas to `(qeu ,@)`~) `(list ,@)`[3 1 2 4 5 6 ~])
~zod/try=> (~(put to a) 7)
{7 6 5 4 2 1 3}
------------------------------------------------------------------------
### `+-tap:to`
Queue to list
+- tap :: queue to list
|= b=(list ,_?>(?=(^ a) n.a))
^+ b
?~ a
b
$(a r.a, b [n.a $(a l.a)])
::
Produces queue `a` as a list from front to back.
`a` is a [queue]().
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[3 1 2 4 5 6 ~])
~zod/try=> `*`a
[6 0 2 [4 [5 0 0] 0] 1 0 3 0 0]
~zod/try=> (~(tap to a) `(list ,@)`[99 100 101 ~])
~[3 1 2 4 5 6 99 100 101]
------------------------------------------------------------------------
### `+-top:to`
+- top :: produces head
|- ^- (unit ,_?>(?=(^ a) n.a))
?~ a ~
?~(r.a [~ n.a] $(a r.a))
Produces the head of queue `a` as a unit (an empty queue has no head).
`a` is a [queue]().
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 4 5 6 ~])
~zod/try=> ~(top to a)
[~ 1]
------------------------------------------------------------------------

Some files were not shown because too many files have changed in this diff Show More