Main navigation

Rholang Wishlist

Submitted by Joshy Orndorff
on Sun, 09/23/2018 - 16:39

I've been programming rholang for about 5 months now and in general I love it and am super happy I learned. If you want to join in that journey, checkout out my tutorial. In those five months, though, I've also noticed a few pain points where I think syntactic changes would go a long ways. I've opened issues or started discussions about some of these already. But I'll write them down here too.

Contract Definitions

The syntax for a contract definition requires an equal sign which isn't required in similar constructs like for.

Trailing Pars

Styleguides (like this one) often recommend including a trailing comma in multi-line list, tuple, object , etc literals. I would like to do the same with my pars in rholang. It makes them feel more like the familiar semicolons at the end of each line. The semantics are that the unary par is sugar for a par with the stopped process.

// The current way
new x in {
@0!(Nil) |
@1!(Nil)
}
// The wishlist way
new x in {
@0!(Nil) |
@1!(Nil) |
}

Convenient Unforgeable Processes

It's great to pattern match data with a preceding @ sign when you want to use it as a process. I want to do the same thing with my news.

// The current way
new x in { *x }
// The wishlist way
new @x in { x }

We don't need all of pattern matching there. Just this one special case for then I want to make a new ack channel and immediately send it.

Less Nesting From New Names

Rholang code gets really deeply nested. Some of that nesting feels natural like in contracts or fors. But it's really common to then create new names immediately inside causing more deeply nested code. I wish we could combine those things.

A crazier idea is to do the same kind of thing for receives instead of just sends. As soon as I receive, immediately put the continuation back listening. I guess this might be hard or impossible. Is it even possible to do that manually in rholang?

Sane Sequential Programming

Rholang is inherently concurrent. It's a wonderful new way of thinking and I'm glad it's so easy to do now. There are also times when things need to happen sequentially. Like printing the heading of a table before the data rows, or integration testing. Sequential code gets really deeply nested, and thus really hard to read. What if we bring back the classic ; from sequential languages such as c or java for this task.

// The current way
new ack in {
stdoutAck!("This is a haiku", *ack) |
for (_ <- ack) {
stdoutAck!("So the line order matters", *ack) |
for (_ <- ack) {
stdoutAck!("Because syllables!") |
}
}
}
// The wishlist way
// The contracts must be of the right form so an ack can be appended to the arg list
new ack(`;`) in {
stdoutAck!("This is a haiku");
stdoutAck!("So the line order matters");
stdoutAck!("Because syllables!");
}

This combines extremely nicely with my trailing | idea, so I've writing it that way. Remember there is an implicit Nil after the trailing par. That Nil will become the body of the last for comprehension during desugaring. Thus the programmer can call the same contract that expects an ack every time and not have to write a special one (equivalent of stdout without the Ack) to handle the last call.

Timer in Powerbox

This would be useful for writing games and stuff, but probably not for the blockchain. And it may encourage bad practices for handling race conditions. But still, I need to to implement a realistic AI in my game.

This one works brilliantly with my sequential idea from above, so I'll write it that way. But this could still be implemented without that previous enhancement. It would just lead to deep nesting.

// There is no current way
// The wishlist way
new timer(`rho:os:timer`) in {
stdoutAck!("three");
timer!(1000); // milliseconds
stdoutAck!("two");
timer!(1000);
stdoutAck!("one");
timer!(1000);
stdoutAck!("blastoff");
}

Console Access in REPL

The REPL (read, evaluate, print, loop) is a convenient way to test little snippets of rholang code interactively. Such a thing is precedented in other languages like python's interactive mode, haskell's ghci, and every browser's javascript console. It is extremely common to print an output to the screen for quick evaluation. But in rholang it takes a lot of code to get access to such capabilities which is a pain to type each time.

// The current way
new stdout(`rho:io:stdout`) in {
stdout!("Hello World")
}
// The wishlist way (REPL ONLY!)
stdout!("Hello World") // Just works ;)