Various thoughts on Verse

Just posting a bunch of different thoughts/ideas I’ve had over the time I’ve spent with Verse.


When creating failable functions, we need the <decides> attribute, which also requires <transactional>

According to the roadmap no_rollback will be removed later on, so I guess we won’t have to type <transactional> anymore, but I still think <decides> is a bit ugly.

I think it would be much nicer if we could type:

Func[A:int, B:int]:void= <# ... #>

Since failable functions are called with [ ]


I love how terse and declarative you can write Verse code, like this is all the code needed to create all pairs of elements in a list:

for(I->A:List, J->B:List, J>I). (A,B)

But there quickly ends up being a lot of nested parentheses, which doesn’t feel great, but I can’t think of a good solution

I tried writing an example of how some more complex code could look without parentheses, but that was honestly way harder to parse

The multiline form

for:
    I -> A : List
    J -> B : List
    J > I
do:
    (A,B)

…looks a bit weird when there’s so little in the do block.
If we could reverse it and put do before for on a single line:

do (A,B) for:
    I -> A : List
    J -> B : List
    J > I

That looks a bit better imo, but now it looks like we’re using A and B before they’re declared, so idk


I think it could be really nice to be able to write user-definable expressions

average:
    2
    3
    4

Maybe just by declaring it to be usable as an expression with a specifier?

([]int).average<expression>():int=
    <# ... #>

Though this doesn’t match the convention of starting functions with an uppercase letter…

In the Fortnite API, instead of spawning asynchronous tasks, perhaps you could use a custom expression to subscribe tasks that all get called in one loop as an optimization?

OnBegin<override>()<suspends>:void=
    if(<#...#>) onUpdate. <#...#>
    if(<#...#>) onUpdate. <#...#>
    <# ... #>

I’ve recently looked a bit at Dafny, and the way you can write functions with requires and ensures so you know the functions can’t fail seems very interesting.

So a function that would look like this in Verse:

F(X:type{_X:int where _X > 0):type{_X where X < 0}=
   <# ... #>

Could be written in Dafny like:

method F(x: int) returns (y: int)
    requires x > 0
    ensures y < 0 
{
    /* ... */
}

In Dafny, a name has to be given to the return value, so that it can be referenced in the postcondition. This also makes it trivial to have multiple return values returns (y: int, z: int)

I think it would be great if we could have something like this in Verse where we could make non-failable versions of functions if we know something about the values we are passing.


Overall, I really like Verse, and the biggest reason I’m not writing Verse code every day is that I have 0 interest in Fortnite, and have to wait a minute to test my code while the server updates every time I make some changes.

Very excited for the future of Verse once “choice” is in the language, the type system gets a bit more fleshed out, and I can compile/run Verse code locally.

3 Likes