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.