Beta Release 0.1.2
This release of Onyx brings a substantial new feature called tagged unions, and a collection of other small bugfixes.
Tagged Unions
Tagged unions are a big addition to the type system in Onyx, as they allow you to represent a new kind of type. They bring a number of safety and sanity features that Onyx had been lacking in its type system.
At their core, tagged unions store at most one type of data at a time, and know which type they are currently holding.
In order to use the data in the tagged union, you must do a switch
statement, which guarantees that you can only access the data if it is of the correct type.
Let's look at a code example.
MultipleTypes :: union {
int: i32;
float: f32;
string: str;
}
main :: () {
value := MultipleTypes.{ string="Tagged unions are cool!" };
switch value {
case .int do println("It was an integer!");
case .float do println("It was a float!");
case .string do println("It was a string!");
}
}
This code will print It was a string!
, because value
currently holds the string
variant.
This is specified with MultipleTypes.{ XXX = ... }
; XXX
must be one of the variants of MultipleTypes
.
In order to access the data inside of the union, you can use a switch with a capture, like so.
main :: () {
value := MultipleTypes.{ string="Tagged unions are cool!" };
switch value {
case .int => int_value do printf("It was an integer: {}\n", int_value);
case .float => float_value do println("It was a float: {}\n", float_value);
// You can also use it by pointer by placing a '&' before the variable.
case .string => &str_value do println("It was a string: {}\n", *str_value);
}
}
You can also directly access the fields, like you would a structure. However, instead of getting the data directly, you get an Optional of the data. You then have to use the methods of the Optional type to access the data.
MultipleTypes :: union {
int: i32;
float: f32;
string: str;
}
main :: () {
v := MultipleTypes.{ float = 12.34 };
// Using Optional.unwrap to get the data.
// This will cause an exception if the union does not currently hold a 'float'.
float_value := v.float->unwrap();
println(float_value);
}
Tagged unions can also be polymorphic, just like structures. With this feature, this is how the Optional
type is now defined.
Optional :: union (Value_Type: type_expr) {
None: void;
Some: Value_Type;
}
main :: () {
v := Optional(i32).{ Some = 123 };
switch v {
case .None {
println("No value :(");
}
case .Some => int_value {
printf("Int value: {}\n", int_value);
}
}
}
Full Changelog
Additions: * Tagged unions (union
type) * String literals can have unicode code points. - '\uXXXX' for small code points (less than U+FFFF) - '\UXXXXXX' for large code points - Does not support UTF-16 surrogate pairs *iter.next_opt
*memory.ptr_add
*misc.any_member
Removals: Changes: *optional
is now a tagged-union *result
is now a tagged-union *iter.single
can take adispose
function, which is called on close of the iterator, with the single value yielded. *io.write_escaped_str
supports escaping "\\" now. * In Javascript runtime, made__read_from_input
not defined right away, so it can be overridden depending on the needs of the program. Bugfixes: *json
encoder was wrongly not encoding strings when usingencode
on anany
.