What's the point of Verse constructors?

Design of Verse constructors is a bit weird. Coming from C# if they would be similar we could use them as:

MyClass := my_class(DataForConstructor:my_data):
    MyClassVar := OtherVar

This makes them very easy to use and discover. After typing my_class( we get a suggestion list of all possible constructors. Additionally it’s possible to make default constructor private and inaccessible, forcing us to use custom constructor.

Verse constructors seem to not differ much from functions? Other then a weird syntax with let, blocks and specific rules when multiple constructors are called.

I thought maybe they can be used for initializing values for variables but no:

1 Like

The major value of Verse constructor functions is their ability to delegate construction to some other constructor function. They are similar to C++'s member initializer list syntax and delegating constructors, but many different constructor functions can be defined for a class external to the class and with arbitrary names. For example,

class1 := class:
  X:int
  Y:int
  Z:int

MakeSomeClass1<constructor>(Arg1:int, Arg2:int) := class1:
  X := Arg1
  Y := Arg2
  Z := Arg1 + Arg2

MakeSomeOtherClass1(Arg1:int) := class1:
  MakeSomeClass1<constructor>(Arg1, Arg1) # delegate to another constructor
  Z := Arg1 # except override what the other constructor did for Z

This delegating applies to inherited classes, as well, with similar syntax.

class1 := class:
  X:int
  Y:int

ZeroClass1<constructor>() := class1:
  X := 0
  Y := 0

class2 := class(class1):
  Z:int

ZeroClass2<constructor>() := class2:
  ZeroClass1<constructor>()
  Z := 0

If you don’t intend to use a constructor function with other constructor functions, you may be better served with a plain function.

4 Likes

There is also another use: easy partial updates of a class without using a var field. For example,

class1 := class:
  X:int
  Y:int

CopyClass1<constructor>(Arg:class1) := class1:
  X := Arg.X
  Y := Arg.Y

var X:class1 = class1{X := 1, Y := 2}
set X = class1:
  CopyClass1<constructor>(X)
  Y := X.Y + 1

Whenever a field is added to class1, only CopyClass1 needs updating, and not all the partial updates. This mimics deep mutation available to structs.

3 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.