Disclaimer: My aim here is to summarize the most recent Verse information and translate some of the more technical parts into concrete examples for an audience familiar with C++. This is based on what they have announced as of December 2022, and my own limited interpretation of it.
tl;dr: I'm kind of stupid, I get stuff wrong a lot.
Verse is an as-yet unreleased language from Epic. It was first announced in December 2020, and not much was known about it until last week one of the authors Simon Peyton-Jones gave a talk at a Haskell convention, so now we have a lot more information!
If you have an advanced degree in programming language design, check out their paper The Verse Calculus: a core calculus for functional logic programming. The slides from the talk are a bit easier to understand, but it was aimed at people with a lot of Haskell experience.
My aim here is to try to translate the slides into something a bit more familiar to C++ programmers.
Why is Verse a thing?
Hearing about Verse, a lot of people have the same concerns:
- Is this going to replace C++?
- Is this going to replace Blueprints?
- Do I have to learn this to continue using Unreal?
The answer to all of these is no.
As far as I can tell, Verse is not intended as a replacement for Blueprints or C++. It's being described as a "programming language for the Metaverse". In more concrete terms it's a new language designed to work at scale and make it easier for players to add user-generated content to games. As we've seen from a December 2020 Tweet, it's already being tested out with Fortnite's user-created game modes.
Let's learn about Verse
I've divided this into two parts:
- The basic features of Verse. Get used to the syntax, before you hit the really weird stuff.
- The really weird stuff.
Basic Features
Variables
Let's start with the basics of syntax. In Verse, there are two different ways to declare a variable and assign it a value.
Declaring a variable and assigning it a value uses :=
Verse | C++ |
---|---|
|
|
Like C++, you can separate declaring a variable, and giving it a value. In this
case you can "bind" x to the value of 5 with just x = 5
.
Verse | C++ |
---|---|
|
|
But unlike C++, all variables are effectively const
(once given a value).
This is an important feature of the language both from a philosophical and
practical standpoint.
Edit: The December 2022 slides mention that there might be a way to make some variables mutable, so maybe this isn't a hard-and-fast rule.
Verse | C++ |
---|---|
|
|
Tuple
Verse supports tuples/arrays that look a lot like C++ arrays.
Verse | C++ |
---|---|
|
|
Choice
A core feature of Verse are "choices".
A variable is only ever bound to a single value. Although that value could be a tuple
Verse | C++ |
---|---|
|
|
More complex things are possible by mixing choices and tuples:
Verse | C++ |
---|---|
|
|
Conditionals and Comparison
The slides for the talk show conditionals all on the same line, but from other talks it seems that they are going for a Python-like syntax.
Verse | C++ |
---|---|
|
|
Confusingly, or interestingly, depending on your position, x=5
can be used to
say that x is equal to the value "5", and also be used in a conditional:
Verse | C++ |
---|---|
|
|
It's also possible to compare against multiple numbers.
Verse | C++ |
---|---|
|
|
Weird Stuff
Everything is Math
One core philosophical difference between Verse and C++ is that Verse tries to be way closer to Math.
In C++, when you write x = 5;
you are telling the computer "take the value
5 and store it in the space that we named x".
In Verse, when you write x := 5;
you are telling the computer that for
all uses of x
, it should be treated as equal to 5. Note that this applies
for all uses of x
, not just subsequent values of x
.
Which brings us neatly to the next point.
Order Does not Matter
The following is completely valid Verse:
Verse | C++ |
---|---|
|
|
As mentioned previously, it's important to remember that Verse is designed not to be a series of instructions that you give the computer, but more like a series of conditions or relationships that you are telling the computer hold true.
First we tell the computer that "y is equal to the value of x, plus one".
Then we tell it x is equal to 3.
This is possible because once the value of a variable has been defined, it
cannot be changed. We know for the rest of that scope that x = 3
There are no booleans
This is more of a clickbait title but it got you here.
In Verse, which branch of a conditional is run depends on whether the expression succeeds or fails.
- Success is defined as "returning one or more values"
- Failure is defined as "returning zero values"
Failure has a shorthand of false?
, which we use later.
Why does this matter?
Taking the example of using choices and expanding them out, we can see that the example below executes statement e1 because the conditional returns one or more values:
Verse | C++ |
---|---|
|
|
Logical OR
Logical OR in verse uses the choice operator |
. Remember that branches are
executed if the if condition succeeds, with success being defined as having one
or more values.
So it would make sense that the choice operator, where every part of it is evaluated, would work as an OR. So long as one of them returns non-null, then the conditional would evaluate to success.
Verse | C++ |
---|---|
|
|
Logical AND
Logical AND in Verse uses the tuple comma. This is not quite as clear as with the choice operator being used like OR.
As shown on slide 25, a tuple with any failures is itself evaluated as a failure.
Verse | |
---|---|
|
Comparison returns the left-hand value if they succeed
This is just kind of a weird feature of the language and feeds in to why you can write some complex conditionals.
Verse | C++ |
---|---|
|
|
Type is a Function
This was dropped at the end and details were kind of scant but it seemed to imply that it was easy to define new types.
int
is a function that returns the value for values that pass the test of
being an integer, and fail otherwise.
Verse | |
---|---|
|
So you could define a new type called isPositive
, I have no idea what the
syntax would be to do that, but it would let you set up rules for valid uses of
that type.
Verse | |
---|---|
|
This might explain why there's a bool
type in the old Fortnite example Verse
we saw in 2020. Or maybe that's just an old feature of the language that was
removed.
Thoughts
It's still way too early to tell much about Verse (but that doesn't stop us wildly speculating and getting ourselves worked up!). So far we have a work-in-progress academic paper that talks about some very cool but unusual language features, and some screenshots of more "normal"-looking code.
I'm wondering if some of the more "odd" features are things that will not get used much in day-to-day programming. For example a language like Perl has some horrendous features that could be described at length, but to write "good Perl" you just avoid those features.
Being able to "use" variables before they are defined, and those definitions being far away in the code could be something that we try to avoid as programmers, just to avoid the cognitive load.
I hope they release a prototype version of the language soon so we can mess around with it.