You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Sometimes it's convenient to have c-style enums, which is essentially a limited set of integer values, each with a given name. Enums in Abra can have variants of two different flavors, Constant and Container; Container enums have fields and are a way of modeling disjointed unions whereas Constant enums have no internal data (fields).
Enum variants are represented in memory as a variable-sized data structure whose first property is a 64-bit integer representing the variant index (64 bits is way more than is necessary, but it's done this way for alignment purposes), followed by any of the data needed to be stored for that variant (Constant variants of course have no internal data). In pseudocode:
{
u64 variant_idx;
[ptr field_n;]*
}
This proposal has 2 subtopics:
Implicit c-style enums
When given an enum with only Constant variants, do not use any backing data structure to represent the variants and instead just use an integer.
Under this new proposal, this would result in FileOpenMode.ReadOnly to simply be represented as 0 rather than a structure like { .variant_idx = 0 }. This would be a slight performance boost in certain special cases, but would become especially useful when defining bridging interfaces with c code (like in std/libc.abra).
Explicitly defining ordinal values
In the implicit example above, the variants' ordinal values are 0, 1, and 2 as would be expected. However, it may be desirable to explicitly set the ordinal value. This can be done with an =:
In this case, like above ReadOnly, WriteOnly, and ReadWrite are represented as 0, 1, and 2 respectively, but Create is represented as 512. The = 0 on ReadOnly is redundant and unnecessary and should result in a warning (once they exist, see #504).
The right-hand side of the = must be a constant integer literal, and in an enum where such construct is used, no Container variants are allowed. Each ordinal number must also be unique, so the following examples would result in type errors:
enum Foo {
Bar = 1
Baz = 1
}
and
enum Foo {
Bar
Baz
Qux = 1 // error, Baz already implicitly has ordinal value 1
}
Functionality
Operations
Such constant enums should have the following comparison operators available: <, <=, >, >=, ==, !=. These operators should work between enum values and also integers. Arithmetic operators are not supported for constant enums.
The binary opertors || and && are supported for constant enums as well and can be used between enum values and integer values, but the resulting expression is of type Int (since the resulting value cannot be guaranteed to be a valid enum value).
Methods
Constant enums will have the following methods automatically defined for them, just by being a constant enum (enums with Container variants will not have these methods):
func fromOrdinal(value: Int): Self?
A static method on the enum itself which can convert an integer value to the enum value. This returns an Option because an invalid ordinal integer may be provided.
func asOrdinal(self): Int
Returns the integer ordinal value of a given enum value.
The toString(self): String, eq(self, other: Self): Bool, and hash(self): Int methods should still function as expected.
The text was updated successfully, but these errors were encountered:
Sometimes it's convenient to have c-style enums, which is essentially a limited set of integer values, each with a given name. Enums in Abra can have variants of two different flavors, Constant and Container; Container enums have fields and are a way of modeling disjointed unions whereas Constant enums have no internal data (fields).
Enum variants are represented in memory as a variable-sized data structure whose first property is a 64-bit integer representing the variant index (64 bits is way more than is necessary, but it's done this way for alignment purposes), followed by any of the data needed to be stored for that variant (Constant variants of course have no internal data). In pseudocode:
This proposal has 2 subtopics:
Implicit c-style enums
When given an enum with only Constant variants, do not use any backing data structure to represent the variants and instead just use an integer.
Under this new proposal, this would result in
FileOpenMode.ReadOnly
to simply be represented as0
rather than a structure like{ .variant_idx = 0 }
. This would be a slight performance boost in certain special cases, but would become especially useful when defining bridging interfaces with c code (like instd/libc.abra
).Explicitly defining ordinal values
In the implicit example above, the variants' ordinal values are
0
,1
, and2
as would be expected. However, it may be desirable to explicitly set the ordinal value. This can be done with an=
:In this case, like above
ReadOnly
,WriteOnly
, andReadWrite
are represented as0
,1
, and2
respectively, butCreate
is represented as512
. The= 0
onReadOnly
is redundant and unnecessary and should result in a warning (once they exist, see #504).The right-hand side of the
=
must be a constant integer literal, and in an enum where such construct is used, no Container variants are allowed. Each ordinal number must also be unique, so the following examples would result in type errors:and
Functionality
Operations
Such constant enums should have the following comparison operators available:
<
,<=
,>
,>=
,==
,!=
. These operators should work between enum values and also integers. Arithmetic operators are not supported for constant enums.The binary opertors
||
and&&
are supported for constant enums as well and can be used between enum values and integer values, but the resulting expression is of typeInt
(since the resulting value cannot be guaranteed to be a valid enum value).Methods
Constant enums will have the following methods automatically defined for them, just by being a constant enum (enums with Container variants will not have these methods):
A static method on the enum itself which can convert an integer value to the enum value. This returns an Option because an invalid ordinal integer may be provided.
Returns the integer ordinal value of a given enum value.
The
toString(self): String
,eq(self, other: Self): Bool
, andhash(self): Int
methods should still function as expected.The text was updated successfully, but these errors were encountered: