struct vs class - TheBuzzSaw/KellyScript GitHub Wiki
This is a key opportunity to remove some complexity introduced by C++. Consider the following.
a = b;
This bit of code needs to restored to its former grace. C++ brought classes into the world, which introduced us to the world of copy construction, copy assignment, move construction, move assignment, etc. This may have not been the worst thing if structs had been left alone, but structs were invaded by this complexity in an effort to unify the type system. As a result, the expression above can have any number of side effects.
In KellyScript, structs are values (copy only), and classes are resources (move only). When b
is assigned to a
, the bits in a
will be changed to match b
. No exceptions. There will be no mechanism for the user to override or redefine assignment behavior. If the type is a class, the compiler will mark variable b
as uninitialized, which means its destructor will not be called unless it is reassigned to some new value. This opens up opportunities for destructive move operations: after a resource has had its guts essentially ripped out, there is often no need to initialize it to a new value as it will be cleaned up anyway. Structs have no destructors.
In C++, complex data structures are often given value-like semantics.
// C++ example
vector<int> values{1, 5, 9, 11, 15};
vector<int> values2 = values;
vector<int> values3{2, 2, 9};
values3 = move(values);
This allows the programmer to reason about these data structures as if they were primitives like int
. However, this comes at the great cost of invisible performance degradation. Since this language is meant to emphasize speaking to the hardware, potentially expensive operations need to be explicitly requested.
// KellyScript example
Vector<Int32> values{1, 5, 9, 11, 15};
Vector<Int32> values2 = values.Clone(); // Request that a duplicate be made.
Vector<Int32> values3{2, 2, 9};
values3 = values; // Destroy content of 'values3'. Move the content of 'values' into 'values3'.
This structured approach to class definition means we cannot have self-referencing pointers. (Good riddance!) One result of this clean separation of behavior is that structs cannot have class data members. This is due to the fact that structs inherently copy (thus do not mark the other value as uninitialized) and have no destructor (thus cannot cleanup class components). The reverse relation is fine: classes may have struct data members.
No more lvalue and rvalue nonsense either.