Last active
February 18, 2019 16:08
-
-
Save tgrospic/5e32fb9e9090c0a95af29c17e8e6c8a3 to your computer and use it in GitHub Desktop.
Rholang compose operators
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
new compose in { | |
contract compose(input ...@sends) = { | |
for(...@inp <= input) { | |
new apply in { | |
apply!(inp, sends) | | |
contract apply(argsc, @[send ...rest]) = { | |
match rest { | |
[] => { | |
// the last contract is the end of composition and it's called with suplied args | |
// and args returned from previous contract (without return channel) | |
match send { [s ...args] => @s!(args ++ *argsc) } | |
} | |
_ => { | |
new ret in { | |
// each contract is called with arguments combined from: suplied args, | |
// args returned from previous contract and a new return channel | |
match send { [s ...args] => @s!(args ++ *argsc ++ [*ret]) } | | |
// match send { {@s!(...args)} => @s!(...args ...*argsc, *ret) } | | |
for(...@inp' <- ret) { apply!(inp', rest) } | |
} | |
} | |
} | |
} | |
} | |
} | |
} | | |
new name, location, hash, print, out(`rho:io:stdout`) in { | |
contract name (@[a, ret]) = { @ret!("Name: " ++ a) } | | |
contract location (@[a, b, ret]) = { @ret!([a, b]) } | | |
contract hash (@[a, b, ret]) = { @ret!({"Hash": a, "Data": b}) } | | |
contract print (@[a ]) = { out!(a) } | | |
new nameLocHash in { | |
// nameLocHash contract is a composition (sequence in this case) | |
// of name, location, hash and print contracts | |
contract nameLocHash(inp) = { | |
new ret1, ret2, ret3 in { | |
name!([*inp, *ret1]) | | |
for(ret1' <- ret1) { | |
location!([42, *ret1', *ret2]) | | |
for(ret2' <- ret2) { | |
hash!(["SHA1", *ret2', *ret3]) | | |
for(ret3' <- ret3) { | |
print!([*ret3']) | |
} | |
} | |
} | |
} | |
} | | |
nameLocHash!("Beth") | | |
nameLocHash!("Summer") | |
} | | |
new nameLocHash in { | |
// - version with compose without creating intermediate channels | |
// nameLocHash contract is a composition (sequence in this case) | |
// of name, location, hash and print contracts | |
compose!(*nameLocHash | |
, [*name] | |
, [*location, 666] | |
, [*hash, "SHA256"] | |
, [*print] | |
) | | |
nameLocHash!("Rick") | | |
nameLocHash!("Morty") | |
/* I'm using the list because it's much easier to use it with | |
// spread operator to match and construct arguments, so it's | |
// easy to imagine compose used like this | |
compose!(*nameLocHash | |
, *name | |
, location!(42) | |
, hash!("SHA1") | |
) | |
| | |
// more complicated example with multiple return channels, | |
// we can define different connectors to match output/input | |
compose!(*nameLocHash | |
, *name | |
, location!(42) | |
, hash!("SHA1") | |
, *verify // returns (left, right) | |
, *pickRight // (left, right) -> right | |
) | |
| | |
// my motivation is to be able to write something like this, | |
// defining custom operators which looks like overloads of Par | |
// - we can translate this to previous example with compose!(,,,) | |
*nameLocHash | |
<= *name | |
|> location!(42) | |
|> hash!("SHA1") | |
|> *verify | |
| | |
// pattern matching on custom operators would be extremely useful, if not necessary | |
new xr, yr in { | |
match proc { | |
{c <= x |> y} => for(@x' <= c) { @x!(x', *xr) | for(@y' <- xr) { @y!(y', *yr) } } | |
} | |
} | |
| | |
// can we go even further and encode match with (|=> and =>)? | |
proc | |
|=> {a /\ String} => out!(a ++ "!") | |
|=> {a /\ Int} => out!(a + 10) | |
*/ | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment