Verse Syntax

I know it’s too late to change anything but I have to say, the syntax looks a little too academic and too verbose.
Not only that, I find it even inconsistent.
To make it more practical and to be consistent with the rest, I propose the following changes.

  1. Allow runs in Specifiers, e.g., instead of <transace><decides>, allow, <transact, decides>

  2. It’s kind of dumb to repeat the same Using keywords every time.

Allow,
using { /Fortnite.com/Devices; /Verse.org/Native}

and also allow the following to make it consistent with the code Blocks

using : 
         /Fortnite.com/Devices
         /Verse.org/Native
  1. Get rid of “var” and “set”. It makes the code look ugly and inconsistent with the rest of the syntax.
    So to define a Constant, use MyConstant<constant> : int = 1
    To define a variable, just don’t specify <constant>, e.g., MyVar : int = 1
    And to set a variable, just do this. MyVar = 2 instead of set MyVar = 2 It looks bad.
    And if you try to set a constant, you will get a compile error anyway.

  2. To instantiate a class with default values, currently, you have to do something like this MyClass {A := 1, B := 2}
    I think it’s not consistent with the rest of the syntax. A colon is used when defining a new var, thus the syntax should look like this. MyClass{ A = 1, B = 2} It’s shorter and more consistent.

  3. I don’t like the way Verse reverses everything. It might be too late to change the whole syntax but we can at least use more common naming standard.
    Please don’t use Snake case. It takes more effort to type and makes the code longer. Screen space is precious, you know.
    Just use Camel case variables. Pascal case for Classes. Lowercase for internal types and so on. Verse is doing things backward pretty much for everything including naming convention. Why??

  4. Just use bool instead of logic. I laughed when I first saw logic, When I heard that there is no boolean type from the earlier presentation, I was really puzzled. But it turned out bool is just logic, the name changed. I don’t really see the difference. Yeah, you can differentiate the underlying meanings if you really want but we all know what it does. I have no problem accepting a failed logic as false.

We will see what the academic people will say.
Thanks.

ps. One thing I don’t fully understand is the use of <decides> and [] to call a function within if Is it really necessary to call the function with []? It makes it really confusing to access an array and to call a function. Is it really wrong to call a function that returns a bool? Again, I think the idea came from academics, ignoring practicality and common conventions.

1 Like

I’m not an academic nor a functional programmer, but i can see a reason for why they’re doings things like this in Verse. For example:

  1. The reason why var is used is because they want inmutable variables by default when no var is used. This is a decision from them to “force us” to use constants. I assume features like transactions and rollbacks are easier to implement in a language that works like this. Also set MyVar = 2 is used, because MyVar = 2 is an equality comparison. I find that weird as well, but I’ll get used to it.
  1. I don’t fully like this, but this makes types consistent in terms of naming convention. Since every type (including primitive types like int) inherit from the same object in Verse.

The <decides> part, while it’s confusing… accessing arrays using [] is like calling a <decides> method. Assume that MyArray[1] is syntax sugar for something like MyArray.GetValueInIndex[1] where GetValueInIndex[] is a <decides> method. So at least it’s consistent. And in a way, using [] can be helpful to identify these methods easily since these are special methods that need to be called within a context that can handle failures, like an if. And having a language that forces us to handle potential failures like this may be a pain to deal with, but it also practically eliminates null related bugs in the code.

But I also have some gripes with the language TBH. I don’t like how we can’t mutate collections. In functional languages, there seems to be features like views (virtual collections) and filters to handle collection manipulations. Filters seem to be implemented in Verse, using for(Item:Collection, FilterPredicate) which can even rollback any method call for elements that failed. I haven’t seen anything like a view feature. So far in order to append or remove elements to a collection, we have to create a new collection.
Also, there doesn’t seem to be a way to pass variables by reference… Maybe I’m wrong, but I haven’t seen it so far. So we can’t do stuff like passing an array to a method to then manipulate the array by its reference. The language doesn’t really like us modifying variables outside of their context (which has its advantages as well…) .

1 Like

Yeah, it’s because they decided to change == to =. I think it’s also a bad decision, probably coming from the academics. It just creates more confusions. I can see that they trying to force constant as the default at the cost of ugliness. If they change back to ==, we can get rid of set, var.

So, accessing an array is like calling decides function? I didn’t think of it that way but I need to wrap my head around it. We will see.

In Functional worlds, everything is immutable, it will require some more head-banging accepting it. The collection is one of them and I hope they will provide ways to make it easier to manipulate collections.

I think there will be more questions like this and I think Epic needs to have a session explaining why they decided on language convention/syntax to make it easier to accept it rather than just throwing it at us.

So what does X equal here if Verse is just making a single = the same as ==, X :?int = option{1 + 3 = 2}
and what does it equal here: X :?int = option{1 + 1 = 2}

hint: the devs of verse are not just changing the syntax for the heck of it. The = and == are not the same… one is assignment the other is…

hint2: it acts more like unification from logical programming languages

I will be creating a course for the language asap, there is far too much misunderstanding going on

2 Likes

Not saying to make the same. A single = is an assignment and a double == is an equality test as we all know.

So it should read, X :?int = option{1 + 3 == 2}

I was replying to that statement where I said that they are not the same.

== would return a boolean, the second = does not return a boolean, they are fundamentally different

I’m not sure what the problem is here.
Currently, = is used for both assignment and equality test, thus it’s confusing.
I’m saying to separate them and you are saying to keep the same.
The example you gave is confusing.
X :?int = option{1 + 3 = 2}
What does it suppose to do?
It will fail and how is it different from X :?int = option{1 + 3 == 2} where == will return false and we make option{false} to return fail?

There is no such a thing as boolean in Verse. To me, boolean and failable are the same conceptually.
Why invent the new concept? Can’t we treat the boolean false to mean both logical false and fail?

Anyway, I don’t mean to nitpick but stuff like these already start to cause confusion.

Despite the fact that Verse should be simple to learn, it already confuses lots of people.
Despite the fact that they want Verse to be widely used outside of Epic, it’s going to be an uphill battle.
It’s ugly, unconventional, and verbose.

The only thing that I like is the concurrency… and for-loop filtering. I like to see more functional stuff as long as they don’t force us to use functional stuff.

Anyway, non-functional should be the default (so get rid of var and set), and functional should be optional.
Functional stuff can enhance things quite nicely like those in Linq and F#.
Game programmers will definitely use non-functional stuff much more often than those in academics.

1 Like

There is a reason for what I chose because = does not mean assignment in verse nor does it mean return true or false based on whether the left is == the right. If the left is equal to the right it is a successful equality, this is more like unification from prolog: Unification in Prolog - javatpoint.

1 + 3 = 2 is not a successful unification, it returns nothing or it fails. 1 + 1 = 2 is a successful unification, so the expression returns 2. You may say which 2 does it return… the answer is that does not matter, if x = x then returning the left x or the right x is irrelevant. So when you say X :blah = something, you are still unifying. Try it yourself with an option type, and you will soon see that = is not the same as == or an assignment from other languages, it is more like both of them at the same time (not quite but close).

Hmm… interesting.
= is not exactly an assignment nor a boolean equality test but it can also work as an assignment (as a side-effect I guess) and equality test that produces either value or failable results.

I’m evil but I’m not bad.
Very deep.
It’s either very obscurely clever (I still have to see if this concept carries over everywhere) or we are trying to make meanings out of it. ^^

Here is another thing regarding option.

my_device := class<concrete>(creative_device):
    var SavedPlayer : ?player = false # unset optional value
 
    @editable
    PlayerSpawn : player_spawner_device = player_spawner_device{}
 
    @editable
    Trigger : trigger_device = trigger_device{}
 
    OnBegin<override>() : void =
        PlayerSpawn.PlayerSpawnedEvent.Subscribe(OnPlayerSpawned)
 
    OnPlayerSpawned(Player : player) : void =
        set SavedPlayer = option{Player}
        if (TriggerPlayer := SavedPlayer?): 
            Trigger.Trigger(TriggerPlayer)

var SavedPlayer : ?player = false # unset optional value

What is this false doing here? It has a totally different meaning.
If they want to explicitly unset, say so, like below,
var SavedPlayer : ?player = unset # unset optional value
or
var SavedPlayer : ?player = null # unset optional value
or do not set anything.
var SavedPlayer : ?player # unset optional value

They invented a new language and why not use more keywords to make things clear?

And the following seem redundant.

set SavedPlayer = option{Player}

option should be optional.
SavedPlayer is the optional type and when you try to assign a value, it should implicitly convert to an optional type.
This is another verbosity that forces us to type more and we have to remember SavedPlayer is optional in order not to forget option.

Please make the language more intuitive to use and follow the more common conventions as much as possible.

ps. I still think set, var has to go away. It is the biggest annoying syntax and it doesn’t follow the rest of the conventions. Not only that, it does not add any values other than reminding us that we are using variables instead of constants.